老鬼的博客 来都来啦,那就随便看看吧~
java word转pdf
发布于: 2019-11-02 更新于: 2019-11-02 分类于:  阅读次数: 

一:背景

1
2
3
4
5
6
公司最近项目需求是上传附件,其中附件是word或者pdf文件,
然后在ipad上做在线预览,并且要求word展示要像pdf一样有
分页的概念,iOS端未找到合适的方案,后台帮忙将用户上传
的word转成pdf,下面介绍了两种方式,一种是Docx4J转换,
另一种是借助com.jacob来转换,这两种方式在生产环境都
无法执行,不过简单记录一下区别和实现。

二:区别

1. Docx4J

1
Docx4J转换速度很慢,转换失真

2. com.jacob

1
2
com.jacob完美转换,不过只能在windows下运行,
还需要本地安装了office组件,还要配置ddl到path路径下。

三:实现

1. Docx4J

  • pom.xml
1
2
3
4
5
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.2.1</version>
</dependency>
  • 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.tohours.superplanner.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.io.IOUtils;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

public class PdfUtils {
public static void main(String[] args) {
String docxPath = "C:\\Users\\Administrator\\Desktop\\关于设立友邦中国2019爱你要久庆百年年度荣誉体系通知.docx";
String pdfPath = "C:\\Users\\Administrator\\Desktop\\1.pdf";
try {
convertDocxToPDF(docxPath, pdfPath);
} catch (Exception e) {
e.printStackTrace();
}
}

public static void convertDocxToPDF(String docxPath, String pdfPath) throws Exception {
OutputStream os = null;
try {
InputStream is = new FileInputStream(new File(docxPath));
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(is);
Mapper fontMapper = new IdentityPlusMapper();
fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));

mlPackage.setFontMapper(fontMapper);

os = new java.io.FileOutputStream(pdfPath);

FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(mlPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);

} catch (Exception ex) {
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(os);
}
}
}

2. com.jacob

1
2
3
4
5
JACOB是一个JAVA-COM桥,允许您从Java调用COM自动化组件。
它使用JNI对COM和Win32库进行本机调用。JACOB项目始于1999年,
目前已被全球成千上万的开发人员所积极使用。作为一个开源项目,
它受益于这些用户的综合经验,其中许多人对代码进行了修改,并
将其提交回以包含在项目中。
  • 如何配置
1
2
3
4
5
1.将下载好的jar包丢在WEB-INF/lib下
2.build path 将 jar包 包含进去
3.将jacob-1.19-x86.dll和jacob-1.19-x64.dll丢在path路径下
这里可以放在jdk/bin下,也可以放在其他已经配置到path路径的地方,
这个按自己的实际情况放置
  • java代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.tohours.superplanner.test;

import java.io.File;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;

public class Word2PdfUtil {
static final int wdFormatPDF = 17;// word转PDF 格式


public static void main(String[] args) {
String source = "C:\\Users\\Administrator\\Desktop\\关于设立友邦中国2019爱你要久庆百年年度荣誉体系通知.docx";
String target = "C:\\Users\\Administrator\\Desktop\\2.pdf";
word2pdf(source, target);
}

public static void word2pdf(String source, String target) {
ComThread.InitSTA();
ActiveXComponent app = null;
try {
app = new ActiveXComponent("Word.Application");
app.setProperty("Visible", false);
Dispatch docs = app.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.call(docs, "Open", source, false, true).toDispatch();
File tofile = new File(target);
if (tofile.exists()) {
tofile.delete();
}
Dispatch.call(doc, "SaveAs", target, wdFormatPDF);
Dispatch.call(doc, "Close", false);
} catch (Exception e) {
System.out.println(e.toString());
} finally {
if (app != null) {
app.invoke("Quit", 0);
}
ComThread.Release();
}
}
}
*************感谢您的阅读*************