最近的项目功能中,有涉及到要将多个doc文件合并成一个文件的功能,网上各种资料都有,现整理一下我自己的处理方法,以供需要之人参考.
首先时pom依赖如下:
<!-- jodconverter -->
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-core</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-spring-boot-starter</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.artofsolving</groupId>
<artifactId>jodconverter</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>pdf2dom</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 合并pdf-->
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>xdocreport</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
jodconverter配置信息如下,在application.yml中添加如下配置:
jodconverter:
local:
enabled: true
office-home: C:\Program Files (x86)\OpenOffice 4
max-tasks-per-process: 10
port-numbers: 8100
openfile:
localPath: D:\upload\openfile\
reviewPath: D:\upload\openfile\review\
处理文件合并的工具类
/**
*
* @param tbPictures 要处理的文件集合
* @param outPath 合并后的文件保存路径
* @return
*/
public static boolean mergeDocFiles(List<TbPicture> tbPictures, String outPath) {
if (StringUtil.isNull(tbPictures)) {
throw new MyException("稿件内容不能为空");
}
List<TbPicture> collect1 = tbPictures.stream().filter(t -> "Title page".equals(t.getFileType())).collect(Collectors.toList());
if (StringUtil.isNull(collect1)) {
throw new MyException("title page 不能为空");
}
//加载第一个文档
Document document1 = new Document(collect1.get(0).getLocalPath());
document1.setWatermark(null);
List<TbPicture> collect2 = tbPictures.stream().filter(t -> "Blinded Manuscript".equals(t.getFileType())).collect(Collectors.toList());
if (StringUtil.isNull(collect2)) {
throw new MyException("Blinded Manuscript 不能为空");
}
//加载第二个文档
Document document2 = new Document(collect2.get(0).getLocalPath());
//获取第一个文档的最后一个section
Section lastSection = document1.getLastSection();
//将第二个文档的段落作为新的段落添加到第一个文档的最后一个section
for (Section section : (Iterable<Section>) document2.getSections()) {
for (DocumentObject obj : (Iterable<DocumentObject>) section.getBody().getChildObjects()
) {
lastSection.getBody().getChildObjects().add(obj.deepClone());
}
}
List<TbPicture> collect3 = tbPictures.stream().filter(t -> "Tables".equals(t.getFileType())).collect(Collectors.toList());
handelFileType(tbPictures, lastSection, collect3, "Supporting information for review and publication");
//合并图片到doc文件中
List<TbPicture> collect7 = tbPictures.stream().filter(t -> "Figures and imagines".equals(t.getFileType())).collect(Collectors.toList());
if (StringUtil.isNotNull(collect7)) {
//添加图片到段落
for (TbPicture tbPicture : collect7) {
Paragraph paragraph2 = lastSection.addParagraph();
DocPicture docPicture = paragraph2.appendPicture(tbPicture.getLocalPath());
//设置图片宽度
docPicture.setWidth(425f);
//设置图片高度
docPicture.setHeight(284f);
}
}
//保存文档
try {
document1.saveToFile(outPath, FileFormat.Docx_2013);
File file = new File(outPath);
while (true) {
if (file.exists()) {
break;
}
}
//下面这一步是为了除掉使用spire.doc合并文件后在文件中会产生自带警告信息的问题
// 重新读取生成的文档
InputStream is = new FileInputStream(outPath);
XWPFDocument document = new XWPFDocument(is);
document.removeBodyElement(0);
//输出word内容文件流,新输出路径位置
OutputStream os = new FileOutputStream(outPath);
try {
document.write(os);
log.info("生成docx文档成功!");
} catch (Exception e) {
e.printStackTrace();
}
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("转换失败,原因是:{}", e.getMessage());
return false;
}
}
private static void handelFileType(List<TbPicture> tbPictures, Section lastSection, List<TbPicture> collect3, String s) {
if (StringUtil.isNotNull(collect3)) {
//加载第三个文档
Document document3 = new Document(collect3.get(0).getLocalPath());
//将第三个文档的段落作为新的段落添加到第一个文档的最后一个section
for (Section section : (Iterable<Section>) document3.getSections()) {
for (DocumentObject obj : (Iterable<DocumentObject>) section.getBody().getChildObjects()
) {
lastSection.getBody().getChildObjects().add(obj.deepClone());
}
}
}
List<TbPicture> collect4 = tbPictures.stream().filter(t -> s.equals(t.getFileType())).collect(Collectors.toList());
if (StringUtil.isNotNull(collect4)) {
//加载第四个文档
Document document4 = new Document(collect4.get(0).getLocalPath());
//将第四个文档的段落作为新的段落添加到第一个文档的最后一个section
for (Section section : (Iterable<Section>) document4.getSections()) {
for (DocumentObject obj : (Iterable<DocumentObject>) section.getBody().getChildObjects()
) {
lastSection.getBody().getChildObjects().add(obj.deepClone());
}
}
}
}