From 6fe37e6b50148b319dccb6890ea067bc6b72af52 Mon Sep 17 00:00:00 2001 From: liyawei Date: Fri, 8 Jul 2022 18:03:33 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A4=E8=AF=81-=E4=B8=8A=E6=8A=A5=E5=BA=93-?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParamsReportDetailEOController.java | 20 +- .../service/IParamsReportDetailEOService.java | 9 + .../impl/ParamsReportDetailEOServiceImpl.java | 201 +++++++- .../modules/cert/report/util/Docx4jUtil.java | 481 ++++++++++++++++++ .../cert/report/vo/ParamsReportDetailVO.java | 17 +- 5 files changed, 695 insertions(+), 33 deletions(-) create mode 100644 jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/util/Docx4jUtil.java diff --git a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/controller/ParamsReportDetailEOController.java b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/controller/ParamsReportDetailEOController.java index 718155cc4..8d3e9f61e 100644 --- a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/controller/ParamsReportDetailEOController.java +++ b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/controller/ParamsReportDetailEOController.java @@ -1,13 +1,10 @@ package com.jero.modules.cert.report.controller; -import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.jero.common.api.vo.Result; import com.jero.common.aspect.annotation.AutoLog; import com.jero.common.system.base.controller.JeroController; -import com.jero.modules.cert.collect.entity.ParamsCollectManifestEO; -import com.jero.modules.cert.collect.vo.ParamsCollectManifestVO; import com.jero.modules.cert.report.entity.ParamsReportDetailEO; import com.jero.modules.cert.report.service.IParamsReportDetailEOService; import com.jero.modules.cert.report.vo.ParamsReportDetailVO; @@ -15,9 +12,11 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -89,7 +88,7 @@ public class ParamsReportDetailEOController extends JeroController> getHeader(String paramsManifestId, String flag, String cut); + /** + * 常规导出 + * @param paramsReportDetailVO + * @param response + * @param request + */ void exportNormal(ParamsReportDetailVO paramsReportDetailVO, HttpServletResponse response, HttpServletRequest request); // 配置-下拉选项 @@ -43,4 +49,7 @@ public interface IParamsReportDetailEOService extends IService> getTemplateLabelList(); + + void exportCustom(ParamsReportDetailVO paramsReportDetailVO, HttpServletResponse response, HttpServletRequest request); + } diff --git a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/service/impl/ParamsReportDetailEOServiceImpl.java b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/service/impl/ParamsReportDetailEOServiceImpl.java index 18b71515c..53f031739 100644 --- a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/service/impl/ParamsReportDetailEOServiceImpl.java +++ b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/service/impl/ParamsReportDetailEOServiceImpl.java @@ -14,7 +14,8 @@ import com.jero.common.exception.JeroBootException; import com.jero.common.util.oss.CosBootUtil; import com.jero.generater.modules.online.cgform.entity.OnlCgformField; import com.jero.generater.modules.online.cgform.service.impl.OnlCgformFieldServiceImpl; -import com.jero.modules.cert.collect.entity.*; +import com.jero.modules.cert.collect.entity.ParamsConfigDataEO; +import com.jero.modules.cert.collect.entity.ParamsConfigEO; import com.jero.modules.cert.collect.enums.CollectManifestStateEnum; import com.jero.modules.cert.collect.enums.ConfigDataTypeEnum; import com.jero.modules.cert.collect.vo.ParamsConfigDataVO; @@ -22,34 +23,23 @@ import com.jero.modules.cert.report.entity.*; import com.jero.modules.cert.report.enums.ExportTypeEnum; import com.jero.modules.cert.report.mapper.ParamsReportDetailEOMapper; import com.jero.modules.cert.report.service.*; +import com.jero.modules.cert.report.util.Docx4jUtil; import com.jero.modules.cert.report.vo.ParamsReportDetailVO; import com.jero.modules.cert.template.enums.ControlTypeEnum; -import com.jero.modules.document.enums.FieldTypeEnum; import com.jero.modules.ocr.util.LineHumpUtil; import com.jero.modules.oss.entity.OSSFile; import com.jero.modules.oss.service.IOSSFileService; -import com.jero.modules.split.common.ConvertHtml2Excel; import com.jero.modules.split.common.ReadExcel; -import com.jero.modules.split.dto.FileSpiltValTableExportDto; -import com.jero.modules.split.dto.FileSplitValExportDto; -import com.jero.modules.split.dto.FileSplitValImgExportDto; -import com.jero.modules.split.entity.SarFileSplitItemsValEO; -import com.jero.modules.split.page.SarFileSplitItemsEOPage; -import com.jero.modules.split.page.SarFileSplitItemsValEOPage; import com.jero.modules.system.entity.SysDictItem; import com.jero.modules.system.service.ISysDictItemService; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.entity.ContentType; -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.usermodel.*; import org.aspectj.util.FileUtil; +import org.docx4j.openpackaging.exceptions.Docx4JException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mock.web.MockMultipartFile; @@ -97,6 +87,10 @@ public class ParamsReportDetailEOServiceImpl extends ServiceImpl fieldList = Arrays.asList(field.split(",")); // list形式 // 查询导出数据 - List> allParamsInfoList = queryForExport(paramsReportDetailVO); // id记得去掉 + List> allParamsInfoList = queryForExportNormal(paramsReportDetailVO); // id记得去掉 // 开始处理工作表 List allRelevFileList = new ArrayList<>(); @@ -641,9 +635,6 @@ public class ParamsReportDetailEOServiceImpl extends ServiceImpl> getTemplateLabelList() { // 查询所有导出模板 @@ -664,6 +655,104 @@ public class ParamsReportDetailEOServiceImpl extends ServiceImpl allParamsInfoList = queryForExportCustom(paramsReportDetailVO); + Map params = allParamsInfoList.get(0); + + String templateUrl = ""; + ParamsExportTemplateEO paramsExportTemplateEO = paramsExportTemplateEOService.getById(paramsReportDetailVO.getExportTemplateId()); + List ossFiles = ossFileService.getFileInfosByConnectId(paramsExportTemplateEO.getFileConnectId()); + if (CollectionUtil.isNotEmpty(ossFiles)) { + templateUrl = ossFiles.get(0).getUrl(); + } + + // 替换模板中的占位符 + try { + //下载关联文件内容 + List allRelevFileList = (List) allParamsInfoList.get(1).get("fileListAll"); + if (allRelevFileList != null && !allRelevFileList.isEmpty()) { + allRelevFileList = allRelevFileList.stream().distinct().collect(Collectors.toList()); + downLoadFileList(allRelevFileList,fileNowPath + File.separator + "导出文件"); + } + + String repFileName = fileName.replaceAll("/","_"); + wordOS = new FileOutputStream(fileNowPath + File.separator + repFileName); + if (CosBootUtil.doesObjectExist(templateUrl)) { + InputStream wordTemplate = CosBootUtil.download(templateUrl); + com.qcloud.cos.utils.IOUtils.copy(wordTemplate, wordOS); + } + + byte[] wordContent = Docx4jUtil.of(fileNowPath + File.separator + repFileName).addParam("title", "测试文档标题") + .addParams(params) + .get(); + + response.setHeader("Content-Disposition", + "attachment; filename=\""+ ReadExcel.encodeFileName(fileOriName+".zip", request) +"\""); + response.setContentType("application/force-download"); + response.flushBuffer(); + os = response.getOutputStream(); + + wordOS.flush(); + wordOS.close(); + ZipUtil.zip(fileNowPath,fileNowPath+".zip"); +// FileInputStream fis = new FileInputStream(fileNowPath+".zip"); + ByteArrayInputStream fis = new ByteArrayInputStream(wordContent); + int len = 0; + while ((len = fis.read()) != -1) { + os.write(len); + } + + // 添加导出历史 + /*String uploadFileName = fileOriName + ".zip"; + MultipartFile mFile = new MockMultipartFile(uploadFileName, uploadFileName, ContentType.APPLICATION_OCTET_STREAM.toString(), fis); // 用于上传 + OSSFile ossFile = ossFileService.uploadLocalOfCos(mFile, "/report", "", CutEnum.CN.getValue()); // 上传导出的压缩包 + ParamsReportExportHistoryEO paramsReportExportHistoryEO = new ParamsReportExportHistoryEO(); + paramsReportExportHistoryEO.setExportType(ExportTypeEnum.NORMAL.getValue()); + paramsReportExportHistoryEO.setExportFileId(ossFile.getId()); + paramsReportExportHistoryEO.setParamsManifestId(paramsReportDetailVO.getParamsManifestId()); + paramsReportExportHistoryEO.setExportTime(new Date()); + paramsReportExportHistoryEOService.add(paramsReportExportHistoryEO);*/ + + os.flush(); + os.close(); // 后开先关 + fis.close(); // 先开后关 + + } catch (Docx4JException e) { + log.error(e.getMessage(), e); + + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new JeroBootException("下载文件失败,请重试"); + + } finally { + IOUtils.closeQuietly(os); + IOUtils.closeQuietly(wordOS); + File tempZipFile = new File(uploadpath + "/tempZip"); + FileUtil.deleteContents(tempZipFile); + } + + } + private void downLoadFileList(List allRelevFileList,String fileNowPath) { File nowFile = new File(fileNowPath); if (nowFile.exists()){ @@ -710,7 +799,7 @@ public class ParamsReportDetailEOServiceImpl extends ServiceImpl> queryForExport(ParamsReportDetailVO paramsReportDetailVO) { + private List> queryForExportNormal(ParamsReportDetailVO paramsReportDetailVO) { List idList = new ArrayList<>(); if (StringUtils.isNotEmpty(paramsReportDetailVO.getIds())) { idList = Arrays.asList(paramsReportDetailVO.getIds().split(",")); @@ -803,6 +892,80 @@ public class ParamsReportDetailEOServiceImpl extends ServiceImpl queryForExportCustom(ParamsReportDetailVO paramsReportDetailVO) { + List idList = new ArrayList<>(); + if (StringUtils.isNotEmpty(paramsReportDetailVO.getIds())) { + idList = Arrays.asList(paramsReportDetailVO.getIds().split(",")); + } + List configIdList = Arrays.asList(paramsReportDetailVO.getConfigIds().split(",")); + List> dataList = paramsReportDetailEOMapper.listInfoForExport(idList, paramsReportDetailVO); + + List paramsConfigEOList = paramsReportConfigEOService.queryList(paramsReportDetailVO.getParamsManifestId()); // 查询所有配置列 + + List resultList = new ArrayList<>(); + Map resultMap = new HashMap<>(); + List fileListAll = new ArrayList<>(); + // 查询配置列数据 + for (Map record1 : dataList) { + + String paramsCollectManifestId = (String) record1.get("id"); + String nioNumber = (String) record1.get("nio_number"); + + if (CollectionUtil.isNotEmpty(paramsConfigEOList)) { + List fileList = new ArrayList<>(); + + // 合并配置数据 + String configData = ""; + List paramsReportConfigDataEOS = paramsReportConfigDataEOService.queryByConfigIdListAndCollectManifestId(configIdList, paramsCollectManifestId); + + String textDatas = paramsReportConfigDataEOS.stream().filter(e->StringUtils.isNotEmpty(e.getTextData())) + .map(ParamsReportConfigDataEO::getTextData).distinct().collect(Collectors.joining(paramsReportDetailVO.getSeparator())); + + String pullDatas = paramsReportConfigDataEOS.stream().filter(e->StringUtils.isNotEmpty(e.getPullData())) + .map(ParamsReportConfigDataEO::getPullData).distinct().collect(Collectors.joining(paramsReportDetailVO.getSeparator())); + + List fileNameList = new ArrayList<>(); + paramsReportConfigDataEOS.forEach(paramsReportConfigDataEO -> { + if (StringUtils.isNotEmpty(paramsReportConfigDataEO.getFileConnectId())) { + List ossFileList = ossFileService.getFileInfosByConnectId(paramsReportConfigDataEO.getFileConnectId()); + if (CollectionUtil.isNotEmpty(ossFileList)) { + fileNameList.add(ossFileList.get(0).getFileName()); + + fileList.addAll(ossFileList); + } + } + }); + + StringBuilder configDataBuilder = new StringBuilder(); // 重新组合配置数据 + if (StringUtils.isNotEmpty(textDatas)) { + configDataBuilder.append(textDatas).append("&"); + } + if (StringUtils.isNotEmpty(pullDatas)) { + configDataBuilder.append(pullDatas).append("&"); + } + if (CollectionUtil.isNotEmpty(fileNameList)) { + configDataBuilder.append(StringUtils.join(fileNameList, ",")).append("&"); + } + configData = configDataBuilder.toString(); + if (configData.contains("&")) { + configData = configData.substring(0, configData.lastIndexOf("&")); + } + resultMap.put(nioNumber, configData); + + + fileListAll.addAll(fileList); + + } + } + + Map fileMap = new HashMap<>(); + fileMap.put("fileListAll", fileListAll); + + resultList.add(resultMap); + resultList.add(fileMap); + return resultList; + } + /** * 获取导出文件的表头 * diff --git a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/util/Docx4jUtil.java b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/util/Docx4jUtil.java new file mode 100644 index 000000000..e034dc69b --- /dev/null +++ b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/util/Docx4jUtil.java @@ -0,0 +1,481 @@ +package com.jero.modules.cert.report.util; + +import org.docx4j.XmlUtils; +import org.docx4j.dml.wordprocessingDrawing.Inline; +import org.docx4j.openpackaging.exceptions.Docx4JException; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; +import org.docx4j.wml.*; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Docx4jUtil { + public static Builder Builder; + + public static Builder of(String path) throws FileNotFoundException, Docx4JException { + return new Builder(path); + } + + public static class Builder { + private WordprocessingMLPackage template = null; + private Iterator texts = null; + + // 占位符参数map + private Map params = new HashMap<>(); + + private Builder(String path) throws FileNotFoundException, Docx4JException { + if (path != null && !path.isEmpty()) { + this.template = WordprocessingMLPackage.load(new FileInputStream(new File(path))); + this.texts = getAllPlaceholderElementFromObject(template.getMainDocumentPart()).iterator(); + } + } + + /** + * 增加文本占位符参数(一个) + * + * @param key 键 + * @param value 值 + * @return Builder对象 + */ + public Builder addParam(String key, String value) { + Builder builder = this; + if (key != null && !key.isEmpty()) { + /*while (texts.hasNext()) { + Text text = texts.next(); + String temp = text.getValue(); + if (temp.equals("${" + key + "}")) { + text.setValue(value); + texts.remove(); + return builder; + } + }*/ + params.put(key, value); + } + return builder; + } + + /** + * 增加参数(多个) + * + * @param params 多个参数的map + * @return Builder对象 + */ + public Builder addParams(Map params) { + this.params = params; + return this; + } + + /** + * 增加一个表格 + * + * @param tablePlaceholder 寻找表格的占位符 + * @param placeholderRows 模板行所占行数 + * @param list 替换模板占位符的数据 + * @return Builder对象 + * @throws JAXBException JAXBException + * @throws Docx4JException Docx4JException + */ + public Builder addTable(String tablePlaceholder, int placeholderRows, List> list) + throws Docx4JException, JAXBException { + List tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class); + + Tbl tempTable = getTemplateTable(tables, tablePlaceholder); // + if (tempTable != null && list != null && !list.isEmpty()) { + List trs = getAllElementFromObject(tempTable, Tr.class); + int rows = trs.size(); + + if (rows > placeholderRows) { + List tempTrs = new ArrayList<>(); + for (int i = rows - placeholderRows; i < rows; i++) { + tempTrs.add((Tr) trs.get(i)); + } + + for (Map trData : list) { + for (Tr tempTr : tempTrs) { + addRowToTable(tempTable, tempTr, trData); + } + } + + for (Tr tempTr : tempTrs) { + tempTable.getContent().remove(tempTr); + } + } + } + return this; + + } + + private void loadImg(Tbl tempTable, byte[] decodeBuffer, int maxWidth) { + Inline inline = createInlineImage(template, decodeBuffer, maxWidth); + P paragraph = addInlineImageToParagraph(inline); + List rows = getAllElementFromObject(tempTable, Tr.class); + Tr tr = (Tr) rows.get(0); + List cells = getAllElementFromObject(tr, Tc.class); + Tc tc = (Tc) cells.get(0); + tc.getContent().clear(); + tc.getContent().add(paragraph); + } + + /** + * 通过占位符确定加载图片的位置,图片的位置为表格 + * + * @param placeholder 占位符 + * @param decodeBuffer 图片的字节流 + * @return 当前对象 + * @throws Docx4JException Docx4JException + * @throws JAXBException JAXBException + */ + public Builder addImg(String placeholder, byte[] decodeBuffer) throws Docx4JException, JAXBException { + addImg(placeholder, decodeBuffer, 0); + return this; + } + + /** + * 通过占位符确定加载图片的位置,图片的位置为表格 + * + * @param placeholder 占位符 + * @param decodeBuffer 图片的字节流 + * @param maxWidth 图片的最多宽度,不传默认写入图片原始宽度 + * @return 当前对象 + * @throws Docx4JException Docx4JException + * @throws JAXBException JAXBException + */ + public Builder addImg(String placeholder, byte[] decodeBuffer, int maxWidth) throws Docx4JException, JAXBException { + List tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class); + Tbl tempTable = getTemplateTable(tables, placeholder); + loadImg(tempTable, decodeBuffer, maxWidth); + return this; + } + + /** + * 通过int的位置数组确定加载图片的位置,图片的位置为表格(以主界面为基准) + * + * @param wz int型数组,长度必须为3 ,第一个值为第几个表格,第二个值为第几行,第三个参数为第几个单元格 + * @param decodeBuffer 图片的字节流 + * @param maxWidth 图片的最多宽度,不传默认写入图片原始宽度 + * @return 当前对象 + */ + public Builder addImg(int[] wz, byte[] decodeBuffer, int maxWidth) { + Tc tc = getTcByWz(wz); + Tbl tempTable = (Tbl) getAllElementFromObject(tc, Tbl.class).get(0); + loadImg(tempTable, decodeBuffer, maxWidth); + return this; + } + + /** + * 通过int的位置数组确定加载图片的位置,图片的位置为表格(以主界面为基准) + * + * @param wz int型数组,长度必须为3 ,第一个值为第几个表格,第二个值为第几行,第三个参数为第几个单元格 + * @param decodeBuffer 图片的字节流 + * @return 当前对象 + */ + public Builder addImg(int[] wz, byte[] decodeBuffer) { + addImg(wz, decodeBuffer, 0); + return this; + } + + /** + * 添加段落 + * + * @param list 数据集合 + * @param wz 模板段落所在的位置,长度为三(第几个表格,第几行,第几个单元格) + * @return Builder对象 + */ + public Builder addParagrash(List> list, int[] wz) { + Tc tc = getTcByWz(wz); + List paraList = getAllElementFromObject(tc, P.class); + tc.getContent().clear(); + for (Map item : list) { + paraList.forEach((tempPara) -> { + P workingPara = (P) XmlUtils.deepCopy(tempPara); + repaleTexts(workingPara, item); + tc.getContent().add(workingPara); + }); + } + return this; + } + + /** + * 移除含有占位符的Tr + * @param placeholder 占位符 + * @return Builder对象 + */ + public Builder removeTrByPlaceholder(String placeholder) { + //这种方式获取是正常的,但是get()方法操作的时候不能正常替换文本了。 + //List trs = template.getMainDocumentPart().getJAXBNodesViaXPath("//w:tr", true); + List trs = getAllElementFromObject(template.getMainDocumentPart(), Tr.class); + Tr tr = (Tr) getTemplateObj(trs,placeholder,false); + if(tr != null){ + Tbl tbl = (Tbl) tr.getParent(); + tbl.getContent().remove(tr); + } + return this; + } + + /** + * 移除含有占位符的Tr + * @param placeholders 占位符的集合 + * @return Builder对象 + */ + public Builder removeTrByPlaceholder(List placeholders) { + /* List trs = template.getMainDocumentPart().getJAXBNodesViaXPath("//w:tr", true);*/ + List trs = getAllElementFromObject(template.getMainDocumentPart(), Tr.class); + List list = getTemplateObjs(trs,placeholders); + for (Object o:list) { + Tr tr = (Tr) o; + if(tr != null){ + Tbl tbl = (Tbl) tr.getParent(); + tbl.getContent().remove(tr); + } + } + return this; + } + + /** + * 获取文件字节流 + * + * @return 文件字节流 + * @throws Docx4JException docx异常 + */ + public byte[] get() throws Docx4JException { + if (!params.isEmpty()) { + while (texts.hasNext()) { + Text text = texts.next(); + String temp = text.getValue(); + for (Map.Entry param : params.entrySet()) { + if (temp.equals("${" + param.getKey() + "}")) { + text.setValue(param.getValue()); + } + } + } + } + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + template.save(outputStream); + return outputStream.toByteArray(); + } + + /** + * 获取指定单元格 + * + * @param temp 模板段落所在的位置,长度为三(第几个表格,第几行,第几个单元格) + * @return tc + */ + private Tc getTcByWz(int[] temp) { + List tables = getAllElementFromObject(template.getMainDocumentPart(), Tbl.class); + Tbl wzTable = (Tbl) tables.get(temp[0]); + Tr tr = (Tr) getAllElementFromObject(wzTable, Tr.class).get(temp[1]); + return (Tc) getAllElementFromObject(tr, Tc.class).get(temp[2]); + } + + } + + /** + * 创建包含图片的一个内联对象 + * + * @param wordMLPackage WordprocessingMLPackage + * @param bytes 图片字节流 + * @param maxWidth 最大宽度 + * @return 图片的内联对象 + */ + private static Inline createInlineImage(WordprocessingMLPackage wordMLPackage, byte[] bytes, int maxWidth) { + Inline inline = null; + try { + BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes); + int docPrId = 1; + int cNvPrId = 2; + if (maxWidth > 0) { + inline = imagePart.createImageInline("Filename hint", "Alternative text", docPrId, cNvPrId, false, maxWidth); + } else { + inline = imagePart.createImageInline("Filename hint", "Alternative text", docPrId, cNvPrId, false); + } + } catch (Exception e) { + e.printStackTrace(); + } + return inline; + } + + /** + * 创建一个对象工厂并用它创建一个段落和一个可运行块R. 然后将可运行块添加到段落中. 接下来创建一个图画并将其添加到可运行块R中. 最后我们将内联 + * 对象添加到图画中并返回段落对象. + * + * @param inline 包含图片的内联对象. + * @return 包含图片的段落 + */ + private static P addInlineImageToParagraph(Inline inline) { + // 添加内联对象到一个段落中 + ObjectFactory factory = new ObjectFactory(); + P paragraph = factory.createP(); + R run = factory.createR(); + paragraph.getContent().add(run); + Drawing drawing = factory.createDrawing(); + run.getContent().add(drawing); + drawing.getAnchorOrInline().add(inline); + return paragraph; + } + + // 发现docx文档包含占位符的文本节点 + private static List getAllPlaceholderElementFromObject(Object obj) { + List result = new ArrayList<>(); + Class toSearch = Text.class; + Text textPlaceholder; + if (obj instanceof JAXBElement) { + obj = ((JAXBElement) obj).getValue(); + } + if (obj.getClass().equals(toSearch)) { + textPlaceholder = (Text) obj; + if (isPlaceholder(textPlaceholder.getValue())) { + result.add((Text) obj); + } + } else if (obj instanceof ContentAccessor) { + List children = ((ContentAccessor) obj).getContent(); + for (Object child : children) { + result.addAll(getAllPlaceholderElementFromObject(child)); + } + } + return result; + } + + // 发现docx文档中的节点 + private static List getAllElementFromObject(Object obj, Class toSearch) { + List result = new ArrayList<>(); + if (obj instanceof JAXBElement) { + obj = ((JAXBElement) obj).getValue(); + } + if (obj.getClass().equals(toSearch)) { + result.add(obj); + } else if (obj instanceof ContentAccessor) { + List children = ((ContentAccessor) obj).getContent(); + for (Object child : children) { + result.addAll(getAllElementFromObject(child, toSearch)); + } + } + return result; + } + + // 这个方法只是查看表格是否含有我们的占位符,如果有则返回表格 + private static Tbl getTemplateTable(List tables, String templateKey) { + return (Tbl) getTemplateObj(tables,templateKey,false); + } + + /** + * 这个方法只是查看dom是否含有我们的占位符,如果有则返回dom + * + * @param objects 需要查找的dom元素 + * @param placeholder 占位符 + * @param f 是否全部查找,为ture时全部查找,返回的是list,为false时一找到元素就返回,只是单个元素 + * @return 找到的元素 + */ + private static Object getTemplateObj(List objects, String placeholder, boolean f) { + List objectList = new ArrayList<>(); + for (Object o : objects) { + List textElements = getAllElementFromObject(o, Text.class); + for (Object text : textElements) { + Text textElement = (Text) text; + if (textElement.getValue() != null && textElement.getValue().equals("${" + placeholder + "}")) { + if (!f) { + return o; + } else { + objectList.add(o); + } + } + } + } + return objectList.isEmpty()?null:objectList; + } + + /** + * 这个方法只是查看dom是否含有我们的占位符,如果有则返回dom + * @param objects 需要查找的dom元素的集合 + * @param placeholders 占位符集合 + * @return 找到的元素的集合 + */ + private static List getTemplateObjs(List objects, List placeholders) { + List objectList = new ArrayList<>(); + for (Object o : objects) { + List textElements = getAllElementFromObject(o, Text.class); + for (Object text : textElements) { + Text textElement = (Text) text; + if (textElement.getValue() != null && placeholders.contains(getPlaceholderStr(textElement.getValue()))) { + objectList.add(o); + } + } + } + return objectList; + } + + /** + * 复制模板行 + * + * @param reviewtable 表格 + * @param templateRow 模板行 + * @param replacements 填充模板行的数据 + */ + private static void addRowToTable(Tbl reviewtable, Tr templateRow, Map replacements) { + Tr workingRow = XmlUtils.deepCopy(templateRow); + repaleTexts(workingRow, replacements); + reviewtable.getContent().add(workingRow); + } + + /** + * 把工作对象中的全部占位符都替换掉 + * + * @param working 工作对象 + * @param replacements map数据对象 + */ + private static void repaleTexts(Object working, Map replacements) { + List textElements = getAllElementFromObject(working, Text.class); + for (Object object : textElements) { + Text text = (Text) object; + String keyStr = getPlaceholderStr(text.getValue()); + if (keyStr != null && !keyStr.isEmpty()) { + String replacementValue = replacements.get(keyStr); + if (replacementValue != null) { + text.setValue(replacementValue); + } else { + text.setValue("--"); + } + } + } + } + + /** + * 判断字符串是否有${}占位符 + * + * @param str 需要判断的字符串 + * @return 是否字符串是否有${}占位符 + */ + private static boolean isPlaceholder(String str) { + if (str != null && !str.isEmpty()) { + Pattern pattern = Pattern.compile("([$]\\{\\w+\\})"); + Matcher m = pattern.matcher(str); + return m.find(); + } + return false; + } + + /** + * 得到占位符${}中的文本 + * + * @param str 需要判断的字符串 + * @return 占位符${}中的文本 + */ + private static String getPlaceholderStr(String str) { + if (str != null && !str.isEmpty()) { + Pattern p = Pattern.compile("\\$\\{(.*?)\\}"); + Matcher m = p.matcher(str); + if (m.find()) { + return m.group(1);//m.group(0)包括这两个字符 + } + } + return null; + } +} diff --git a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/vo/ParamsReportDetailVO.java b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/vo/ParamsReportDetailVO.java index 84ec1e32b..1ab8e7c79 100644 --- a/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/vo/ParamsReportDetailVO.java +++ b/jero-boot/jero-boot-module-certification/src/main/java/com/jero/modules/cert/report/vo/ParamsReportDetailVO.java @@ -1,13 +1,7 @@ package com.jero.modules.cert.report.vo; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import org.jeecgframework.poi.excel.annotation.Excel; -import org.springframework.format.annotation.DateTimeFormat; @Data public class ParamsReportDetailVO { @@ -43,12 +37,19 @@ public class ParamsReportDetailVO { @ApiModelProperty(value = "对应参数模板发布版本") private Integer paramsTemplatePublishVersion; + // 导出通用 + private String cut; + private String exportName; private String ids; // 勾选导出 private String configIds; // 导出的配置列 + + // 常规导出专用 private String combineFlag; // 合并标识 1-不合并,2-合并 private String separator; // 分隔符 - private String cut; - private String exportName; + // 自定义导出专用 + private String exportTemplateId; //导出模板id + + }