本项目所有源码和依赖资源都在文章顶部链接,有需要可以下载使用
poi-tl
库实现aspose-words
库实现aspose-pdf
库实现poi-tl
可以使用 maven 直接从中央仓库下载,但是 aspose
无法下载,需要从网上下载 jar 包并导入本地仓库
poi-tl
<dependency>
<groupId>com.deepoovegroupId>
<artifactId>poi-tlartifactId>
<version>1.12.1version>
dependency>
aspose-word
将 jar 包导入本地仓库
mvn install:install-file \
-DgroupId="com.aspose" \
-DartifactId="aspose-words" \
-Dversion="15.8.0" \
-Dpackaging="jar" \
-Dfile="aspose-words-15.8.0-jdk16.jar"
项目中添加依赖
<dependency>
<groupId>com.asposegroupId>
<artifactId>aspose-wordsartifactId>
<version>15.8.0version>
dependency>
aspose-pdf
将 jar 包导入本地仓库
mvn install:install-file \
-DgroupId="com.aspose" \
-DartifactId="aspose-pdf" \
-Dversion="17.8" \
-Dpackaging="jar" \
-Dfile="aspose.pdf-17.8.jar"
项目中添加依赖
<dependency>
<groupId>com.asposegroupId>
<artifactId>aspose-pdfartifactId>
<version>17.8version>
dependency>
license.xml
由于 aspose
库分为免费版和收费版,免费版导出的文档带有试用水印,所以需要添加 license.xml
,版权关系不在文章中写出,有需要的可以下载文章顶部链接的完整源码包。
@SpringBootApplication
public class Word2PDFApplication {
public static void main(String[] args) {
SpringApplication.run(Word2PDFApplication.class, args);
// word 模板
String wordTemplatePath = "src/main/resources/templates/简历模板.docx";
// 写入数据后的 word
String wordOutputPath = "src/main/resources/templates/简历模板-output.docx";
// word 转换为 pdf
String pdfOutputPath = "src/main/resources/templates/简历模板.pdf";
// pdf 增加水印
String pdfWithMarkerOutputPath = "src/main/resources/templates/简历模板-marker.pdf";
// step 1: 封装模板数据
Map<String, Object> dataMap = getPersonDataMap();
// step 2: 将数据写入 word 模板
writeDataToWord(dataMap, wordTemplatePath, wordOutputPath);
// step 3: 将 word 转换为 pdf
convertWordToPdf(wordOutputPath, pdfOutputPath);
// step 4: 将 pdf 增加水印
addMarkerToPdf(pdfOutputPath, pdfWithMarkerOutputPath);
}
// 封装业务数据,用于填入模板对应占位符中
private static Map<String, Object> getPersonDataMap() {
Map<String, Object> personDataMap = new HashMap<>();
personDataMap.put("name", "张三");
personDataMap.put("sex", "男");
personDataMap.put("birthDate", "1998-12-02");
personDataMap.put("id", "420202199812020011");
personDataMap.put("phone", "18819297766");
personDataMap.put("skills", "java Spring MySQL ...");
return personDataMap;
}
// 将业务数据写入 word 模板,并生成新的 word 文件
private static void writeDataToWord(Map<String, Object> dataMap, String wordTemplatePath, String wordOutputPath) {
XWPFTemplate render = XWPFTemplate.compile(wordTemplatePath).render(dataMap);
File dest = new File(wordOutputPath);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
render.writeToFile(wordOutputPath);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 将新生成的带有业务数据的 word 文档转换为 pdf 格式
private static void convertWordToPdf(String wordOutputPath, String pdfOutputPath) {
// 验证 License 若不验证则转化出的 pdf 文档带有水印
if (!getAsposeWordLicense()) {
return;
}
FileOutputStream os = null;
try {
long old = System.currentTimeMillis();
File file = new File(pdfOutputPath);
os = new FileOutputStream(file);
Document doc = new Document(wordOutputPath);
doc.save(os, SaveFormat.PDF);
long now = System.currentTimeMillis();
System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 对转换后的 pdf 文档添加水印效果
private static void addMarkerToPdf(String pdfOutputPath, String pdfWithMarkerOutputPath) {
// 验证 License 若不验证则增加水印后的 pdf 文档带有试用水印
boolean asposePdfLicense = getAsposePdfLicense();
if (!asposePdfLicense) {
return;
}
com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(pdfOutputPath);
TextStamp textStamp = new TextStamp("水印文本");
textStamp.getTextState().setFontSize(14.0F);
textStamp.getTextState().setFontStyle(FontStyles.Bold);
textStamp.setRotateAngle(45);
textStamp.setOpacity(0.2);
// 设置水印间距
float xOffset = 100;
float yOffset = 100;
// 添加水印到每一页
for (Page page : pdfDocument.getPages()) {
float xPosition = 0;
float yPosition = 0;
// 在页面上添加水印直到页面被覆盖
while (yPosition < page.getRect().getHeight()) {
textStamp.setXIndent(xPosition);
textStamp.setYIndent(yPosition);
page.addStamp(textStamp);
xPosition += xOffset;
// 如果水印超过页面宽度,移到下一行
if (xPosition + textStamp.getWidth() > page.getRect().getWidth()) {
xPosition = 0;
yPosition += yOffset;
}
}
}
// 保存修改后的文档
pdfDocument.save(pdfWithMarkerOutputPath);
}
// 验证 license,否则有试用水印
private static boolean getAsposeWordLicense() {
boolean result = false;
InputStream is = null;
try {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
org.springframework.core.io.Resource[] resources = resolver.getResources("classpath:license.xml");
is = resources[0].getInputStream();
License asposeLic = new License();
asposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
// 验证 license,否则有试用水印
private static boolean getAsposePdfLicense() {
boolean result = false;
InputStream is = null;
try {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
org.springframework.core.io.Resource[] resources = resolver.getResources("classpath:license.xml");
is = resources[0].getInputStream();
com.aspose.pdf.License asposeLic = new com.aspose.pdf.License();
asposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
}