@ -1,17 +1,28 @@
@@ -1,17 +1,28 @@
package jnpf.service.impl ;
import cn.hutool.core.bean.BeanUtil ;
import cn.hutool.core.collection.CollectionUtil ;
import cn.hutool.core.date.LocalDateTimeUtil ;
import cn.hutool.core.io.resource.ResourceUtil ;
import cn.hutool.core.util.ObjectUtil ;
import cn.hutool.core.util.StrUtil ;
import cn.xuyanwu.spring.file.storage.FileInfo ;
import cn.xuyanwu.spring.file.storage.MockMultipartFile ;
import com.alibaba.fastjson.JSON ;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper ;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page ;
import com.google.protobuf.ServiceException ;
import jnpf.base.UserInfo ;
import jnpf.base.vo.DownloadVO ;
import jnpf.constant.FileTypeConstant ;
import jnpf.entity.Expert ;
import jnpf.entity.LotteryProject ;
import jnpf.entity.LotteryReview ;
import jnpf.exception.DataException ;
import jnpf.file.FileApi ;
import jnpf.file.FileUploadApi ;
import jnpf.mapper.LotteryProjectMapper ;
import jnpf.model.dto.ExpertDto ;
import jnpf.model.dto.IndicatorStatisticsDto ;
import jnpf.model.dto.LotteryProjectDto ;
import jnpf.permission.OrganizeApi ;
@ -19,16 +30,28 @@ import jnpf.permission.entity.OrganizeEntity;
@@ -19,16 +30,28 @@ import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.model.authorize.AuthorizeConditionModel ;
import jnpf.permission.service.OrganizeService ;
import jnpf.service.CustomAuthService ;
import jnpf.service.ExpertService ;
import jnpf.service.ILotteryProjectService ;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl ;
import jnpf.service.ILotteryReviewService ;
import jnpf.util.UploaderUtil ;
import jnpf.util.UserProvider ;
import lombok.AllArgsConstructor ;
import org.apache.poi.ss.formula.functions.T ;
import org.apache.poi.xwpf.usermodel.* ;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Service ;
import java.io.* ;
import java.math.BigInteger ;
import java.time.LocalDate ;
import java.time.LocalDateTime ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.Optional ;
import java.util.stream.Collectors ;
import java.util.stream.Stream ;
/ * *
* < p >
@ -45,6 +68,12 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@@ -45,6 +68,12 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
private final UserProvider userProvider ;
private final OrganizeApi organizeService ;
private final ILotteryReviewService iLotteryReviewService ;
private final RedisSerialNumberGenerator redisSerialNumberGenerator ;
private final ExpertService expertService ;
private static final String ROUND_KEY = "roundKey:" ;
private final FileUploadApi fileUploadApi ;
private final FileApi fileApi ;
@Override
public void add ( LotteryProjectDto . AddParam param ) {
@ -52,7 +81,7 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@@ -52,7 +81,7 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
lotteryProject . setType ( LotteryProjectDto . TypeEnum . ONESELF . getCode ( ) ) ;
lotteryProject . setStatus ( LotteryProjectDto . StatusEnum . TO_BE_EXTRACTED . getCode ( ) ) ;
lotteryProject . setStatusName ( LotteryProjectDto . StatusEnum . TO_BE_EXTRACTED . getDescribe ( ) ) ;
lotteryProject . setBidOpeningTime ( LocalDate . parse ( LocalDateTimeUtil . format ( param . getBidEvaluationTime ( ) , "yyyy-MM-dd" ) ) ) ;
lotteryProject . setBidOpeningTime ( LocalDate . parse ( LocalDateTimeUtil . format ( param . getBidEvaluationTime ( ) , "yyyy-MM-dd" ) ) ) ;
UserInfo userInfo = userProvider . get ( ) ;
lotteryProject . setUserDeptId ( userInfo . getOrganizeId ( ) ) ;
//添加根子单数据
@ -69,12 +98,13 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@@ -69,12 +98,13 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@Override
public void edit ( LotteryProjectDto . EditParam param ) {
if ( null = = param . getId ( ) ) {
if ( null = = param . getId ( ) ) {
throw new DataException ( "id不能为空" ) ;
}
LotteryProject lotteryProject = BeanUtil . copyProperties ( param , LotteryProject . class ) ;
lotteryProject . setBidOpeningTime ( LocalDate . parse ( LocalDateTimeUtil . format ( param . getBidEvaluationTime ( ) , "yyyy-MM-dd" ) ) ) ;
UserInfo userInfo = userProvider . get ( ) ; ;
lotteryProject . setBidOpeningTime ( LocalDate . parse ( LocalDateTimeUtil . format ( param . getBidEvaluationTime ( ) , "yyyy-MM-dd" ) ) ) ;
UserInfo userInfo = userProvider . get ( ) ;
;
lotteryProject . setUpdateId ( userInfo . getUserId ( ) ) ;
lotteryProject . setUpdateName ( userInfo . getUserName ( ) ) ;
lotteryProject . setUpdateTime ( LocalDateTime . now ( ) ) ;
@ -85,17 +115,16 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@@ -85,17 +115,16 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@Override
public void delete ( LotteryProjectDto . DeleteParam param ) {
if ( null = = param . getId ( ) ) {
if ( null = = param . getId ( ) ) {
throw new DataException ( "id不能为空" ) ;
}
this . lambdaUpdate ( )
. set ( LotteryProject : : getDelFlag , "1" )
. eq ( LotteryProject : : getId , param . getId ( ) )
. set ( LotteryProject : : getDelFlag , "1" )
. eq ( LotteryProject : : getId , param . getId ( ) )
. update ( ) ;
}
private final CustomAuthService customAuthService ;
private QueryWrapper < T > getAuthWrapper ( String menuId ) {
@ -107,6 +136,7 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@@ -107,6 +136,7 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
}
return null ;
}
@Override
public Page < LotteryProjectDto . QueryResponse > queryList ( LotteryProjectDto . QueryListParam param ) {
if ( param . getPageNum ( ) = = null ) {
@ -121,14 +151,693 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
@@ -121,14 +151,693 @@ public class LotteryProjectServiceImpl extends ServiceImpl<LotteryProjectMapper,
return new Page < > ( ) ;
}
assert queryWhere ! = null ;
return this . getBaseMapper ( ) . queryList ( new Page < > ( param . getPageNum ( ) , param . getPageSize ( ) ) , param , queryWhere . getParamNameValuePairs ( ) , queryWhere . getSqlSegment ( ) . replace ( "paramNameValuePairs." , "" ) ) ;
return this . getBaseMapper ( ) . queryList ( new Page < > ( param . getPageNum ( ) , param . getPageSize ( ) ) , param , queryWhere . getParamNameValuePairs ( ) , queryWhere . getSqlSegment ( ) . replace ( "paramNameValuePairs." , "" ) ) ;
}
@Override
public LotteryProjectDto . QueryResponse queryInfo ( String id ) {
if ( StrUtil . isBlank ( id ) ) {
if ( StrUtil . isBlank ( id ) ) {
throw new DataException ( "id不能为空" ) ;
}
return this . getBaseMapper ( ) . queryInfo ( id ) ;
}
@Override
public void addReview ( LotteryProjectDto . AddReviewParam param ) {
if ( StrUtil . isBlank ( param . getId ( ) ) ) {
throw new DataException ( "抽签项目不能为空" ) ;
}
if ( ! this . lambdaQuery ( )
. eq ( LotteryProject : : getId , param . getId ( ) )
. exists ( ) ) {
throw new DataException ( "抽签项目不存在" ) ;
}
LotteryReview lotteryReview = new LotteryReview ( ) ;
lotteryReview . setExpertGroupInfo ( param . getExpertGroupInfo ( ) ) ;
lotteryReview . setCreateTime ( LocalDateTime . now ( ) ) ;
lotteryReview . setRelationId ( param . getId ( ) ) ;
lotteryReview . setDelFlag ( "0" ) ;
//查询评审次数
Long count = iLotteryReviewService . lambdaQuery ( )
. eq ( LotteryReview : : getRelationId , param . getId ( ) )
. eq ( LotteryReview : : getDelFlag , "0" )
. count ( ) ;
lotteryReview . setCount ( ( count + 1 ) + "" ) ;
iLotteryReviewService . save ( lotteryReview ) ;
}
@Override
public void editReview ( LotteryProjectDto . EditReviewParam param ) {
if ( StrUtil . isBlank ( param . getId ( ) ) ) {
throw new DataException ( "评审id不能为空" ) ;
}
LotteryReview lotteryReview = iLotteryReviewService . getById ( param . getId ( ) ) ;
lotteryReview . setExpertGroupInfo ( param . getExpertGroupInfo ( ) ) ;
iLotteryReviewService . saveOrUpdate ( lotteryReview ) ;
}
@Override
public void participateInConfirmation ( LotteryProjectDto . ParticipateInConfirmationParam param ) {
if ( StrUtil . isBlank ( param . getStatus ( ) ) ) {
throw new DataException ( "状态不能为空" ) ;
}
if ( StrUtil . isBlank ( param . getId ( ) ) ) {
throw new DataException ( "评审id不能为空" ) ;
}
LotteryReview lotteryReview = iLotteryReviewService . getById ( param . getId ( ) ) ;
if ( null = = lotteryReview ) {
throw new DataException ( "评审不存在" ) ;
}
if ( StrUtil . isBlank ( param . getExpertId ( ) ) ) {
throw new DataException ( "评审专家id不能为空" ) ;
}
List < LotteryProjectDto . ExtractExpertsInfo > extractExpertsInfo = lotteryReview . getExtractExpertsInfo ( ) ;
if ( null = = extractExpertsInfo ) {
throw new DataException ( "请先保存评审信息" ) ;
}
Optional < LotteryProjectDto . ExtractExpertsInfo > expertsInfo = extractExpertsInfo . stream ( ) . filter ( e - > e . getId ( ) . equals ( param . getExpertId ( ) ) ) . findFirst ( ) ;
if ( ! expertsInfo . isPresent ( ) ) {
throw new DataException ( "评审专家未被抽取" ) ;
}
UserInfo userInfo = userProvider . get ( ) ;
LotteryProjectDto . ExtractExpertsInfo extractExpertsInfoComfirm = expertsInfo . get ( ) ;
String status = param . getStatus ( ) ;
//确认参加修改组别确认人数
if ( StrUtil . equals ( status , "1" ) & & null ! = lotteryReview . getExpertGroupInfo ( ) ) {
List < LotteryProjectDto . ExpertGroupInfo > expertGroupInfo = lotteryReview . getExpertGroupInfo ( ) ;
for ( LotteryProjectDto . ExpertGroupInfo groupInfo : expertGroupInfo ) {
if ( ! groupInfo . getGroupCode ( ) . equals ( extractExpertsInfoComfirm . getExpertGroup ( ) ) ) {
continue ;
}
groupInfo . setNumberOfParticipants ( ( Integer . parseInt ( groupInfo . getNumberOfParticipants ( ) ) + 1 ) + "" ) ;
}
}
extractExpertsInfoComfirm . setStatus ( status ) ;
extractExpertsInfoComfirm . setRemark ( param . getRemark ( ) ) ;
extractExpertsInfoComfirm . setConfirmTime ( LocalDateTime . now ( ) ) ;
extractExpertsInfoComfirm . setConfirmId ( userInfo . getUserId ( ) ) ;
extractExpertsInfoComfirm . setConfirmName ( userInfo . getUserName ( ) ) ;
extractExpertsInfoComfirm . setShowJoinButton ( false ) ;
iLotteryReviewService . updateById ( lotteryReview ) ;
}
@Override
public LotteryProjectDto . QueryReviewResponse queryReviewInfo ( String id ) {
if ( StrUtil . isBlank ( id ) ) {
throw new DataException ( "评审信息id不能为空" ) ;
}
return iLotteryReviewService . queryReviewInfo ( id ) ;
}
@Override
public void deleteReview ( LotteryProjectDto . DeleteReviewParam param ) {
if ( StrUtil . isBlank ( param . getId ( ) ) ) {
throw new DataException ( "评审信息id不能为空" ) ;
}
iLotteryReviewService . lambdaUpdate ( )
. set ( LotteryReview : : getDelFlag , "1" )
. eq ( LotteryReview : : getId , param . getId ( ) )
. update ( ) ;
}
@Override
public void saveExtractionResults ( LotteryProjectDto . SaveExtractionResultsParam param ) {
if ( StrUtil . isBlank ( param . getId ( ) ) ) {
throw new DataException ( "评审信息id不能为空" ) ;
}
LotteryReview lotteryReview = iLotteryReviewService . getById ( param . getId ( ) ) ;
//获取抽取轮次
long round = redisSerialNumberGenerator . generateSerialNumber ( ROUND_KEY + lotteryReview . getId ( ) , 1L ) ;
//组别删除按钮不再展示
if ( round > = 1L & & null ! = lotteryReview . getExpertGroupInfo ( ) ) {
for ( LotteryProjectDto . ExpertGroupInfo expertGroupInfo : lotteryReview . getExpertGroupInfo ( ) ) {
expertGroupInfo . setShowDelButton ( false ) ;
}
}
List < String > oldExpertIdList = null ;
if ( null ! = lotteryReview . getExtractExpertsInfo ( ) ) {
oldExpertIdList = lotteryReview . getExtractExpertsInfo ( ) . stream ( ) . map ( LotteryProjectDto . ExtractExpertsInfo : : getId ) . collect ( Collectors . toList ( ) ) ;
}
//配置抽取轮次
for ( LotteryProjectDto . ExtractExpertsInfo extractExpertsInfo : param . getExtractExpertsInfo ( ) ) {
if ( CollectionUtil . isNotEmpty ( oldExpertIdList ) ) {
if ( oldExpertIdList . contains ( extractExpertsInfo . getId ( ) ) ) {
continue ;
}
}
if ( StrUtil . isBlank ( extractExpertsInfo . getExtractionRounds ( ) ) ) {
extractExpertsInfo . setExtractionRounds ( round + "" ) ;
}
if ( null = = lotteryReview . getExtractExpertsInfo ( ) ) {
lotteryReview . setExtractExpertsInfo ( new ArrayList < > ( ) ) ;
}
lotteryReview . getExtractExpertsInfo ( ) . add ( extractExpertsInfo ) ;
}
iLotteryReviewService . updateById ( lotteryReview ) ;
}
@Override
public List < Expert > getExpertsByType ( String reviewId , String expertGroup ) {
if ( StrUtil . isBlank ( reviewId ) | | StrUtil . isBlank ( expertGroup ) ) {
throw new DataException ( "评审信息id和抽取类型不能为空" ) ;
}
//获取评审信息
LotteryReview lotteryReview = iLotteryReviewService . getById ( reviewId ) ;
//获取已专家编号列表抽取
List < String > expertIdList = null ;
if ( null ! = lotteryReview . getExtractExpertsInfo ( ) ) {
expertIdList = lotteryReview . getExtractExpertsInfo ( ) . stream ( ) . map ( LotteryProjectDto . ExtractExpertsInfo : : getId ) . collect ( Collectors . toList ( ) ) ;
}
return expertService . lambdaQuery ( )
. eq ( Expert : : getStatus , "0" )
. eq ( Expert : : getDelFlag , "0" )
. eq ( Expert : : getDataType , "1" )
. eq ( Expert : : getExpertGroup , expertGroup )
. notIn ( CollectionUtil . isNotEmpty ( expertIdList ) , Expert : : getId , expertIdList )
. list ( ) ;
}
@Override
public DownloadVO resultPrinting ( String reviewId ) {
if ( StrUtil . isBlank ( reviewId ) ) {
throw new DataException ( "评审信息id不能为空" ) ;
}
LotteryReview lotteryReview = iLotteryReviewService . getById ( reviewId ) ;
if ( null = = lotteryReview . getExtractExpertsInfo ( ) ) {
throw new DataException ( "未抽取专家,无法打印" ) ;
}
//校验打印类型
LotteryProject lotteryProject = this . getById ( lotteryReview . getRelationId ( ) ) ;
if ( null = = lotteryReview . getExtractExpertsInfo ( ) ) {
throw new DataException ( "未抽取专家,无法打印[2]" ) ;
}
List < LotteryProjectDto . ExtractExpertsInfo > extractExpertsInfo = lotteryReview . getExtractExpertsInfo ( ) . stream ( ) . filter ( e - > e . getStatus ( ) . equals ( LotteryProjectDto . ConfirmEnum . JOIN . getCode ( ) ) ) . collect ( Collectors . toList ( ) ) ;
DownloadVO vo = DownloadVO . builder ( ) . build ( ) ;
switch ( lotteryProject . getLotteryType ( ) ) {
case "1" :
if ( CollectionUtil . isEmpty ( extractExpertsInfo ) ) {
throw new DataException ( "暂未有确认专家,无法打印" ) ;
}
try {
MockMultipartFile mockMultipartFile = expertPrinting ( "专家抽取结果打印.docx" , extractExpertsInfo ) ;
String temporaryFilePath = fileApi . getPath ( FileTypeConstant . TEMPORARY ) ;
FileInfo fileInfo = fileUploadApi . uploadFile ( mockMultipartFile , temporaryFilePath , "专家抽取结果打印.docx" ) ;
vo . setName ( fileInfo . getFilename ( ) ) ;
vo . setUrl ( UploaderUtil . uploaderFile ( fileInfo . getFilename ( ) + "#" + "Temporary" ) + "&name=" + "专家抽取结果打印.docx" ) ;
} catch ( Exception e ) {
log . error ( "专家抽取结果打印异常" , e ) ;
}
break ;
case "2" :
try {
if ( CollectionUtil . isEmpty ( extractExpertsInfo ) ) {
throw new DataException ( "暂未有确认公司,无法打印" ) ;
}
MockMultipartFile mockMultipartFile = companyPrinting ( "招投标公司抽取结果打印.docx" , extractExpertsInfo ) ;
String temporaryFilePath = fileApi . getPath ( FileTypeConstant . TEMPORARY ) ;
FileInfo fileInfo = fileUploadApi . uploadFile ( mockMultipartFile , temporaryFilePath , "招投标公司抽取结果打印.docx" ) ;
vo . setName ( fileInfo . getFilename ( ) ) ;
vo . setUrl ( UploaderUtil . uploaderFile ( fileInfo . getFilename ( ) + "#" + "Temporary" ) + "&name=" + "招投标公司抽取结果打印.docx" ) ;
} catch ( Exception e ) {
log . error ( "专家抽取结果打印异常" , e ) ;
}
break ;
}
return vo ;
}
private MockMultipartFile expertPrinting ( String fileName , List < LotteryProjectDto . ExtractExpertsInfo > data ) throws Exception {
try ( InputStream inputStream = ResourceUtil . getStream ( "jnpf/templete/浙江出版传媒股份有限公司ERP系统建设项目.docx" ) ;
XWPFDocument doc = new XWPFDocument ( inputStream ) ) {
// 找到标记位置的段落
XWPFParagraph placeholderParagraph = null ;
for ( XWPFParagraph paragraph : doc . getParagraphs ( ) ) {
if ( paragraph . getText ( ) . contains ( "{{table_here}}" ) ) {
placeholderParagraph = paragraph ;
break ;
}
}
if ( placeholderParagraph = = null ) {
throw new IllegalStateException ( "Cannot find placeholder in the document." ) ;
}
// 删除包含占位符的段落
XWPFRun run = placeholderParagraph . getRuns ( ) . get ( 0 ) ;
run . setText ( run . getText ( 0 ) . replace ( "{{table_here}}" , "" ) , 0 ) ;
// 在占位符位置插入表格
// 插入表格到占位符位置后
// XWPFTable table = doc.createTable();
XWPFTable table = doc . insertNewTbl ( placeholderParagraph . getCTP ( ) . newCursor ( ) ) ;
table . setWidth ( "100%" ) ;
// 创建表头
XWPFTableRow headerRow = table . getRow ( 0 ) ;
headerRow . getCell ( 0 ) . setText ( "专家编号" ) ;
headerRow . addNewTableCell ( ) . setText ( "专家姓名" ) ;
headerRow . addNewTableCell ( ) . setText ( "出版集团" ) ;
headerRow . addNewTableCell ( ) . setText ( "联系方式" ) ;
headerRow . addNewTableCell ( ) . setText ( "备注" ) ;
// 填充表格数据
for ( LotteryProjectDto . ExtractExpertsInfo datum : data ) {
XWPFTableRow row = table . createRow ( ) ;
row . getCell ( 0 ) . setText ( datum . getId ( ) ) ;
row . getCell ( 1 ) . setText ( datum . getExpertName ( ) ) ;
row . getCell ( 2 ) . setText ( datum . getWorkUnit ( ) ) ;
row . getCell ( 3 ) . setText ( datum . getPhoneNumber ( ) ) ;
row . getCell ( 4 ) . setText ( datum . getRemark ( ) ) ;
}
XWPFTableRow rowEnd = table . createRow ( ) ;
rowEnd . getCell ( 3 ) . setText ( "总人数:" + data . size ( ) ) ;
for ( XWPFTableRow row : table . getRows ( ) ) {
for ( XWPFTableCell tableCell : row . getTableCells ( ) ) {
List < XWPFParagraph > paragraphs = tableCell . getParagraphs ( ) ;
for ( XWPFParagraph paragraph : paragraphs ) {
List < XWPFRun > runs = paragraph . getRuns ( ) ;
for ( XWPFRun xwpfRun : runs ) {
xwpfRun . setFontFamily ( "仿宋" ) ;
xwpfRun . setFontSize ( 10 ) ;
}
}
}
}
// 保存Word文档
// try (FileOutputStream fos = new FileOutputStream("/Users/yangzhenli/Documents/项目/jnpf/结果打印_out.docx")) {
// doc.write(fos);
// }
// 将XWPFDocument写入ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ( ) ;
MockMultipartFile mockMultipartFile = null ;
try {
doc . write ( byteArrayOutputStream ) ;
// 将ByteArrayOutputStream转换为MockMultipartFile
mockMultipartFile = new MockMultipartFile (
fileName , // 文件名
fileName , // 原始文件名
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" , // ContentType
byteArrayOutputStream . toByteArray ( ) // 文件内容
) ;
} finally {
if ( null ! = byteArrayOutputStream ) {
byteArrayOutputStream . close ( ) ;
}
}
return mockMultipartFile ;
}
}
private MockMultipartFile companyPrinting ( String fileName , List < LotteryProjectDto . ExtractExpertsInfo > data ) throws Exception {
try ( InputStream inputStream = ResourceUtil . getStream ( "jnpf/templete/招投标公司打印.docx" ) ;
XWPFDocument doc = new XWPFDocument ( inputStream ) ) {
// 找到标记位置的段落
XWPFParagraph placeholderParagraph = null ;
for ( XWPFParagraph paragraph : doc . getParagraphs ( ) ) {
if ( paragraph . getText ( ) . contains ( "{{table_here}}" ) ) {
placeholderParagraph = paragraph ;
break ;
}
}
if ( placeholderParagraph = = null ) {
throw new IllegalStateException ( "Cannot find placeholder in the document." ) ;
}
// 删除包含占位符的段落
XWPFRun run = placeholderParagraph . getRuns ( ) . get ( 0 ) ;
run . setText ( run . getText ( 0 ) . replace ( "{{table_here}}" , "" ) , 0 ) ;
// 在占位符位置插入表格
// 插入表格到占位符位置后
// XWPFTable table = doc.createTable();
XWPFTable table = doc . insertNewTbl ( placeholderParagraph . getCTP ( ) . newCursor ( ) ) ;
table . setWidth ( "100%" ) ;
XWPFTableRow headerRow = table . getRow ( 0 ) ;
headerRow . getCell ( 0 ) . setText ( "公司编号" ) ;
headerRow . addNewTableCell ( ) . setText ( "招投标公司" ) ;
headerRow . addNewTableCell ( ) . setText ( "联系人" ) ;
headerRow . addNewTableCell ( ) . setText ( "联系方式" ) ;
headerRow . addNewTableCell ( ) . setText ( "备注" ) ;
// // 填充表格数据
for ( LotteryProjectDto . ExtractExpertsInfo datum : data ) {
int i = 0 ;
int startRowNum = 1 ;
for ( ExpertDto . ContactInformation contactInformation : datum . getContactInformation ( ) ) {
XWPFTableRow row = table . createRow ( ) ;
row . getCell ( 0 ) . setText ( datum . getId ( ) ) ;
row . getCell ( 1 ) . setText ( datum . getCompanyName ( ) ) ;
row . getCell ( 2 ) . setText ( contactInformation . getContactName ( ) ) ;
row . getCell ( 3 ) . setText ( contactInformation . getContactPhone ( ) ) ;
row . getCell ( 4 ) . setText ( datum . getRemark ( ) ) ;
if ( i = = 0 ) {
startRowNum = table . getRows ( ) . indexOf ( row ) ;
datum . setId ( "" ) ;
datum . setCompanyName ( "" ) ;
}
i + + ;
}
mergeCellsVertically ( table , 0 , startRowNum , ( datum . getContactInformation ( ) . size ( ) - 1 ) + startRowNum ) ;
mergeCellsVertically ( table , 1 , startRowNum , ( datum . getContactInformation ( ) . size ( ) - 1 ) + startRowNum ) ;
mergeCellsVertically ( table , 4 , startRowNum , ( datum . getContactInformation ( ) . size ( ) - 1 ) + startRowNum ) ;
}
// 保存Word文档
// try (FileOutputStream fos = new FileOutputStream("/Users/yangzhenli/Documents/项目/jnpf/结果打印_out.docx")) {
// doc.write(fos);
// }
// 将XWPFDocument写入ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream ( ) ;
MockMultipartFile mockMultipartFile = null ;
try {
doc . write ( byteArrayOutputStream ) ;
// 将ByteArrayOutputStream转换为MockMultipartFile
mockMultipartFile = new MockMultipartFile (
fileName , // 文件名
fileName , // 原始文件名
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" , // ContentType
byteArrayOutputStream . toByteArray ( ) // 文件内容
) ;
} finally {
byteArrayOutputStream . close ( ) ;
}
return mockMultipartFile ;
}
}
@Override
public void uploadExtractionResults ( LotteryProjectDto . UploadExtractionResults param ) {
if ( StrUtil . isBlank ( param . getId ( ) ) ) {
throw new DataException ( "id不能为空" ) ;
}
LotteryProject lotteryProject = this . getById ( param . getId ( ) ) ;
lotteryProject . setUploadResultsInfo ( param . getUploaderVO ( ) ) ;
lotteryProject . setStatus ( LotteryProjectDto . StatusEnum . ALREADY_EXTRACTED . getCode ( ) ) ;
lotteryProject . setStatusName ( LotteryProjectDto . StatusEnum . ALREADY_EXTRACTED . getDescribe ( ) ) ;
this . saveOrUpdate ( lotteryProject ) ;
}
@Override
public List < Expert > getCompanyByReview ( String reviewId ) {
if ( StrUtil . isBlank ( reviewId ) ) {
throw new DataException ( "评审ID不能为空" ) ;
}
//获取评审信息
LotteryReview lotteryReview = iLotteryReviewService . getById ( reviewId ) ;
//获取已专家编号列表抽取
List < String > expertIdList = null ;
if ( null ! = lotteryReview . getExtractExpertsInfo ( ) ) {
expertIdList = lotteryReview . getExtractExpertsInfo ( ) . stream ( ) . map ( LotteryProjectDto . ExtractExpertsInfo : : getId ) . collect ( Collectors . toList ( ) ) ;
}
return expertService . lambdaQuery ( )
. eq ( Expert : : getStatus , "0" )
. eq ( Expert : : getDelFlag , "0" )
. eq ( Expert : : getDataType , "2" )
. notIn ( CollectionUtil . isNotEmpty ( expertIdList ) , Expert : : getId , expertIdList )
. list ( ) ;
}
public static void main ( String [ ] args ) throws IOException {
String s = "[\n" +
" {\n" +
" \"id\": \"EXPERT00010\",\n" +
" \"expertName\": \"测试专家\",\n" +
" \"expertGroup\": \"\",\n" +
" \"phoneNumber\": \"13467167538\",\n" +
" \"workUnit\": \"工作单位\",\n" +
" \"confirmTime\": \"2024-09-03 15:09:50\",\n" +
" \"confirmName\": \"一级\",\n" +
" \"confirmId\": \"568797187002084037\",\n" +
" \"status\": \"1\",\n" +
" \"remark\": \"同意\",\n" +
" \"showJoinButton\": false,\n" +
" \"extractionRounds\": \"4\"\n" +
" },\n" +
" {\n" +
" \"id\": \"EXPERT00011\",\n" +
" \"expertName\": \"测试专家2\",\n" +
" \"expertGroup\": \"\",\n" +
" \"phoneNumber\": \"13467167539\",\n" +
" \"workUnit\": \"工作单位2\",\n" +
" \"confirmTime\": \"2024-09-03 15:10:38\",\n" +
" \"confirmName\": \"一级\",\n" +
" \"confirmId\": \"568797187002084037\",\n" +
" \"status\": \"1\",\n" +
" \"remark\": \"同意\",\n" +
" \"showJoinButton\": false,\n" +
" \"extractionRounds\": \"5\"\n" +
" }\n" +
" ]" ;
String s2 = "[\n" +
" {\n" +
" \"id\": \"COMPANY00002\",\n" +
" \"expertName\": null,\n" +
" \"expertGroup\": null,\n" +
" \"phoneNumber\": null,\n" +
" \"workUnit\": null,\n" +
" \"confirmTime\": \"2024-09-04 11:08:31\",\n" +
" \"confirmName\": \"一级\",\n" +
" \"confirmId\": \"568797187002084037\",\n" +
" \"status\": \"1\",\n" +
" \"remark\": \"通过\",\n" +
" \"showJoinButton\": false,\n" +
" \"contactInformation\":\n" +
" [\n" +
" {\n" +
" \"contactName\": \"杨振立\",\n" +
" \"contactPhone\": \"18177857446\"\n" +
" }\n" +
" ],\n" +
" \"companyName\": \"测试公司名称\",\n" +
" \"extractionRounds\": \"1\"\n" +
" },\n" +
" {\n" +
" \"id\": \"COMPANY00002\",\n" +
" \"expertName\": null,\n" +
" \"expertGroup\": null,\n" +
" \"phoneNumber\": null,\n" +
" \"workUnit\": null,\n" +
" \"confirmTime\": \"2024-09-04 11:08:31\",\n" +
" \"confirmName\": \"一级\",\n" +
" \"confirmId\": \"568797187002084037\",\n" +
" \"status\": \"1\",\n" +
" \"remark\": \"通过\",\n" +
" \"showJoinButton\": false,\n" +
" \"contactInformation\":\n" +
" [\n" +
" {\n" +
" \"contactName\": \"杨振立\",\n" +
" \"contactPhone\": \"18177857446\"\n" +
" },\n" +
" {\n" +
" \"contactName\": \"联系姓名1\",\n" +
" \"contactPhone\": \"18104627731\"\n" +
" }\n" +
" ],\n" +
" \"companyName\": \"测试公司名称\",\n" +
" \"extractionRounds\": \"1\"\n" +
" }\n" +
"]" ;
// List<LotteryProjectDto.ExtractExpertsInfo> data = JSON.parseArray(s, LotteryProjectDto.ExtractExpertsInfo.class);
List < LotteryProjectDto . ExtractExpertsInfo > data = JSON . parseArray ( s2 , LotteryProjectDto . ExtractExpertsInfo . class ) ;
try ( InputStream inputStream = new FileInputStream ( new File ( "/Users/yangzhenli/Documents/项目/jnpf/浙江出版传媒股份有限公司ERP系统建设项目.docx" ) ) ;
XWPFDocument doc = new XWPFDocument ( inputStream ) ) {
// 找到标记位置的段落
XWPFParagraph placeholderParagraph = null ;
for ( XWPFParagraph paragraph : doc . getParagraphs ( ) ) {
if ( paragraph . getText ( ) . contains ( "{{table_here}}" ) ) {
placeholderParagraph = paragraph ;
break ;
}
}
if ( placeholderParagraph = = null ) {
throw new IllegalStateException ( "Cannot find placeholder in the document." ) ;
}
// 删除包含占位符的段落
XWPFRun run = placeholderParagraph . getRuns ( ) . get ( 0 ) ;
run . setText ( run . getText ( 0 ) . replace ( "{{table_here}}" , "" ) , 0 ) ;
// 在占位符位置插入表格
// 插入表格到占位符位置后
// XWPFTable table = doc.createTable();
XWPFTable table = doc . insertNewTbl ( placeholderParagraph . getCTP ( ) . newCursor ( ) ) ;
table . setWidth ( "100%" ) ;
XWPFTableRow headerRow = table . getRow ( 0 ) ;
headerRow . getCell ( 0 ) . setText ( "公司编号" ) ;
headerRow . addNewTableCell ( ) . setText ( "招投标公司" ) ;
headerRow . addNewTableCell ( ) . setText ( "联系人" ) ;
headerRow . addNewTableCell ( ) . setText ( "联系方式" ) ;
headerRow . addNewTableCell ( ) . setText ( "备注" ) ;
// // 填充表格数据
for ( LotteryProjectDto . ExtractExpertsInfo datum : data ) {
int i = 0 ;
int startRowNum = 1 ;
for ( ExpertDto . ContactInformation contactInformation : datum . getContactInformation ( ) ) {
XWPFTableRow row = table . createRow ( ) ;
row . getCell ( 0 ) . setText ( datum . getId ( ) ) ;
row . getCell ( 1 ) . setText ( datum . getCompanyName ( ) ) ;
row . getCell ( 2 ) . setText ( contactInformation . getContactName ( ) ) ;
row . getCell ( 3 ) . setText ( contactInformation . getContactPhone ( ) ) ;
row . getCell ( 4 ) . setText ( datum . getRemark ( ) ) ;
if ( i = = 0 ) {
startRowNum = table . getRows ( ) . indexOf ( row ) ;
datum . setId ( "" ) ;
datum . setCompanyName ( "" ) ;
}
i + + ;
}
mergeCellsVertically ( table , 0 , startRowNum , ( datum . getContactInformation ( ) . size ( ) - 1 ) + startRowNum ) ;
mergeCellsVertically ( table , 1 , startRowNum , ( datum . getContactInformation ( ) . size ( ) - 1 ) + startRowNum ) ;
mergeCellsVertically ( table , 4 , startRowNum , ( datum . getContactInformation ( ) . size ( ) - 1 ) + startRowNum ) ;
}
// // 在该行中添加三个单元格
// row.createCell();
// row.createCell();
//
// // 假设我们要拆分第一个单元格
// int cellIndexToSplit = 0;
//
// // 获取要拆分的单元格
// XWPFTableCell cellToSplit = row.getCell(cellIndexToSplit);
//
// // 获取原始单元格的内容
// String originalText = cellToSplit.getText();
//
// // 移除第一个单元格
// row.removeCell(cellIndexToSplit);
//
// // 创建两个新单元格
// XWPFTableCell newCell1 = row.createCell();
// XWPFTableCell newCell2 = row.createCell();
//
// // 设置新单元格的内容
// newCell1.setText("First part of split");
// newCell2.setText("Second part of split");
//
// // 将新的单元格移到正确的位置
// // POI中不能直接在特定位置插入新单元格,只能依次添加。
// // 因此,我们需要重新调整所有单元格的顺序。
//
// // 调整现有单元格的顺序,确保表格结构正确
// XWPFTableCell thirdCell = row.getCell(2); // 获取原始的第三个单元格
// row.removeCell(2); // 移除第三个单元格
// row.addNewTableCell(); // 重新创建第二个单元格(此时是新创建的空单元格)
// row.addNewTableCell(); // 创建第三个单元格(空)
// 将原始第三个单元格的内容移动到最后
// row.getCell(2).setText(thirdCell.getText());
// // 创建表头
// XWPFTableRow headerRow = table.getRow(0);
// headerRow.getCell(0).setText("专家编号");
// headerRow.addNewTableCell().setText("专家姓名");
// headerRow.addNewTableCell().setText("出版集团");
// headerRow.addNewTableCell().setText("联系方式");
// headerRow.addNewTableCell().setText("备注");
//
// // 填充表格数据
// for (LotteryProjectDto.ExtractExpertsInfo datum : data) {
//
// XWPFTableRow row = table.createRow();
// row.getCell(0).setText(datum.getId());
// row.getCell(1).setText(datum.getExpertName());
// row.getCell(2).setText(datum.getWorkUnit());
// row.getCell(3).setText(datum.getPhoneNumber());
// row.getCell(4).setText(datum.getRemark());
// }
// XWPFTableRow rowEnd = table.createRow();
// XWPFTableCell cell = rowEnd.getCell(0);
// // 设置单元格的文本
// // 获取或创建 TcPr(单元格属性)
// if (cell.getCTTc().getTcPr() == null) {
// cell.getCTTc().addNewTcPr();
// }
// cell.setText("总人数: "+data.size()+" ");
// // 合并第一行的单元格,从第一个单元格到第5个单元格
// for (int colIndex = 0; colIndex <= 4; colIndex++) {
// XWPFTableCell cell1 = rowEnd.getCell(colIndex);
// if (cell1.getCTTc().getTcPr() == null) {
// cell1.getCTTc().addNewTcPr();
// }
// if (colIndex == 0) {
// // 设置起始单元格跨越的列数
// cell1.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.RESTART);
// } else {
// // 其他单元格设为继续合并
// cell1.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
// }
// }
//
// // 设置单元格文本向右对齐
// cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT);
//
// for (XWPFTableRow row : table.getRows()) {
// for (XWPFTableCell tableCell : row.getTableCells()) {
// List<XWPFParagraph> paragraphs = tableCell.getParagraphs();
// for (XWPFParagraph paragraph : paragraphs) {
// List<XWPFRun> runs = paragraph.getRuns();
// for (XWPFRun xwpfRun : runs) {
// xwpfRun.setFontFamily("仿宋");
// xwpfRun.setFontSize(10);
// }
// }
// }
// }
// 保存Word文档
try ( FileOutputStream fos = new FileOutputStream ( "/Users/yangzhenli/Documents/项目/jnpf/结果打印_out.docx" ) ) {
doc . write ( fos ) ;
}
}
}
private static void mergeCellsVertically ( XWPFTable table , int col , int fromRow , int toRow ) {
for ( int rowIndex = fromRow ; rowIndex < = toRow ; rowIndex + + ) {
XWPFTableCell cell = table . getRow ( rowIndex ) . getCell ( col ) ;
if ( rowIndex = = fromRow ) {
// 设置合并的起始单元格的属性
cell . getCTTc ( ) . addNewTcPr ( ) . addNewVMerge ( ) . setVal ( STMerge . Enum . forString ( "restart" ) ) ;
} else {
// 设置被合并的单元格的属性
cell . getCTTc ( ) . addNewTcPr ( ) . addNewVMerge ( ) . setVal ( STMerge . Enum . forString ( "continue" ) ) ;
}
}
}
}