Commit 9cb3780a authored by 侯彦文's avatar 侯彦文

生成案卷目录

parent dab44b67
......@@ -20,6 +20,12 @@
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-common</artifactId>
<version>4.1-20241024-RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-expand</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.yonde.dex</groupId>
......
......@@ -188,6 +188,7 @@ public class ExtDesignReviewNoticeVO extends IdOnlyVO implements IdVO ,DxContext
@VersionProperty(curVersion = VersionRelationType.ITERATION, refVersion = VersionRelationType.NONE)
private List<ExtNoticeContactLinkVO> extNoticeContactLinks;
/**
* 主持人
*/
......@@ -277,6 +278,8 @@ public class ExtDesignReviewNoticeVO extends IdOnlyVO implements IdVO ,DxContext
*/
private String sendPerson;
}
......@@ -29,4 +29,9 @@ public class ExtTransferDocProjectVO {
*/
private String topicTitle;
/**
* 项目ID
*/
private Long projectId;
}
......@@ -30,6 +30,12 @@
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-core</artifactId>
<version>4.1-20241024-RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-expand</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.yonde.dcs</groupId>
......@@ -145,6 +151,13 @@
<version>1.4</version>
</dependency>
<!-- POI -->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.9.0-beta</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
......
......@@ -9,10 +9,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import java.util.List;
......@@ -38,6 +35,13 @@ public class ExtFilesController<V extends ExtFilesVO, S extends ExtFilesService<
return ApiResult.ok(extFilesVOList);
}
@ApiOperation(value = "生成案卷目录", notes = "生成案卷目录")
@PostMapping(value = "/generatFilesDirectory")
public ApiResult generatFilesDirectory(@RequestParam("id") Long id) {
extFilesService.generatFilesDirectory(id);
return ApiResult.ok("生成成功");
}
}
......@@ -38,4 +38,7 @@ public interface ExtFilesService<V extends ExtFilesVO> extends ExtFilesServiceSh
*/
List<ExtFilesVO> getExtFilesByProjectCode(ExtFilesUpdateVO extFilesUpdateVO);
void generatFilesDirectory(Long id);
}
package com.inet.dcs.document.core.service.impl;
import cn.hutool.core.lang.Assert;
import com.inet.dcs.document.common.vo.ExtFilesDocLinkVO;
import com.inet.dcs.document.common.vo.ExtFilesVO;
import com.inet.dcs.document.common.vo.archivesOtherVO.ExtFilesUpdateVO;
......@@ -9,9 +10,11 @@ import com.inet.dcs.document.core.service.ExtDocService;
import com.inet.dcs.document.core.service.ExtFilesDocLinkService;
import com.inet.dcs.document.core.service.ExtFilesService;
import com.inet.dcs.document.core.util.SearchUtil;
import com.inet.dcs.document.core.util.WordUtils;
import com.inet.dcs.document.entity.po.ExtFiles;
import com.yonde.dex.basedata.data.search.SearchItem;
import com.yonde.dex.basedata.data.search.SearchItems;
import com.yonde.dex.basedata.data.search.SearchQueryBuilder;
import com.yonde.dex.basedata.data.search.SearchQueryCondition;
import com.yonde.dex.basedata.entity.data.DxPageImpl;
import com.yonde.dex.basedata.entity.data.OperatorType;
......@@ -20,14 +23,23 @@ import com.yonde.dex.basic.feign.expand.ExtDxContextProjectServiceFeign;
import com.yonde.dex.context.common.vo.DxContextProjectVO;
import com.yonde.dex.context.common.vo.DxContextVO;
import com.yonde.dex.dao.service.DxDaoPluginExpander;
import com.yonde.dex.dfs.feign.FileManagerFeignService;
import com.yonde.dex.dfs.objfilelink.enums.FileTypeEnum;
import com.yonde.dex.dfs.objfilelink.plugin.core.util.DxObjFileUtils;
import com.yonde.dex.dfs.vo.RepoFileVO;
import com.yonde.dex.dict.feign.DictDataFeignService;
import com.yonde.dex.feign.applink.DxAppModelDefLinkFeignService;
import com.yonde.dex.vo.info.DxApplicationVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection;
import java.util.List;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
/**
* @description: ExtFiles-ServiceImpl
......@@ -41,6 +53,9 @@ public class ExtFilesServiceImpl<V extends ExtFilesVO> implements ExtFilesServic
public static final String BEAN_NAME = "extFilesServiceImpl";
List<String> ALL_PDF_PATH = Collections.synchronizedList(new ArrayList<>());
@Autowired
ExtFilesRepository<ExtFiles> extFilesRepository;
......@@ -59,6 +74,12 @@ public class ExtFilesServiceImpl<V extends ExtFilesVO> implements ExtFilesServic
@Autowired
private ExtDocService extDocService;
@Autowired
private DxAppModelDefLinkFeignService dxAppModelDefLinkFeignService;
@Autowired
private FileManagerFeignService fileManagerFeignService;
@Override
public void beforeSave(Collection<V> target) {
// 全宗号+项目号+项目代号+类别代号+盒号(三位流水号)+后缀“-(两位数字流水号)例如:2-20114272031-QH03-JS01-001-(01)
......@@ -198,6 +219,108 @@ public class ExtFilesServiceImpl<V extends ExtFilesVO> implements ExtFilesServic
return caseNumberBuilder.append(caseNumber).toString();
}
@Override
public void generatFilesDirectory(Long id) {
//查询项目组下所有子项目与子项包括项目群
List<Long> childList = this.getChildList(id, new ArrayList<>());
//父节点id
childList.add(id);
DxContextProjectVO dxContextProjectVO = (DxContextProjectVO) extDxContextProjectServiceFeign.get(id);
//查询项目群下所有案卷
SearchQueryCondition searchProgram = SearchUtil.buildQuery("dxContextId", SearchItem.Operator.IN, childList);
List<V> content = this.findRecursion(searchProgram).getContent();
//查询案卷下文件清单
List<Long> extFilesIdList = content.stream().map(v -> v.getId()).collect(Collectors.toList());
SearchQueryCondition build = SearchQueryBuilder.openBuild().openFilterBuilder().setItemWithIN("targetId", extFilesIdList).closeFilterBuilder().setPropName("target").setPropName("source").build();
List<ExtFilesDocLinkVO> extFilesDocLinkVOList = extFilesDocLinkService.findRecursion(build).getContent();
List<Map<String, Object>> extFilesMap = new ArrayList<>();
Map<String, Object> resultDatas = new HashMap<>();
int serialNumber = 0;
int zhNumber = 0;
int jjNumber = 0;
int sbNumber = 0;
int jsNumber = 0;
int countNumber=0;
for (ExtFilesDocLinkVO extFilesDocLinkVO:extFilesDocLinkVOList){
Map<String, Object> datas = new HashMap<>();
ExtFilesVO target = extFilesDocLinkVO.getTarget();
datas.put("contextName",dxContextProjectVO.getName());
datas.put("serialNumber",serialNumber);
datas.put("categoryNumber",categoryNumber(target.getCategoryNumber(),zhNumber,jjNumber,sbNumber,jsNumber,countNumber));
datas.put("volumeNumber",target.getVolumeNumber());
datas.put("caseName",target.getCaseName());
datas.put("pageNumber",target.getPageNumber());
datas.put("remarks",target.getRemarks());
datas.put("number",countNumber);
extFilesMap.add(datas);
serialNumber++;
}
resultDatas.put("data", extFilesMap);
String string = convertPdf("案卷目录模板.docx", resultDatas);
/*File pdfFile = new File(string);*/
MultipartFile multipartFile = DxObjFileUtils.createFile(string);
DxApplicationVO modelApp = dxAppModelDefLinkFeignService.findAppByModelName("DxContextProject");
Assert.notNull(modelApp.getBucketId(), String.format("当前应用%s未绑定桶!", modelApp.getName()));
RepoFileVO fileVo = fileManagerFeignService.uploadFile(multipartFile, Long.parseLong(modelApp.getBucketId()));
DxObjFileUtils.replaceFile(dxContextProjectVO, fileVo, FileTypeEnum.MASTER_FILE);
dxContextProjectVO.setOperator(OperatorType.MODIFY);
extDxContextProjectServiceFeign.saveRecursion(dxContextProjectVO);
}
public String categoryNumber(String categoryNumber,int zhNumber,int jjNumber,int sbNumber,int jsNumber,int countNumber){
if (categoryNumber.contains("ZH")){
categoryNumber = "综合";
zhNumber++;
countNumber= zhNumber;
}
if (categoryNumber.contains("JJ")){
categoryNumber = "基建";
jjNumber++;
countNumber= jjNumber;
}
if (categoryNumber.contains("SB")){
categoryNumber = "设备";
sbNumber++;
countNumber= sbNumber;
}
if (categoryNumber.contains("JS")){
categoryNumber = "技术";
jsNumber++;
countNumber = jsNumber;
}
return categoryNumber;
}
public String convertPdf(String modelName, Map<String, Object> dataMap) {
String targetPath = System.getProperty("user.dir") + "/TEMP/";
File wordFile = new File(targetPath + modelName);
File pdfFile2 = new File("TEMP/" + modelName + "---" + UUID.randomUUID() + ".pdf");
try {
InputStream tempStream2 = Files.newInputStream(wordFile.toPath());
OutputStream outputStream = Files.newOutputStream(pdfFile2.toPath());
byte[] bytes2 = WordUtils.fillWord(dataMap, tempStream2);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes2);
WordUtils.wordToPDF(byteArrayInputStream, outputStream);
byteArrayInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return pdfFile2.getAbsolutePath();
}
//递归根据项目群查询项目子项
public List<Long> getChildList(Long partId, List<Long> list) {
SearchQueryCondition build = SearchQueryBuilder.openBuild().openFilterBuilder().setEq("parentId", partId).closeFilterBuilder().build();
List<DxContextProjectVO> dxContextProjectVOS= extDxContextProjectServiceFeign.findRecursion(build).getContent();
for (DxContextProjectVO dxContextProjectVO : dxContextProjectVOS) {
list.add(dxContextProjectVO.getId());
getChildList(dxContextProjectVO.getId(), list);
}
return list;
}
}
......@@ -144,13 +144,13 @@ public class ExtTransferDocumentServiceImpl<V extends ExtTransferDocumentVO> imp
if ("program".equals(dxContextProjectVO.getProjectClass())) {
extTransferDocProjectVO.setProjectCode(dxContextProjectVO.getNumber());
extTransferDocProjectVO.setProjectGroupName(dxContextProjectVO.getName());
extTransferDocProjectVO.setProjectId(dxContextProjectVO.getParentId());
return extTransferDocProjectVO;
} else if ("project".equals(dxContextProjectVO.getProjectClass())) {
extTransferDocProjectVO.setProjectName(dxContextProjectVO.getName());
} else if ("childProject".equals(dxContextProjectVO.getProjectClass())) {
extTransferDocProjectVO.setTopicTitle(dxContextProjectVO.getName());
}
id = dxContextProjectVO.getParentId();
}
}
......
package com.inet.dcs.document.core.util;
import cn.hutool.poi.word.WordUtil;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
......@@ -23,6 +33,7 @@ import java.util.Map;
* @Description Word文件操作工具包
* @createTime 2021/09/02 14:42:00
*/
@Slf4j
public class WordUtils {
/**
......@@ -290,4 +301,94 @@ public class WordUtils {
return result;
}
/**
* 填充word模板,获取填充后的word文件流:
*
* @param datas: 填充数据
* @param fileStream: 文件模板流 -- 可从OSS/FastDFS上获取流,直接传入;
* @return
* @throws IOException
*/
public static byte[] fillWord(Map<String, Object> datas, InputStream fileStream) throws IOException {
XWPFTemplate template = null;
ByteArrayOutputStream wordOut = new ByteArrayOutputStream(1024);
try {
//设置占位符:
Configure config = Configure.builder()
.buildGramer("${", "}") //设置模板中的占位符${}, 默认是{{}}
.setValidErrorHandler(new Configure.AbortHandler()) //若模板中占位符与填充属性不对应,则报错;
.bind("data", new HackLoopTableRenderPolicy()) //设置模板中表格的参数属性
.build();
//填充文本域:
template = XWPFTemplate.compile(fileStream, config).render(datas);
template.write(wordOut);
} catch (RenderException ex) {
log.error("模板填充失败,请保证模板文本域与参数保持一致。错误信息::{}", ex);
throw ex;
} catch (IOException ex) {
log.error("系统异常::{}", ex);
throw ex;
} finally {
try {
if (template != null) {
template.close();
}
} catch (IOException ex) {
log.error("关闭文件流资源异常::{}", ex);
}
}
return wordOut.toByteArray();
}
/**
* word转pdf
*
* @param wordInStream: word文件输入流;
* @param pdfOutStream: pdf文件输出流;
*/
public static void wordToPDF(InputStream wordInStream, OutputStream pdfOutStream) {
try {
getLicense();
//因linux环境没有语言包,当项目部署到linux环境后,转成的pdf中的中文是类似乱码的,所以需要去加载此目录下的语言包;
OsInfo osInfo = SystemUtil.getOsInfo();
if (osInfo.isLinux()) {
//====================================== 注意 ============================================
//注意: 需要把项目中resource/fonts目录下的语言包全部放到linux中的此目录下,否则linux环境中处理是乱码;
//以下是我自己定义的目录,你可随意更改为你linux上的目录;
//FontSettings.setFontsFolder("/usr/share/fonts/chinese", true);
//=======================================================================================
}
//Address是将要被转化的word文档
com.aspose.words.Document doc = new com.aspose.words.Document(wordInStream);
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
doc.save(pdfOutStream, SaveFormat.PDF);
} catch (Exception e) {
log.error("word转pdf异常::{}", e);
throw new RuntimeException("word转pdf异常");
}
}
/**
* 获取license 去除水印
*
* @return
*/
public static boolean getLicense() {
try {
InputStream licenseIn = WordUtil.class.getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(licenseIn);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
......@@ -25,6 +25,12 @@
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-entity</artifactId>
<version>4.1-20241024-RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-expand</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.yonde.dex</groupId>
......
......@@ -24,6 +24,12 @@
<groupId>com.yonde.dcs</groupId>
<artifactId>dcs-doc-feign</artifactId>
<version>4.1-20241024-RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.yonde.dex</groupId>
<artifactId>dcs-doc-expand</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.yonde.dex</groupId>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment