基于word模板打印word原创
67次浏览
未经作者许可,禁止转载编辑于2024年07月05日 10:07:54
这个代理里面的内容,大部分是我通过和chatGPT生成的,我验证了一下,基本的功能还是没问题,能写入图片,替换变量这种。
模板在附件中
package digi.alm.plugin.prjimportexport; import digi.alm.orm.util.AlmBusinessDataServiceHelper; import kd.bos.cache.CacheFactory; import kd.bos.cache.TempFileCache; import kd.bos.dataentity.entity.DynamicObject; import kd.bos.dataentity.entity.DynamicObjectCollection; import kd.bos.dataentity.utils.StringUtils; import kd.bos.entity.datamodel.ListSelectedRow; import kd.bos.entity.datamodel.ListSelectedRowCollection; import kd.bos.exception.KDException; import kd.bos.fileservice.FileServiceFactory; import kd.bos.form.control.events.ItemClickEvent; import kd.bos.list.IListView; import kd.bos.list.plugin.AbstractListPlugin; import lombok.SneakyThrows; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; import java.io.*; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class WordExportListPlugin extends AbstractListPlugin { /** * 列表菜单点击事件 * * @param evt */ @SneakyThrows @Override public void itemClick(ItemClickEvent evt) { super.itemClick(evt); IListView listView = (IListView) this.getView(); ListSelectedRowCollection selectedRows = listView.getSelectedRows(); if (StringUtils.equals("digi_baritemap", evt.getItemKey())) { if (selectedRows.size() > 0) { ListSelectedRow selectedRow = selectedRows.get(0); Object contractId = selectedRow.getPrimaryKeyValue(); DynamicObject loadOptional = AlmBusinessDataServiceHelper.loadSingle(contractId, "digi_lwt_test"); // 导出对应的报告 String url = annualReportWord(loadOptional); // 下载 getView().download(url); } } } public static String annualReportWord(DynamicObject dynamicObject) { String path = "D:\\PROJECT\\DIGI\\digi-project\\src\\main\\java\\digi\\alm\\plugin\\prjimportexport\\template.docx"; try (FileInputStream is = new FileInputStream(path); XWPFDocument doc = new XWPFDocument(is)) { //部建一/wond/的 replaceWord(doc, dynamicObject); // 输出相对路径,和绝对路径 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); doc.write(outputStream); //reportword方法里面是组装数据,可以视情况而定 ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); TempFileCache tfc = CacheFactory.getCommonCacheFactory().getTempFileCache(); // 设置临时文件有效时间 return tfc.saveAsUrl("fileName.docx", inputStream, 60 * 60 * 2); } catch (FileNotFoundException e) { e.printStackTrace(); throw new KDException("word棋板文档读取有误,请联系管理员"); } catch (IOException e) { e.printStackTrace(); throw new KDException("word文档导出失败,请联系管理员"); } } public static void replaceWord(XWPFDocument document, DynamicObject dynamicObject) { // 定义正则表达式来匹配${variable}模式 Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}"); // 处理段落中的变量替换 for (XWPFParagraph paragraph : document.getParagraphs()) { replaceInParagraph(paragraph, pattern, dynamicObject); } // 处理表格中的变量替换 for (XWPFTable table : document.getTables()) { table.setCellMargins(0,0,0,1); processTable(table, dynamicObject); } } /** * 在段落中替换变量 * * @param paragraph 要处理的段落 * @param pattern 匹配${variable}的正则表达式 * @param dynamicObject 包含变量及其替换值 */ private static void replaceInParagraph(XWPFParagraph paragraph, Pattern pattern, DynamicObject dynamicObject) { // 连接段落中的所有run文本 StringBuilder paragraphText = new StringBuilder(); for (XWPFRun run : paragraph.getRuns()) { paragraphText.append(run.getText(0)); } // 使用正则表达式找到并替换所有的占位符 Matcher matcher = pattern.matcher(paragraphText.toString()); StringBuffer stringBuffer = new StringBuffer(); while (matcher.find()) { String variable = matcher.group(1); String replacement = dynamicObject.getString(variable); if (replacement != null) { matcher.appendReplacement(stringBuffer, replacement); } } matcher.appendTail(stringBuffer); // 获取替换后的文本 String replacedText = stringBuffer.toString(); int pos = 0; // 按照run的长度分割替换后的文本,并重新设置回段落中,同时保留格式 for (XWPFRun run : paragraph.getRuns()) { String runText = run.getText(0); if (runText != null) { int runLength = runText.length(); if (pos + runLength <= replacedText.length()) { // 设置当前run的文本为替换后的相应部分 run.setText(replacedText.substring(pos, pos + runLength), 0); pos += runLength; } else { // 设置当前run的文本为替换后的剩余部分 run.setText(replacedText.substring(pos), 0); pos = replacedText.length(); } } } // 如果替换后的文本比原始run文本长,创建一个新的run来保存剩余的文本 if (pos < replacedText.length()) { XWPFRun newRun = paragraph.createRun(); newRun.setText(replacedText.substring(pos)); } } /** * 处理表格中的变量替换 * * @param table 要处理的表格 * @param dynamicObject 包含变量及其替换值的JSONObject */ private static void processTable(XWPFTable table, DynamicObject dynamicObject) { DynamicObjectCollection dyEntry = dynamicObject.getDynamicObjectCollection("digi_lwt_entry"); int initialRowCount = table.getNumberOfRows(); for (int i = 0; i < dyEntry.size(); i++) { DynamicObject entry = dyEntry.get(i); XWPFTableRow textRow; XWPFTableRow imageRow; // 动态增加行 if (i >= initialRowCount / 2) { textRow = table.createRow(); imageRow = table.createRow(); } else { textRow = table.getRow(i * 2); imageRow = table.getRow(i * 2 + 1); } // 填充第一列的数据 XWPFTableCell textCell1 = textRow.getCell(0); XWPFTableCell imageCell1 = imageRow.getCell(0); if (textCell1 == null) { textCell1 = textRow.createCell(); } if (imageCell1 == null) { imageCell1 = imageRow.createCell(); } replaceTextInParagraph(textCell1.getParagraphArray(0), entry.getString("digi_textfield")); insertImage(imageCell1.getParagraphArray(0).createRun(), entry.getString("digi_picturefield")); // 填充第二列的数据,确保不重复 if ((i + 1) < dyEntry.size()) { DynamicObject nextEntry = dyEntry.get(i + 1); XWPFTableCell textCell2 = textRow.getCell(1); XWPFTableCell imageCell2 = imageRow.getCell(1); if (textCell2 == null) { textCell2 = textRow.createCell(); } if (imageCell2 == null) { imageCell2 = imageRow.createCell(); } replaceTextInParagraph(textCell2.getParagraphArray(0), nextEntry.getString("digi_textfield")); insertImage(imageCell2.getParagraphArray(0).createRun(), nextEntry.getString("digi_picturefield")); i++; // 跳过已处理的下一行数据 } } } /** * 在段落中替换文本内容 * * @param paragraph 要处理的段落 * @param text 要替换的文本内容 */ private static void replaceTextInParagraph(XWPFParagraph paragraph, String text) { List<XWPFRun> runs = paragraph.getRuns(); if (runs.isEmpty()) { XWPFRun run = paragraph.createRun(); run.setText(text); } else { runs.get(0).setText(text, 0); for (int i = 1; i < runs.size(); i++) { runs.get(i).setText("", 0); // 清空多余的runs } } } /** * 在XWPFRun中插入图片 * * @param run 需要插入图片的XWPFRun * @param imageUrl 图片路径 */ private static void insertImage(XWPFRun run, String imageUrl) { try { run.setText(""); InputStream is = FileServiceFactory.getImageFileService().getInputStream(imageUrl); run.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imageUrl, Units.toEMU(200), Units.toEMU(200)); // 插入图片,调整大小 } catch (Exception e) { e.printStackTrace(); } } }
template.docx(10.63KB)
推荐阅读