合并两个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;
}
}
});
}
}
合并两个word文档,保持样式不变的更多相关文章
- C# 合并及拆分Word文档
本文简要分析一下如何如何使用C#简单实现合并和拆分word文档.平时我们在处理多个word文档时,可能会想要将两个文档合并为一个,或者是将某个文档的一部分添加到另一个文档中,有的时候也会想要将文档拆分 ...
- C#/VB.NET 比较两个Word文档差异
本文以C#和VB.NET代码为例,来介绍如何对比两个Word文档差异.程序中使用最新版的Spire.Doc for .NET 版本8.8.2.编辑代码前,先在VS程序中添加引用Spire.Doc.dl ...
- C# 实现将多个word文档合并成一个word文档的功能
前段时间项目上遇到这么一个需求,需要将多个OCR识别的word文档合并成一个,于是就在网上找了找,自己修改了一下.在这里跟大家分享一下,希望有用的到的. 要做多word文档合并,首先要导入Micros ...
- JAVA合并多个word文档根据文章标题生成目录
此产品版本是免费版的,我也是在用免费,除了只能单次识别25张一下的word和生成pdf有限制,其他的功能都和正式版差不多. 如果你几十个文档,每个文档几页,输出出来超过25页,那没关系,依然可以使用. ...
- Java 比较两个Word文档差异
本文介绍使用Spire.Doc for Java的比较功能来比较两个相似Word文档的差异.需要使用的版本为3.8.8或者后续发布的新版本.可下载jar包,解压将lib文件夹下的Spire.doc.j ...
- C# 之 比较两个word文档的内容
利用 Microsoft.Office.Interop.Word 组件进行比较.引入命名空间:using Word2013 = Microsoft.Office.Interop.Word; 代码如下: ...
- 用WPS查看两篇word文档异同之处
写的合同,后期又有修改,电脑里同样名字的合同有好几个版本,不知道有什么不同,怎么办? 打开wps-->[审阅]-->[比较],剩下的按照提示很容易,略...
- C#使用NPOI对Word文档进行导出操作的dll最新版2.5.1
Npoi导出非模板 最近使用NPOI做了个导出Word文档的功能,因为之前都是导出Excel很方便(不用模板),所以导出Word也选用了Npoi(也没有用模板,
- POI生成word文档完整案例及讲解
一,网上的API讲解 其实POI的生成Word文档的规则就是先把获取到的数据转成xml格式的数据,然后通过xpath解析表单式的应用取值,判断等等,然后在把取到的值放到word文档中,最后在输出来. ...
随机推荐
- 第3节 sqoop:3、sqoop的入门测试使用
3.5. Sqoop的数据导入 “导入工具”导入单个表从RDBMS到HDFS.表中的每一行被视为HDFS的记录.所有记录都存储为文本文件的文本数据(或者Avro.sequence文件等二进制数据) 列 ...
- List<Object> 查询解析优化
2018年3月16日 大型仪器设备分类查出后,需要展示个分类下总共有多少台设备.因为分类总共分三层,加起来数据700+.以后该系统上线设备可能达到2000+,这样统计每个分类下的设备可能会拖垮服务器. ...
- Excel中列宽、行高与像素的换算公式
DPI Scale ColumnWidth RowHeight 72dpi 75% cw=(pix-5)/6 ...
- JS: 复选框——ALL与A、B、C(选中ALL同时选中各子项)
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title> ...
- SpringBoot-属性配置yaml自定义属性和值
SpringBoot-属性配置yaml自定义属性和值 SpringBoot-属性配置yaml自定义属性和值 在SpringBoot中yml/yaml文件可以自定义一些属性,以供注入给自定义bean对象 ...
- 完整版excel上传导入读写批量数据并将反馈结果写入远程exel中
思路:excel的读写借助于poi框架,在写入远程的时候,是不能直接写入的,本博主将传入的文件再次拉下来写到项目临时文件中,然后,在临时文件中写入,然后,以同样的名称路径覆盖掉远程的就可以了,稍微有点 ...
- Python 操作 sqlite
代码示例 #导入sqlite3库 import sqlite3 #连接数据库 conn = sqlite3.connect("customers.db") #创建表,主键id自增 ...
- /和//的区别(python)
/ 除 得到的是浮点数,结果是大数的时候会使用科学计数法 但是 / 会在遇到大数时候运算不准确 因为将两个int相除会产生一个浮点数,并且除法的确切结果不能精确地表示为float. 精确结果必须四舍 ...
- [Updating]点分治学习笔记
Upd \(2020/2/15\),又补了一题 LuoguP2664 树上游戏 \(2020/2/14\),补了一道例题 LuoguP3085 [USACO13OPEN]阴和阳Yin and Yang ...
- Bulma CSS - 开始
Bulma CSS框架教程 Bulma CSS – 简介 Bulma CSS – 开始 Bulma CSS – CSS类 Bulma CSS – 模块化 Bulma CSS – 响应式 有数种方法可以 ...