概述
思路:word模板转成Freemarker模板,再转换成pdf图片
限制:1.转换出的pdf排版会把模板的格式打乱,是文本居中显示;2. 仅支持文本的填充,图片没做过测试
需要的jar包:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>6.0.1</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>3.3.0</version>
</dependency>
废话少说,直接上代码:
package com.word.test.util;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.docx4j.convert.out.pdf.PdfConversion;
import org.docx4j.convert.out.pdf.viaXSLFO.Conversion;
import org.docx4j.convert.out.pdf.viaXSLFO.PdfSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import java.io.*;
import java.util.Map;
/**
* @Description: word文档测试
*/
public class WordTest {
/**
* word填充模板地址
*/
private String wordMouldPath = "D:\word\wordMoudle";
/**
* word填充模板地址
*/
private String wordMouldName = "intermediaryContract.ftl";
/**
* word填充后保存的地址
*/
private String wordStuffPath = " D:\word\wordToStuff";
/**
* word转换为pdf后保存的地址
*/
private String wordTransformPdfPath = "D:\word\wordToPdf";
private Configuration configuration = null;
private static final String CODING = "utf-8";
public WordTest() {
if (configuration == null) {
configuration = new Configuration();
configuration.setDefaultEncoding(CODING);
}
}
/**
* @param dataMap
要填入模本的数据文件
* @description 将数据归档到.doc的word文档中。数据续写到原目标文件末尾。
*/
public String fillContent(Map dataMap) {
// 输出文档路径及名称
Writer out = null;
FileOutputStream fileOutputStream = null;
String fileName = DataHelper.getFileName("doc"); // 获取文件名称
String stuffPath = wordStuffPath + File.separator + fileName; // 保存填充文件的绝对路径
try {
// 设置模本装置方法和路径,模板装载
configuration.setDirectoryForTemplateLoading(cn.hutool.core.io.FileUtil.touch(wordMouldPath));
Template template = configuration.getTemplate(wordMouldName);
template.setOutputEncoding(CODING);
fileOutputStream = new FileOutputStream(cn.hutool.core.io.FileUtil.touch(stuffPath));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, CODING);
out = new BufferedWriter(outputStreamWriter);
template.process(dataMap, out);
System.err.println("word文档填充成功!");
} catch (IOException | TemplateException e) {
e.printStackTrace();
} finally {
try {
if (ObjectUtil.isNotEmpty(out)) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (ObjectUtil.isNotEmpty(fileOutputStream)) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return stuffPath;
}
/**
* @Description word转换为pdf并保存
* @param path 带转换的word具体路径
* @Return java.lang.String
*/
public String wordTransformPDF(String path) {
OutputStream outputStream = null;
InputStream inputStream = null;
// 转换完后的pdf路径
String pdfPath = wordTransformPdfPath + File.separator + DataHelper.getFileName("pdf");
try {
inputStream = new FileInputStream(cn.hutool.core.io.FileUtil.touch(path));
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(inputStream);
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);
PdfConversion conversion = new Conversion(mlPackage);
outputStream = new FileOutputStream(pdfPath);
conversion.output(outputStream, new PdfSettings());
FileUtil.del(path);
System.err.println("转换成pdf成功!" + pdfPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Docx4JException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (ObjectUtil.isNotEmpty(outputStream)) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (ObjectUtil.isNotEmpty(inputStream)) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return pdfPath;
}
}
需要的jar包,等在代码中有明确的表示,唯独没有文件起名的封装方法,在下面贴出:
/**
* @param suffix
* @Description 根据后缀名获取文件名称,日期+随机字符串+后缀名
* @Return java.lang.String
*/
public static String getFileName(String suffix) {
String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String random = RandomUtil.randomNumbers(8);
return dateTime + random + "." + suffix;
}
封装方法的效果实例:
2020030313450866256796.doc
总结:
1.此方法有一个疑点,即org.docx4j.convert.out.pdf.PdfConversion; org.docx4j.convert.out.pdf.viaXSLFO.Conversion;
这两个类是官方不建议采用的,故此在编码时会显示红色字体,但并不报错,也不影响结果的输出。
2.通过Freemarker生成的word是doc格式的;
3.最终生成的pdf排版会把文本都居中显示;
此方法有瑕疵,在此记录仅为能否帮助到各位,以及自身再熟悉熟悉!大家有解决方法,非常欢迎在评论区留言,若转载请说明出处,谢谢!
(本文完)
最后
以上就是诚心早晨为你收集整理的word转PDF的全部内容,希望文章能够帮你解决word转PDF所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复