当前位置:   article > 正文

poi实现多个word文档合并,加超简单分页教程_poi合并word

poi合并word

1.pom包

  1. <dependency>
  2. <groupId>com.deepoove</groupId>
  3. <artifactId>poi-tl</artifactId>
  4. <version>1.8.1</version>
  5. </dependency>

2.合并word工具类

  1. package cn.com.fesco.hpe.config;
  2. import org.apache.poi.openxml4j.opc.OPCPackage;
  3. import org.apache.poi.xwpf.usermodel.BreakType;
  4. import org.apache.poi.xwpf.usermodel.Document;
  5. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  6. import org.apache.poi.xwpf.usermodel.XWPFPictureData;
  7. import org.apache.xmlbeans.XmlOptions;
  8. import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
  9. import java.io.File;
  10. import java.io.FileInputStream;
  11. import java.io.FileOutputStream;
  12. import java.io.OutputStream;
  13. import java.util.ArrayList;
  14. import java.util.HashMap;
  15. import java.util.List;
  16. import java.util.Map;
  17. import java.util.regex.Matcher;
  18. import java.util.regex.Pattern;
  19. /**
  20. * 参数1:需要合并的word的文件对象list
  21. * 参数2:合并之后word存储的全路径file对象
  22. */
  23. public class MergeDocUtils {
  24. public static void mergeDoc(List<File> fileList, File newFile) throws Exception {
  25. OutputStream dest = new FileOutputStream(newFile);
  26. ArrayList<XWPFDocument> documentList = new ArrayList<XWPFDocument>();
  27. XWPFDocument doc = null;
  28. for (int i = 0; i < fileList.size(); i++) {
  29. FileInputStream in = new FileInputStream(fileList.get(i).getPath());
  30. OPCPackage open = OPCPackage.open(in);
  31. XWPFDocument document = new XWPFDocument(open);
  32. documentList.add(document);
  33. }
  34. for (int i = 0; i < documentList.size(); i++) {
  35. doc = documentList.get(0);
  36. if (i != 0) {
  37. //documentList.get(i).createParagraph().setPageBreak(true);//实现了分页效果。//但是会出现在首行为空的情况
  38. documentList.get(i).createParagraph().createRun().addBreak(BreakType.PAGE);//现了分页效果。使用这种方式不会出现留白的情况
  39. appendBody(doc, documentList.get(i));
  40. }
  41. }
  42. doc.write(dest);//输出合并之后的文件
  43. }
  44. public static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
  45. CTBody src1Body = src.getDocument().getBody();
  46. CTBody src2Body = append.getDocument().getBody();
  47. List<XWPFPictureData> allPictures = append.getAllPictures();
  48. // 记录图片合并前及合并后的ID
  49. Map<String, String> map = new HashMap();
  50. for (XWPFPictureData picture : allPictures) {
  51. String before = append.getRelationId(picture);
  52. //将原文档中的图片加入到目标文档中
  53. String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG);
  54. map.put(before, after);
  55. }
  56. appendBody(src1Body, src2Body, map);
  57. }
  58. private static void appendBody(CTBody src, CTBody append, Map<String, String> map) throws Exception {
  59. XmlOptions optionsOuter = new XmlOptions();
  60. optionsOuter.setSaveOuter();
  61. String appendString = append.xmlText(optionsOuter);
  62. //去掉追加word内容中的 w:sectPr 标签,确保合成的word中只有一个 w:sectPr 标签对
  63. //避免合成的word文档打开之后会提示有些内容读不出来,导致文件损坏
  64. String rgex = "<[\\s]*?w:sectPr[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?w:sectPr[\\s]*?>";
  65. appendString = appendString.replaceAll(rgex, "");
  66. String srcString = src.xmlText();
  67. String regex = regex(srcString, "w:sectPr");
  68. System.out.println(regex);
  69. String prefix = srcString.substring(0, srcString.indexOf(">") + 1);
  70. String mainPart = srcString.substring(srcString.indexOf(">") + 1, srcString.lastIndexOf("<"));
  71. String sufix = srcString.substring(srcString.lastIndexOf("<"));
  72. String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
  73. if (map != null && !map.isEmpty()) {
  74. //对xml字符串中图片ID进行替换
  75. for (Map.Entry<String, String> set : map.entrySet()) {
  76. addPart = addPart.replace(set.getKey(), set.getValue());
  77. }
  78. }
  79. //将两个文档的xml内容进行拼接
  80. CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart + sufix);
  81. src.set(makeBody);
  82. }
  83. /**
  84. * 获取指定标签中的内容
  85. *
  86. * @param xml
  87. * @param label
  88. * @return
  89. */
  90. public static String regex(String xml, String label) {
  91. String context = "";
  92. // 正则表达式
  93. String rgex = "<" + label + "[^>]*>((?:(?!<\\/" + label + ">)[\\s\\S])*)<\\/" + label + ">";
  94. Pattern pattern = Pattern.compile(rgex);// 匹配的模式
  95. Matcher m = pattern.matcher(xml);
  96. // 匹配的有多个
  97. List<String> list = new ArrayList<String>();
  98. while (m.find()) {
  99. int i = 1;
  100. list.add(m.group(i));
  101. i++;
  102. }
  103. if (list.size() > 0) {
  104. // 输出内容自己定义
  105. context = String.valueOf(list.size());
  106. }
  107. return context;
  108. }
  109. }

3.代码实例

  1. //new一个list 模拟要合并的word对象集合
  2. List<File>docFileList = new ArrayList<>();
  3. docFileList.add(new File("D:/pdfData/2022-06-23-2c3d300450884b19bb58585d2c4ae518.docx"));
  4. docFileList.add(new File("D:/pdfData/2022-06-23-4a899305225e4fd8abc7ae154841124c.docx"));
  5. //合并之后doc存储路径 此处读的配置文件的存储路径 D:/pdfData/
  6. String docPath = fileUploadConfig.getDocPath();
  7. //当前日期+UUID作为文件名防止重复
  8. String fileName = LocalDate.now() + "-" + UUID.randomUUID().toString().replaceAll("-", "");
  9. //合并之后doc存储路径
  10. String mergeDocUrl = docPath+fileName+".docx";
  11. //转成file对象
  12. File mergeDocFile = new File(mergeDocUrl);
  13. //合并doc
  14. MergeDocUtils.mergeDoc(docFileList,mergeDocFile);
  15. System.out.println("合并word成功");

4.分页问题,我直接读的word模板,填充的数据,下边动态生成的表格

word填充模板,动态生成表格可以看这条poi填充word,动态生成表格+LibreOffice转成pdf_ytqucheng的博客-CSDN博客_poi 动态生成word表格

直接在word模板上需要分页的地方添加分页标识符,

我这里直接在最后一行加的分页标识

下面上图片

 5.效果图

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号