word文档转pdf

主要使用的库是xdocreport

参考链接 link

maven 依赖

1
2
3
4
5
6
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<xdocreport.version>1.0.5</xdocreport.version>
</properties>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.converter.docx.xwpf</artifactId>
<version>${xdocreport.version}</version>
</dependency>

<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.template.velocity</artifactId>
<version>${xdocreport.version}</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
<version>${xdocreport.version}</version>
</dependency>

<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.itext.extension</artifactId>
<version>${xdocreport.version}</version>
</dependency>

demo代码

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
public class PDFUtils {

public static void main(String[] args) {
try {
// 1) Load Docx file by filling Velocity template engine and cache
// it to the registry
InputStream in = new FileInputStream(new File("D:\\work\\pdf\\DocxProjectWithVelocity.docx"));
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Velocity);

// 2) Create context Java model
IContext context = report.createContext();
Project project = new Project("XDocReport");
context.put("project", project);

// 3) Generate report by merging Java model with the Docx
OutputStream out = new FileOutputStream(new File(
"DocxProjectWithVelocity_Out.pdf"));
// report.process(context, out);
Options options = Options.getTo(ConverterTypeTo.PDF).via(
ConverterTypeVia.XWPF);
report.convert(context, options, out);
System.out.println("finish");
} catch (IOException e) {
e.printStackTrace();
} catch (XDocReportException e) {
e.printStackTrace();
}
}
}

完整代码,包括解决中文显示问题

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.foxconn.fuyhui.util.pdf;

import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.pdf.BaseFont;
import fr.opensagres.xdocreport.converter.ConverterTypeTo;
import fr.opensagres.xdocreport.converter.ConverterTypeVia;
import fr.opensagres.xdocreport.converter.Options;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.itext.extension.font.ITextFontRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import org.apache.log4j.Logger;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
* Created by Beldon.
* Copyright (c) 2017/7/27, All Rights Reserved.
* https://www.fuyhui.com/
*/
public abstract class PdfUtil {
private static Logger log = Logger.getLogger(PdfUtil.class);

private static BaseFont defaultFont = null;

static {
try {
loadFont();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}

//加载字体
private static void loadFont() throws IOException, DocumentException {
//arialuni能够显示中文
defaultFont = BaseFont.createFont(PdfUtil.class.getResource("/font/arialuni.ttf").getFile(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
String path = PdfUtil.class.getResource("/font").getFile();
FontFactory.registerDirectory(path); //加载字体
}

/**
* word模板解析转PDF
* <p>
* 主要用到 velocity 模板引擎,word里面要插入 MergeField 域,变量格式是velocity格式
*
* @param template 模板
* @param data 模板数据
* @param outputStream 输出流
*/
public final static void render(File template, Map<String, Object> data, OutputStream outputStream) {
try {
if (log.isDebugEnabled()) {
log.info("Begin to render pdf");
}
// 1) Load Docx file by filling Velocity template engine and cache
// it to the registry
InputStream in = new FileInputStream(template);
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Velocity);
report.setFieldsMetadata(new FieldsMetadata());

// 2) Create context Java model
IContext context = report.createContext();
data.forEach(context::put);
// report.process(context, out);
Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF);

//设置字体
PdfOptions pdfOptions = PdfOptions.create();
pdfOptions.fontProvider((familyName, encoding, size, style, color) -> {
try {
if (FontFactory.contains(familyName)) { //如果font工厂里面有font,则加载,否则使用默认字体
return FontFactory.getFont(familyName,encoding,size,style,color);
}else{
return new Font(defaultFont, size, style, color);
}
} catch (Throwable e) {
e.printStackTrace();
return ITextFontRegistry.getRegistry().getFont(familyName, encoding, size, style, color);
}
});
options.subOptions(pdfOptions);

report.convert(context, options, outputStream);
if (log.isDebugEnabled()) {
log.info("Finish rendering pdf");
}
} catch (IOException | XDocReportException e) {
e.printStackTrace();
log.error("Rendering pdf error", e);
}
}

public final static void render(String templatePath, Map<String, Object> data, OutputStream outputStream) {
render(new File(templatePath), data, outputStream);
}

public final static void render(String templatePath, Map<String, Object> data, String outputFilePath) throws FileNotFoundException {
render(new File(templatePath), data, new FileOutputStream(new File(outputFilePath)));
}

//demo
public static void main(String[] args) {
try {
Map<String, Object> data = new HashMap<>();
Map<String, String> name = new HashMap<>();
name.put("name", "Demo我的中文");
data.put("project", name);
data.put("demoName", "Demo我的中文");
render("D:\\work\\pdf\\template.docx", data, "D:\\work\\pdf\\DocxProjectWithVelocity.pdf");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}