合并两个word文档,保持样式不变
一、需求说明
例如将封面插入到word正文上方
二、导入依赖
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.1.1</version> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>3.1.0</version> </dependency>
三、准备工作
准备两个word文档
四、代码
import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.xwpf.usermodel.Document; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFPictureData; import org.apache.xmlbeans.XmlOptions; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody; public class test { public static void main (String[] args) throws Exception { /*String[] str = {"街道(年度)","街道(季度)","街道(月度)","全区(年度)","全区(季度)","全区(月度)"};*/ String[] str = {"街道(年度)"}; for (int k = 0; k < str.length; k++) { String type = str[k]; String path ="E:/1/确认打印报告/"+type+"/"; File fileRoot = new File(path); List<File> subFileList = new ArrayList<File>(); getAllFile(subFileList,fileRoot); for (File file : subFileList) { String name = file.getName(); File newFile = new File("f:/final/"+type+"/"+name); List<File> srcfile = new ArrayList<>(); File file1 = new File("E:/1/确认打印报告/"+type+"/"+name); File file2 = new File("D:/word/封面/生成/"+type+"/"+name); srcfile.add(file1); srcfile.add(file2); try { OutputStream dest = new FileOutputStream(newFile); ArrayList<XWPFDocument> documentList = new ArrayList<>(); XWPFDocument doc = null; for (int i = 0; i < srcfile.size(); i++) { FileInputStream in = new FileInputStream(srcfile.get(i).getPath()); OPCPackage open = OPCPackage.open(in); XWPFDocument document = new XWPFDocument(open); documentList.add(document); in.close(); } for (int i = 0; i < documentList.size(); i++) { doc = documentList.get(0); if(i != 0){ appendBody(doc,documentList.get(i)); } } // doc.createParagraph().setPageBreak(true); doc.write(dest); System.out.println(name); doc.close(); dest.close(); } catch (Exception e) { e.printStackTrace(); } } } } public static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception { CTBody src1Body = src.getDocument().getBody(); CTBody src2Body = append.getDocument().getBody(); List<XWPFPictureData> allPictures = append.getAllPictures(); // 记录图片合并前及合并后的ID Map<String,String> map = new HashMap(); for (XWPFPictureData picture : allPictures) { String before = append.getRelationId(picture); //将原文档中的图片加入到目标文档中 String after = src.addPictureData(picture.getData(), Document.PICTURE_TYPE_PNG); map.put(before, after); } appendBody(src1Body, src2Body,null); } private static void appendBody(CTBody src, CTBody append,Map<String,String> map) throws Exception { XmlOptions optionsOuter = new XmlOptions(); optionsOuter.setSaveOuter(); String appendString = append.xmlText(optionsOuter); String srcString = src.xmlText(); String prefix = srcString.substring(0,srcString.indexOf(">")+1); String mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<")); String sufix = srcString.substring( srcString.lastIndexOf("<") ); String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<")); if (map != null && !map.isEmpty()) { //对xml字符串中图片ID进行替换 for (Map.Entry<String, String> set : map.entrySet()) { addPart = addPart.replace(set.getKey(), set.getValue()); } } //将两个文档的xml内容进行拼接 CTBody makeBody = CTBody.Factory.parse(prefix+addPart+mainPart+sufix); src.set(makeBody); } private static void getAllFile(final List<File> subFileList, File fileRoot) { fileRoot.listFiles(new FileFilter() { @Override public boolean accept(File file) { if (file.isDirectory()) { getAllFile(subFileList, file); return false; }else{ if(file.getName().endsWith(".docx")){ subFileList.add(file); } return false; } } }); } }