doc/img_1.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/img_2.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/img_3.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/print.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/service/PrintRealizeService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/util/DynamicTableRenderPolicy.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/util/FlowOpinionRenderPolicy.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/util/PrintPoiUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/util/PrintTest.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/util/TableEmptyHandler.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/product/print/util/WordReplaceUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
doc/img_1.png
doc/img_2.png
doc/img_3.png
doc/print.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ # æå°æ¨¡æ¿é 置说æ ## æ ç¾ ### {{var}} ç¨äºè¾åºåéï¼å¦ï¼{{name}}ï¼è¾åºåénameçå¼ ####  ### {{@var}} ç¨äºè¾åºæå®æµç¨èç¹æè§ ä¾åï¼ 1.{{@å®¡æ ¸}}ï¼è¾åºæµç¨ä¸èç¹å称为âå®¡æ ¸âçæè§ 2.{{@xxxx-xxxx-xxxx-xxxx}},è¾åºæµç¨ä¸èç¹uuid为âxxxx-xxxx-xxxx-xxxxâçæè§ ### {{@var|var2}} ç¨äºåä¸ä½ç½®è¾åºä¸åæµç¨èç¹æè§ ç¨æ³ä¸{{@var}}ä¸è´ï¼åªæ¯æ¯æå¤ä¸ªèç¹ï¼èç¹ä¹é´ç¨â|âåéï¼ä¼å 级ä»å·¦å°å³ ####  ## <span id="table">å¨æè¡¨æ ¼ï¼å表ï¼</a> {{表å}}ï¼æ ¹æ®â表åâè·åFieldSetEntityä¸çåè¡¨æ°æ®ï¼ç¬å ä¸è¡,渲æå®æåä¼èªå¨å é¤è¯¥è¡ ### å表æ ç¾ {{$~index~}}ï¼ åºå®åæ³ï¼è¾åºå表è¡å· {{$åæ®µå}}ï¼è¾åºåè¡¨ä¸æå®å段çå¼ ###  ## æµç¨æè§ å°æææµç¨æè§è¾åºï¼è¾åºé¡ºåºä¸ºåçæ¶é´ååº æ ç¾é ç½®ä¸[å¨æè¡¨æ ¼ï¼å表ï¼](#table)å¨æè¡¨æ ¼ï¼å表ï¼ä¸è´ æ ç¾ä¸çåé为åºå®å¼:"lx_flow_opinion",宿´æ ç¾ä¸ºï¼{{lx_flow_opinion}} ### è¡¨æ ¼å 容æ ç¾ {{$node_title}} èç¹åç§° {{$opinion}} èç¹æè§ï¼å¦æç¾ååä¼å°ç¾åå¾çä¸å¹¶è¾åº æ´å¤åéåè§ç³»ç»æµç¨è¯¦æ 表ï¼product_sys_flow_detailï¼åä¸çåé ### åä¸ä½ç½®ä¸åèç¹æè§ #### src/main/java/com/product/print/service/PrintRealizeService.java
@@ -10,6 +10,8 @@ import com.deepoove.poi.config.ConfigureBuilder; import com.deepoove.poi.data.TextRenderData; import com.deepoove.poi.data.style.Style; import com.deepoove.poi.render.RenderContext; import com.deepoove.poi.util.RegexUtils; import com.product.common.lang.StringUtils; import com.product.core.cache.DataPoolCacheImpl; import com.product.core.config.Global; @@ -23,16 +25,21 @@ import com.product.print.config.CmnConst; import com.product.print.service.ide.IPrintRealizeService; import com.product.print.util.DynamicTableRenderPolicy; import com.product.print.util.FlowOpinionRenderPolicy; import com.product.print.util.TableEmptyHandler; import com.product.tool.flow.service.FlowDetailService; import com.product.util.BaseUtil; import com.product.util.SystemParamReplace; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -57,7 +64,7 @@ public static void dataConvertCheckedData(FieldSetEntity fse) { TextRenderData selSymbol = new TextRenderData(CmnConst.PRINT_CHECKED_CHAR, new Style(CmnConst.PRINT_FONT, 14)); TextRenderData unselSymbol = new TextRenderData(CmnConst.PRINT_UNCHECKED_CHAR, new Style(CmnConst.PRINT_FONT, 14)); TextRenderData unselSymbol = new TextRenderData(CmnConst.PRINT_UNCHECKED_CHAR, new Style(CmnConst.PRINT_FONT, 18)); //è·å表ååæ®µ Object[] fields = fse.getMeta().getFields(); @@ -186,6 +193,9 @@ for (int i = 0; i < fields.length; i++) { String field = fields[i].toString(); FieldSetEntity metaEntity = fse.getMeta().getFieldMeta(field); if (metaEntity == null) { continue; } String fieldType = metaEntity.getString("field_type"); //夿æ¯å¦æ¥ææµç¨æ è¯ if ("flowsign".equals(fieldType)) { @@ -217,7 +227,7 @@ replaceWord(localTempPathWord, file.getPath(), fse); file.delete(); String replaceParams = SystemParamReplace.replaceParams(printConf.getString(CmnConst.PRINT_FILE_NAME), fse); String replaceParams = SystemParamReplace.replaceParams(Optional.ofNullable(printConf.getString(CmnConst.PRINT_FILE_NAME)).orElse(printConf.getString(CmnConst.PRINT_NAME)), fse); printConf.setValue(CmnConst.PRINT_FILE_NAME, replaceParams); if (isConvertPdf) { try { @@ -261,16 +271,36 @@ //è·ååè¡¨æ°æ® Map<String, DataTableEntity> subDataMap = dataFse.getSubData(); ConfigureBuilder config = Configure.createDefault().builder(); config.addPlugin('@', new FlowOpinionRenderPolicy(flowOpinion)); config.addPlugin('$', new com.deepoove.poi.policy.DynamicTableRenderPolicy() { @Override public void doRender(RenderContext<Object> context) throws Exception { return; } @Override public void render(XWPFTable table, Object data) throws Exception { return; } }); config.buildGrammerRegex("(#)?([\\w\\u4e00-\\u9fa5]+)(\\.?[\\w\\u4e00-\\u9fa5\\|]*)*(#)?"); TableEmptyHandler tableEmptyHandler = new TableEmptyHandler(); if (!CollectionUtil.isEmpty(subDataMap)) { for (Map.Entry<String, DataTableEntity> entry : subDataMap.entrySet()) { cloneValues.put(entry.getKey(), entry.getValue().getData().stream().map(item -> (Map<String, Object>) ((Map) item.getValues())).collect(Collectors.toList())); config.bind(entry.getKey(), new DynamicTableRenderPolicy(entry.getKey())); tableEmptyHandler.addTag(entry.getKey()); } } if(flowOpinion!=null && flowOpinion.size()>0){ cloneValues.put("lx_flow_opinion", flowOpinion); config.bind("lx_flow_opinion", new DynamicTableRenderPolicy("lx_flow_opinion")); if (flowOpinion != null) { if (!CollectionUtil.isEmpty(flowOpinion)) { cloneValues.put("lx_flow_opinion", flowOpinion); config.bind("lx_flow_opinion", new DynamicTableRenderPolicy("lx_flow_opinion")); } tableEmptyHandler.addTag("lx_flow_opinion"); } config.setValidErrorHandler(tableEmptyHandler); try { //æ£æ¥è¾åºæä»¶æ¯å¦åå¨ï¼ä¸åå¨åå建 FileUtil.touch(outPath); src/main/java/com/product/print/util/DynamicTableRenderPolicy.java
@@ -1,8 +1,10 @@ package com.product.print.util; import cn.hutool.core.io.IoUtil; import cn.hutool.core.collection.CollectionUtil; import com.deepoove.poi.exception.RenderException; import com.deepoove.poi.render.RenderContext; import com.deepoove.poi.template.ElementTemplate; import com.deepoove.poi.template.MetaTemplate; import com.deepoove.poi.template.run.RunTemplate; import com.deepoove.poi.util.TableTools; import com.product.common.lang.StringUtils; @@ -11,18 +13,11 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.Map; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,12 +32,14 @@ private final String indexKey = "~index~"; public DynamicTableRenderPolicy(String replaceKey) { public DynamicTableRenderPolicy(String replaceKey) { this.replaceKey = replaceKey; } private XWPFRun run; private List<MetaTemplate> metaTemplateList; @Override public void doRender(RenderContext<Object> context) throws Exception { @@ -55,8 +52,13 @@ } XWPFTableCell cell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody(); XWPFTable table = cell.getTableRow().getTable(); this.metaTemplateList = context.getTemplate().getElementTemplates(); ElementTemplate eleTemplate = context.getEleTemplate(); int index = metaTemplateList.indexOf(eleTemplate); this.metaTemplateList = metaTemplateList.subList(index + 1, metaTemplateList.size()); render(table, context.getData()); } catch (Exception e) { e.printStackTrace(); throw new RenderException("Dynamic render table error:" + e.getMessage(), e); } } @@ -124,133 +126,79 @@ } fieldNames[i] = replaceKey; } //è·åfieldRowæå¨ç䏿 int fieldRowIndex = xwpfTable.getRows().indexOf(fieldRow); for (int i = 0; i < subTableData.size(); i++) { Map<String, Object> map = subTableData.get(i); //å建ä¸è¡å¨fieldRowIndexä¸é¢ XWPFTableRow row = xwpfTable.insertNewTableRow(fieldRowIndex + 1 + i); copyTableRow(row, fieldRow); //设置rowç屿§ä¸fieldRowä¸è´ row.setHeight(fieldRow.getHeight()); //éååæ®µæ¯ä¸ªå段å建ä¸ä¸ªåå æ ¼ for (int j = 0; j < fieldNames.length; j++) { //å½ååå æ ¼ XWPFTableCell cell; //夿rowä¸ç¬¬j个åå æ ¼æ¯å¦åå¨ if (row.getTableCells().size() > j) { cell = row.getCell(j); if (subTableData != null && subTableData.size() > 0) { for (int i = 0; i < subTableData.size(); i++) { Map<String, Object> map = subTableData.get(i); XWPFTableRow row; if (i == 0) { row = fieldRow; } else { cell = row.createCell(); //å建ä¸è¡å¨fieldRowIndexä¸é¢ row = xwpfTable.insertNewTableRow(xwpfTable.getRows().size()); PrintPoiUtil.copyTableRow(row, fieldRow); } //设置åå æ ¼çå¼ä»mapä¸ååº //夿æ¯å¦æ¯åºå·å if (indexKey.equals(fieldNames[j])) { cell.setText(String.valueOf(i + 1)); continue; } Object value = map.get(fieldNames[j]); if (value == null) { value = ""; } String text = cell.getText(); //å é¤åå æ ¼ä¸çæ§å 容 if (!StringUtils.isEmpty(text)) { List<XWPFParagraph> paragraphs = cell.getParagraphs(); if (paragraphs.size() > 1) { cell.removeParagraph(1); } List<XWPFRun> runs = paragraphs.get(0).getRuns(); //æ¸ ç©ºæå for (int k = 0; k < runs.size(); k++) { runs.get(k).setText("", 0); } } cell.setText(value.toString()); if ("lx_flow_opinion".equals(this.replaceKey) && "opinion".equals(fieldNames[j]) && !StringUtils.isEmpty(map.get("sign_attachment_uuid"))) { //æè§æ¡ æå ¥ç¾åå¾çå°åå æ ¼å³ä¸è§ä½ç½® //éååæ®µæ¯ä¸ªå段å建ä¸ä¸ªåå æ ¼ for (int j = 0; j < fieldNames.length; j++) { //å½ååå æ ¼ XWPFTableCell cell = row.getCell(j); //æ¸ ç©ºåå æ ¼å 容 XWPFParagraph xwpfParagraph = cell.addParagraph(); xwpfParagraph.setAlignment(ParagraphAlignment.RIGHT); XWPFRun run = xwpfParagraph.createRun(); String signAttachmentBase64 = map.get("sign_attachment_uuid").toString(); //å°base64转æ¢åèæµ byte[] bytes = Base64.getDecoder().decode(signAttachmentBase64.split(",")[1]); //å°åèæµè½¬æ¢ä¸ºè¾å ¥æµ InputStream inputStream = new ByteArrayInputStream(bytes); try { //æ¢è¡æå ¥å¾ç run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, "sign.png", Units.toEMU(50), Units.toEMU(20)); inputStream.close(); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); int index = cell.getParagraphs().indexOf(xwpfParagraph); PrintPoiUtil.copyParagraph(xwpfParagraph, cell.getParagraphs().get(0)); //å 餿æçrun for (int k = xwpfParagraph.getRuns().size() - 1; k >= 0; k--) { xwpfParagraph.removeRun(k); } } XWPFRun xwpfRun = xwpfParagraph.createRun(); PrintPoiUtil.copyRun(xwpfRun, cell.getParagraphs().get(0).getRuns().get(0)); //å é¤cellä¸ç段è½ä½æé¤æ°å¢çæ®µè½ for (int k = cell.getParagraphs().size() - 1; k >= 0; k--) { if (k < index) { cell.removeParagraph(k); } } //夿æ¯å¦æ¯åºå·å if (indexKey.equals(fieldNames[j])) { cell.setText(String.valueOf(i + 1)); continue; } Object value = map.get(fieldNames[j]); if (value == null) { value = ""; } xwpfRun.setText(value.toString(), 0); if ("lx_flow_opinion".equals(this.replaceKey) && "opinion".equals(fieldNames[j]) && !StringUtils.isEmpty(map.get("sign_attachment_uuid"))) { //æè§æ¡ æå ¥ç¾åå¾çå°åå æ ¼å³ä¸è§ä½ç½® xwpfParagraph = cell.addParagraph(); xwpfParagraph.setAlignment(ParagraphAlignment.RIGHT); XWPFRun run = xwpfParagraph.createRun(); String signAttachmentBase64 = map.get("sign_attachment_uuid").toString(); //å°base64转æ¢åèæµ byte[] bytes = Base64.getDecoder().decode(signAttachmentBase64.split(",")[1]); //å°åèæµè½¬æ¢ä¸ºè¾å ¥æµ InputStream inputStream = new ByteArrayInputStream(bytes); try { //æ¢è¡æå ¥å¾ç run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, "sign.png", Units.toEMU(50), Units.toEMU(20)); inputStream.close(); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } } } else { // å é¤fieldRow int index = xwpfTable.getRows().indexOf(fieldRow); xwpfTable.removeRow(index); } //å é¤èµ·å§è¡ xwpfTable.removeRow(startRowIndex); //å é¤fieldRow xwpfTable.removeRow(fieldRowIndex - 1); // //读å宿¯åå 餿åä¸è¡ // xwpfTable.removeRow(rows.size() - 1); //è·åææçè¡å¤æåå æ ¼æ¯å¦æå¼æ²¡æå°±å é¤è¯¥è¡ // List<XWPFTableRow> tableRows = xwpfTable.getRows(); // List<XWPFTableRow> deleteRows = new ArrayList<>(); // for (int i = 0; i < tableRows.size(); i++) { // XWPFTableRow row = tableRows.get(i); // boolean flag = false; // for (int j = 0; j < row.getTableCells().size(); j++) { // XWPFTableCell cell = row.getTableCells().get(j); // if (StringUtils.isNotEmpty(cell.getText())) { // flag = true; // break; // } // } // if (!flag) { // deleteRows.add(row); // } // } // //éåè¦å é¤çè¡è·åæå¨ç䏿 è¿è¡å é¤ // for (int i = 0; i < deleteRows.size(); i++) { // XWPFTableRow row = deleteRows.get(i); // int index = xwpfTable.getRows().indexOf(row); // xwpfTable.removeRow(index); // } // //éåæ°æ®éåï¼æ¯ä¸ªmap对åºä¸è¡æ°æ® // for (int i = 0; i < subTableData.size(); i++) { // Map<String, Object> map = subTableData.get(i); // //å建ä¸è¡ // XWPFTableRow row = xwpfTable.createRow(); // //éååæ®µæ¯ä¸ªå段å建ä¸ä¸ªåå æ ¼ // for (int j = 0; j < fieldNames.length; j++) { // //å½ååå æ ¼ // XWPFTableCell cell; // //夿rowä¸ç¬¬j个åå æ ¼æ¯å¦åå¨ // if (row.getTableCells().size() > j) { // cell = row.getTableCells().get(j); // } else { // cell = row.createCell(); // } // //设置åå æ ¼çå¼ä»mapä¸ååº // //夿æ¯å¦æ¯åºå·å // if (indexKey.equals(fieldNames[j])) { // cell.setText(String.valueOf(i + 1)); // continue; // } // Object value = map.get(fieldNames[j]); // if (value == null) { // value = ""; // } // //设置åå æ ¼çå¼ // cell.setText(value.toString()); // } // } } /** src/main/java/com/product/print/util/FlowOpinionRenderPolicy.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,112 @@ package com.product.print.util; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.deepoove.poi.data.TextRenderData; import com.deepoove.poi.policy.AbstractRenderPolicy; import com.deepoove.poi.render.RenderContext; import com.deepoove.poi.xwpf.BodyContainer; import com.deepoove.poi.xwpf.BodyContainerFactory; import com.product.common.lang.StringUtils; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Base64; import java.util.Optional; /** * èªå®ä¹è§£æ{{@var}}æ ç¾ * * @Author cheng * @Date 2023/6/27 15:50 * @Desc */ public class FlowOpinionRenderPolicy extends AbstractRenderPolicy<TextRenderData> { /** * æè§å表 */ private JSONArray opinionArray; public FlowOpinionRenderPolicy(JSONArray opinionArray) { this.opinionArray = opinionArray; } @Override public void doRender(RenderContext<TextRenderData> context) throws Exception { XWPFRun run = context.getRun(); //æ ç¾åç§° String tagName = context.getEleTemplate().getTagName(); JSONObject opinion=null; //æ¯æå¤ä¸ªæ ç¾åç§°ï¼ç¨|åé ä¾å¦ï¼{{@var1|var2|var3...}} æç §é¡ºåºæ¥æ¾æè§å表 for (String name : tagName.split("\\|")) { opinion = getOpinion(name); if(opinion!=null){ break; } } if (opinion == null) { //妿æè§åè¡¨ä¸æ²¡ææ¾å°ï¼åç´æ¥æ¿æ¢ä¸ºç©º run.setText("", 0); return; } XWPFParagraph parent = (XWPFParagraph) run.getParent(); XWPFRun newRun = run; //夿æ¯å¦æç¾å if (!StringUtils.isEmpty(opinion.getString("sign_attachment_uuid"))) { XWPFParagraph paragraph = createParagraph(run); //设置ç¾åçæ®µè½å± å³ paragraph.setAlignment(ParagraphAlignment.RIGHT); //æå ¥ä¸ä¸ªæ°çrun newRun = paragraph.createRun(); String signAttachmentBase64 = opinion.getString("sign_attachment_uuid"); String[] split = signAttachmentBase64.split(","); //å°base64转æ¢åèæµ byte[] bytes = Base64.getDecoder().decode(split[split.length - 1]); //å°åèæµè½¬ä¸ºè¾å ¥æµ InputStream byteArrayInputStream = new ByteArrayInputStream(bytes); //æå ¥å¾ç newRun.addPicture(byteArrayInputStream, XWPFDocument.PICTURE_TYPE_PNG, "sign.png", Units.toEMU(50), Units.toEMU(20)); byteArrayInputStream.close(); newRun.setText("", 0); } XWPFParagraph paragraph = createParagraph(newRun); //æ®µè½æ ·å¼ä¸åå§æ®µè½ä¸è´ paragraph.getCTP().setPPr(parent.getCTP().getPPr()); //设置å建æ°çrun XWPFRun textRun = paragraph.createRun(); //å¤å¶åå§run PrintPoiUtil.copyRun(textRun, run); //设置runçå 容 textRun.setText(Optional.ofNullable(opinion.getString("opinion")).orElse("æªå¡«ååçæè§"), 0); //å 餿®µè½parentï¼å¦æåªå é¤runï¼åä¼å¯¼è´æ®µè½ä¸è¿æä¸ä¸ªç©ºçrun parent.getCTP().newCursor().removeXml(); } public XWPFParagraph createParagraph(XWPFRun run) { //è·åbodyå®¹å¨ BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run); //æå ¥ä¸ä¸ªæ°çæ®µè½ XWPFParagraph paragraph = bodyContainer.insertNewParagraph(run); return paragraph; } public JSONObject getOpinion(String tagName) { //å ç¨tagName廿è§åè¡¨ä¸æ¥æ¾node_uuidæ¯å¦åå¨ï¼ä¸åå¨å使ç¨node_title廿¥æ¾ for (int i = 0; i < opinionArray.size(); i++) { JSONObject opinion = opinionArray.getJSONObject(i); if (tagName.equals(opinion.getString("node_uuid"))) { return opinion; } } for (int i = 0; i < opinionArray.size(); i++) { JSONObject opinion = opinionArray.getJSONObject(i); if (tagName.equals(opinion.getString("node_title"))) { return opinion; } } return null; } } src/main/java/com/product/print/util/PrintPoiUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,138 @@ package com.product.print.util; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.xwpf.usermodel.*; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; /** * @Author cheng * @Date 2023/8/5 16:40 * @Desc */ public class PrintPoiUtil { /** * å¤å¶è¡ï¼ä»sourceå°target * * @param target * @param source */ public static void copyTableRow(XWPFTableRow target, XWPFTableRow source) { // å¤å¶æ ·å¼ if (source.getCtRow() != null) { target.getCtRow().setTrPr(source.getCtRow().getTrPr()); } // å¤å¶åå æ ¼ for (int i = 0; i < source.getTableCells().size(); i++) { XWPFTableCell cell1 = target.getCell(i); XWPFTableCell cell2 = source.getCell(i); if (cell1 == null) { cell1 = target.addNewTableCell(); } copyTableCell(cell1, cell2); } } /** * å¤å¶åå æ ¼ï¼ä»sourceå°target * * @param target * @param source */ public static void copyTableCell(XWPFTableCell target, XWPFTableCell source) { // å屿§ if (source.getCTTc() != null) { target.getCTTc().setTcPr(source.getCTTc().getTcPr()); } // å 餿®µè½ for (int pos = 0; pos < target.getParagraphs().size(); pos++) { target.removeParagraph(pos); } // æ·»å æ®µè½ for (XWPFParagraph sp : source.getParagraphs()) { XWPFParagraph targetP = target.addParagraph(); copyParagraph(targetP, sp); } } /** * å¤å¶å¾çå°target * * @param target * @param picture * @throws IOException * @throws InvalidFormatException */ public static void copyPicture(XWPFRun target, XWPFPicture picture) throws IOException, InvalidFormatException { String filename = picture.getPictureData().getFileName(); InputStream pictureData = new ByteArrayInputStream(picture .getPictureData().getData()); int pictureType = picture.getPictureData().getPictureType(); int width = (int) picture.getCTPicture().getSpPr().getXfrm().getExt() .getCx(); int height = (int) picture.getCTPicture().getSpPr().getXfrm().getExt() .getCy(); // target.addBreak(); target.addPicture(pictureData, pictureType, filename, width, height); // target.addBreak(BreakType.PAGE); } /** * å¤å¶æ®µè½ï¼ä»sourceå°target * * @param target * @param source */ public static void copyParagraph(XWPFParagraph target, XWPFParagraph source) { // è®¾ç½®æ®µè½æ ·å¼ target.getCTP().setPPr(source.getCTP().getPPr()); // ç§»é¤ææçrun for (int pos = target.getRuns().size() - 1; pos >= 0; pos--) { target.removeRun(pos); } // copy æ°çrun for (XWPFRun s : source.getRuns()) { XWPFRun targetrun = target.createRun(); copyRun(targetrun, s); } } /** * å¤å¶RUNï¼ä»sourceå°target * * @param target * @param source */ public static void copyRun(XWPFRun target, XWPFRun source) { // 设置run屿§ target.getCTR().setRPr(source.getCTR().getRPr()); // è®¾ç½®ææ¬ target.setText(source.text()); // å¤çå¾ç List<XWPFPicture> pictures = source.getEmbeddedPictures(); for (XWPFPicture picture : pictures) { try { copyPicture(target, picture); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } System.out.println(source.getColor()); System.out.println(target.getColor()); } } src/main/java/com/product/print/util/PrintTest.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,41 @@ package com.product.print.util; import cn.hutool.core.io.FileUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @Author cheng * @Date 2023/8/5 14:18 * @Desc */ public class PrintTest { static String templatePath = "d:\\desktop\\APP_NOTICE_DECIDE.docx"; static String outPath = "d:\\desktop\\APP_NOTICE_DECIDE_out.docx"; public static void main(String[] args) throws IOException { Map<String, Object> values = new HashMap<>(); values.put("name", "许é¹ç¨"); ConfigureBuilder config = Configure.createDefault().builder(); JSONArray array = new JSONArray(); JSONObject object=new JSONObject(); object.put("node_uuid","flow"); object.put("node_title","node_title"); object.put("node_content","node_content"); object.put("opinion","opinion"); object.put("sign_attachment_uuid","sign_attachment_uuid"); array.add(object); config.addPlugin('@', new FlowOpinionRenderPolicy(array)); FileUtil.touch(outPath); XWPFTemplate.compile(templatePath, config.build()).render(values).writeToFile(outPath); } } src/main/java/com/product/print/util/TableEmptyHandler.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,101 @@ package com.product.print.util; import cn.hutool.core.util.ArrayUtil; import com.deepoove.poi.config.Configure; import com.deepoove.poi.render.RenderContext; import com.deepoove.poi.template.run.RunTemplate; import com.product.core.exception.BaseException; import com.product.print.config.CmnCode; import org.apache.poi.xwpf.usermodel.*; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author cheng * @Date 2023/8/7 10:04 * @Desc è¡¨æ ¼æ°æ®ç©ºæ¶ */ public class TableEmptyHandler extends Configure.ClearHandler { private String[] tagName; public TableEmptyHandler() { } public void addTag(String tagName) { if (this.tagName == null) { this.tagName = new String[]{}; } this.tagName = ArrayUtil.append(this.tagName, tagName); } @Override public void handler(RenderContext<?> context) { String tagName = context.getEleTemplate().getTagName(); if (this.tagName == null || ArrayUtil.indexOf(this.tagName, tagName) == -1) { super.handler(context); return; } RunTemplate runTemplate = (RunTemplate) context.getEleTemplate(); XWPFRun run = runTemplate.getRun(); XWPFTableCell cell = (XWPFTableCell) ((XWPFParagraph) run.getParent()).getBody(); XWPFTable xwpfTable = cell.getTableRow().getTable(); doRemove(xwpfTable, tagName); } private void doRemove(XWPFTable xwpfTable, String tagName) { List<XWPFTableRow> rows = xwpfTable.getRows(); //读årowsä¸çå 容 String tableExpression = "{{" + tagName + "}}"; //è·åè¡¨æ ¼èµ·å§è¡åç»æè¡ int startRowIndex = -1; rows: for (int i = 0; i < rows.size(); i++) { XWPFTableRow row = rows.get(i); for (int j = 0; j < row.getTableCells().size(); j++) { XWPFTableCell cell = row.getTableCells().get(j); String text = cell.getText(); if (tableExpression.equals(text)) { startRowIndex = i; break rows; } } } if (startRowIndex == -1) { return; } //å¨è¡¨æ ¼ä¸æ¥æ¾åè¡¨åæ®µä»¥{{$å¼å¤´}}以}}ç»å°¾çå 容 String regex = "\\{\\{\\$[a-zA-Z0-9_]+\\}\\}"; Pattern pattern = Pattern.compile(regex); //åæ®µæå¨è¡ XWPFTableRow fieldRow = null; for (int i = startRowIndex; i < rows.size(); i++) { XWPFTableRow row = rows.get(i); for (int j = 0; j < row.getTableCells().size(); j++) { XWPFTableCell cell = row.getTableCells().get(j); String text = cell.getText(); Matcher matcher = pattern.matcher(text); if (matcher.find()) { fieldRow = row; i = rows.size(); break; } } } //å é¤èµ·å§è¡ xwpfTable.removeRow(startRowIndex); if (fieldRow == null) { return; } //è·ååæ®µæå¨è¡çç´¢å¼ int fieldRowIndex = xwpfTable.getRows().indexOf(fieldRow); //å é¤èµ·å§è¡å°å段æå¨è¡ä¹é´çææè¡ xwpfTable.removeRow(fieldRowIndex); } } src/main/java/com/product/print/util/WordReplaceUtil.java
@@ -22,11 +22,7 @@ values.put("name", "许é¹ç¨"); values.put("n1", 101); values.put("n2", "20-1"); XWPFTemplate template = XWPFTemplate.compile("D:\\Desktop\\APP_NOTICE_DECIDE.docx").render(values); File file = new File("D:\\Desktop\\test.docx"); OutputStream out = new ByteArrayOutputStream(); template.write(out); template.close(); }