一、需求说明

例如将封面插入到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;
}
}
});
}
}

合并两个word文档,保持样式不变的更多相关文章

  1. C# 合并及拆分Word文档

    本文简要分析一下如何如何使用C#简单实现合并和拆分word文档.平时我们在处理多个word文档时,可能会想要将两个文档合并为一个,或者是将某个文档的一部分添加到另一个文档中,有的时候也会想要将文档拆分 ...

  2. C#/VB.NET 比较两个Word文档差异

    本文以C#和VB.NET代码为例,来介绍如何对比两个Word文档差异.程序中使用最新版的Spire.Doc for .NET 版本8.8.2.编辑代码前,先在VS程序中添加引用Spire.Doc.dl ...

  3. C# 实现将多个word文档合并成一个word文档的功能

    前段时间项目上遇到这么一个需求,需要将多个OCR识别的word文档合并成一个,于是就在网上找了找,自己修改了一下.在这里跟大家分享一下,希望有用的到的. 要做多word文档合并,首先要导入Micros ...

  4. JAVA合并多个word文档根据文章标题生成目录

    此产品版本是免费版的,我也是在用免费,除了只能单次识别25张一下的word和生成pdf有限制,其他的功能都和正式版差不多. 如果你几十个文档,每个文档几页,输出出来超过25页,那没关系,依然可以使用. ...

  5. Java 比较两个Word文档差异

    本文介绍使用Spire.Doc for Java的比较功能来比较两个相似Word文档的差异.需要使用的版本为3.8.8或者后续发布的新版本.可下载jar包,解压将lib文件夹下的Spire.doc.j ...

  6. C# 之 比较两个word文档的内容

    利用 Microsoft.Office.Interop.Word 组件进行比较.引入命名空间:using Word2013 = Microsoft.Office.Interop.Word; 代码如下: ...

  7. 用WPS查看两篇word文档异同之处

    写的合同,后期又有修改,电脑里同样名字的合同有好几个版本,不知道有什么不同,怎么办? 打开wps-->[审阅]-->[比较],剩下的按照提示很容易,略...

  8. C#使用NPOI对Word文档进行导出操作的dll最新版2.5.1

    Npoi导出非模板 最近使用NPOI做了个导出Word文档的功能,因为之前都是导出Excel很方便(不用模板),所以导出Word也选用了Npoi(也没有用模板,

  9. POI生成word文档完整案例及讲解

    一,网上的API讲解 其实POI的生成Word文档的规则就是先把获取到的数据转成xml格式的数据,然后通过xpath解析表单式的应用取值,判断等等,然后在把取到的值放到word文档中,最后在输出来. ...

随机推荐

  1. centos下离线安装zip和unzip

    首先如果你的centos可以联网,那可以不用看了,直接yum install -y zip unzip就行,非常的痛快! 如果不能联网,像我一样,只能用vpn连上去,做了点限制.那就非常烦了,yum了 ...

  2. 深入理解JVM Note

    第2章 Java内存区域与内存溢出异常 运行时数据区域 在虚拟机有栈.堆和方法区. 线程共享的:堆.方法区 不共享的:栈.程序计数器(代码执行的行号) 程序计数器(Program Counter Re ...

  3. LabVIEW面向对象的ActorFramework(1)

    本系列文章主要阐述以下几个问题: (1)什么是面向对象编程? (2)为什么要学习面向编程? (3)LabVIEW面向编程学习为什么有点难? (4)LabVIEW面向对象的编程架构:Actor Fram ...

  4. java核心-多线程(9)- ThreadLocal类

    1.背景     ThreadLocal类我想一般的码农或初级程序员在平时开发中基本上接触不到,但是面试老师会问.往高级点走会遇到这个类.这个类不是为了解决资源的竞争问题,而是为每个线程提供同一个容器 ...

  5. torch.nn.Conv2d()使用

    API 输入:[ batch_size, channels, height_1, width_1 ] Conv2d输入参数:[ channels, output, height_2, width_2 ...

  6. 《ES6标准入门》(阮一峰)--7.数值的扩展

    1.二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === 503 ...

  7. 小程序封装API

    一般我们https请求都是通过wx.request来请求,但是这种请求如果多了,页面会混乱不说,还不好管理,因此我将请求单独拎出去,方便管理,也方便后期维护. // api.js const API_ ...

  8. 百度杀毒停止下载,个人PC杀毒软件真的走到尽头了吗?

    在时代浪潮的席卷下,不适应的服务和产品终将被淘汰.诺基亚如此,杀毒软件亦是如此.就在近日,久久沉寂的杀毒软件市场被投下一颗重磅炸弹--百度杀毒软件官网PC端不再提供下载,但手机端依然提供下载和杀毒服务 ...

  9. .Net 笔记

    1.介绍 .net一般指.Net Framework框架.一种平台,一种技术. C#是一种编程语言,可以开发基于.net平台的应用. .Net Framework是框架是.Net平台不可缺少的一部分, ...

  10. 152-PHP htmlspecialchars函数

    <?php //定义一个HTML代码字符串 $str=<<<HTM <a href=#><b><i>到一个网址的链接<>< ...