java中使用poi实现合并word文档,兼容图片的合并并分页

最近需要做一个java合并wrod的实现方法,网上查了看看发现有的方法word里的图片没办法正确的合并到目标文件。后来又查了下,综合了一下自己写了个测试方法,顺手记了一下。

1package com.fosung.pb.develop.report.service; 2 3import org.apache.poi.openxml4j.opc.OPCPackage; 4import org.apache.poi.xwpf.usermodel.Document; 5import org.apache.poi.xwpf.usermodel.XWPFDocument; 6import org.apache.poi.xwpf.usermodel.XWPFPictureData; 7import org.apache.xmlbeans.XmlOptions; 8import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody; 9 10import java.io.File; 11import java.io.FileInputStream; 12import java.io.FileOutputStream; 13import java.io.OutputStream; 14import java.util.ArrayList; 15import java.util.HashMap; 16import java.util.List; 17import java.util.Map; 18 19public class test { 20 public static void main (String[] args) throws Exception { 21 22 File newFile = new File("f:\\张三_发展党员纪实材料.docx"); 23 List<File> srcfile = new ArrayList<>(); 24 File file1 = new File("F:\\report\\step3\\substep7.docx"); 25 File file2 = new File("F:\\report\\step3\\substep9.docx"); 26 File file3 = new File("F:\\report\\step3\\substep9-4.docx"); 27 File file4 = new File("F:\\report\\step2\\substep3.docx"); 28 srcfile.add(file2); 29 srcfile.add(file1); 30 srcfile.add(file3); 31 srcfile.add(file4); 32 try { 33 OutputStream dest = new FileOutputStream(newFile); 34 ArrayList<XWPFDocument> documentList = new ArrayList<>(); 35 XWPFDocument doc = null; 36 for (int i = 0; i < srcfile.size(); i++) { 37 FileInputStream in = new FileInputStream(srcfile.get(i).getPath()); 38 OPCPackage open = OPCPackage.open(in); 39 XWPFDocument document = new XWPFDocument(open); 40 documentList.add(document); 41 } 42 for (int i = 0; i < documentList.size(); i++) { 43 doc = documentList.get(0); 44 if(i != 0){ 45 documentList.get(i).createParagraph().setPageBreak(true); 46 appendBody(doc,documentList.get(i)); 47 } 48 } 49 doc.createParagraph().setPageBreak(true); 50 doc.write(dest); 51 } catch (Exception e) { 52 e.printStackTrace(); 53 } 54 } 55 56 public static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception { 57 CTBody src1Body = src.getDocument().getBody(); 58 CTBody src2Body = append.getDocument().getBody(); 59 60 List<XWPFPictureData> allPictures = append.getAllPictures(); 61 // 记录图片合并前及合并后的ID 62 Map<String,String> map = new HashMap(); 63 for (XWPFPictureData picture : allPictures) { 64 String before = append.getRelationId(picture); 65 //将原文档中的图片加入到目标文档中 66 String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG); 67 map.put(before, after); 68 } 69 70 appendBody(src1Body, src2Body,map); 71 72 } 73 74 private static void appendBody(CTBody src, CTBody append,Map<String,String> map) throws Exception { 75 XmlOptions optionsOuter = new XmlOptions(); 76 optionsOuter.setSaveOuter(); 77 String appendString = append.xmlText(optionsOuter); 78 79 String srcString = src.xmlText(); 80 String prefix = srcString.substring(0,srcString.indexOf(">")+1); 81 String mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<")); 82 String sufix = srcString.substring( srcString.lastIndexOf("<") ); 83 String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<")); 84 85 if (map != null && !map.isEmpty()) { 86 //对xml字符串中图片ID进行替换 87 for (Map.Entry<String, String> set : map.entrySet()) { 88 addPart = addPart.replace(set.getKey(), set.getValue()); 89 } 90 } 91 //将两个文档的xml内容进行拼接 92 CTBody makeBody = CTBody.Factory.parse(prefix+mainPart+addPart+sufix); 93 94 src.set(makeBody); 95 } 96}

刚开始合并后遇到了一个问题,就是合并完word后,所有表格都紧紧挨在了一起,没有分页。后来加上了分页符

documentList.get(i).createParagraph().setPageBreak(true);实现了分页效果。
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )