先看效果:
填充前:
填充后效果:
第一步: 引入Maven坐标:
<!-- hutool工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.3</version>
</dependency>
<!--word模板数据解析-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.9.0-beta</version>
</dependency>
<!-- word/pdf操作 -->
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>14.7.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/lib/aspose-words-15.8.0-jdk16.jar</systemPath>
</dependency>
第二步: 工具类:
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.exception.RenderException;
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.util.Map;
/**
* @author LSL
* @version 1.0
* @date 2022/6/22
*/
@Slf4j
public class WordUtil {
/**
* 填充word模板,并且转成pdf文件后返回:
* @param datas: 填充数据
* @param fileStream: 文件模板流 -- 可从OSS/FastDFS上获取流,直接传入;
* @return
* @throws IOException
*/
public static byte[] fillWordToPDF(Map<String,Object> datas,InputStream fileStream) throws IOException {
try {
//先填充word:
byte[] bytes = fillWord(datas, fileStream);
//在word转pdf:
return wordToPDF(new ByteArrayInputStream(bytes));
} catch (IOException ex){
log.error("系统异常::{}",ex);
throw ex;
}
}
/**
* 填充word模板,获取填充后的word文件流:
* @param datas: 填充数据
* @param fileStream: 文件模板流 -- 可从OSS/FastDFS上获取流,直接传入;
* @return
* @throws IOException
*/
public static byte[] fillWord(Map<String,Object> datas, InputStream fileStream) throws IOException {
XWPFTemplate template = null;
ByteArrayOutputStream wordOut = new ByteArrayOutputStream(1024);
try {
//设置占位符:
Configure config = Configure.builder()
.buildGramer("${", "}") //设置模板中的占位符${}, 默认是{{}}
.setValidErrorHandler(new Configure.AbortHandler()) //若模板中占位符与填充属性不对应,则报错;
.bind("item", new HackLoopTableRenderPolicy()) //设置模板中表格的参数属性
.build();
//填充文本域:
template = XWPFTemplate.compile(fileStream, config).render(datas);
template.write(wordOut);
}catch (RenderException ex){
log.error("模板填充失败,请保证模板文本域与参数保持一致。错误信息::{}",ex);
throw ex;
} catch (IOException ex){
log.error("系统异常::{}",ex);
throw ex;
}finally {
try {
if (template != null){
template.close();
}
} catch (IOException ex) {
log.error("关闭文件流资源异常::{}",ex);
}
}
return wordOut.toByteArray();
}
/**
* word转pdf
* @param wordInStream: word文件输入流;
*/
public static byte[] wordToPDF(InputStream wordInStream) {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(1024);
try {
InputStream licenseIn = WordUtil.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(licenseIn);
//因linux环境没有语言包,当项目部署到linux环境后,转成的pdf中的中文是类似乱码的,所以需要去加载此目录下的语言包;
OsInfo osInfo = SystemUtil.getOsInfo();
if(osInfo.isLinux()){
//====================================== 注意 ============================================
//注意: 需要把项目中resource/fonts目录下的语言包全部放到linux中的此目录下,否则linux环境中处理是乱码;
//以下是我自己定义的目录,你可随意更改为你linux上的目录;
FontSettings.setFontsFolder("/usr/share/fonts/chinese", true);
//=======================================================================================
}
//Address是将要被转化的word文档
Document doc = new Document(wordInStream);
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
doc.save(byteOut, SaveFormat.PDF);
} catch (Exception e) {
log.error("word转pdf异常::{}",e);
throw new RuntimeException("word转pdf异常");
}
return byteOut.toByteArray();
}
/**
* word转pdf
* @param wordInStream: word文件输入流;
* @param pdfOutStream: pdf文件输出流;
*/
public static void wordToPDF(InputStream wordInStream, OutputStream pdfOutStream) {
try {
InputStream licenseIn = WordUtil.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(licenseIn);
//因linux环境没有语言包,当项目部署到linux环境后,转成的pdf中的中文是类似乱码的,所以需要去加载此目录下的语言包;
OsInfo osInfo = SystemUtil.getOsInfo();
if(osInfo.isLinux()){
//====================================== 注意 ============================================
//注意: 需要把项目中resource/fonts目录下的语言包全部放到linux中的此目录下,否则linux环境中处理是乱码;
//以下是我自己定义的目录,你可随意更改为你linux上的目录;
FontSettings.setFontsFolder("/usr/share/fonts/chinese", true);
//=======================================================================================
}
//Address是将要被转化的word文档
Document doc = new Document(wordInStream);
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
doc.save(pdfOutStream, SaveFormat.PDF);
} catch (Exception e) {
log.error("word转pdf异常::{}",e);
throw new RuntimeException("word转pdf异常");
}
}
}
第三步: 测试
1、word模板文件: 请按照第一张图片自行制作;
2、测试代码:填充成功后直接转成pdf文件;
public static void main(String[] args) throws IOException {
//数据
Map datas = new HashMap<String,Object>();
datas.put("dept", "采购部");
datas.put("name", "张三");
LocalDate date = LocalDate.now();
datas.put("year", date.getYear());
datas.put("month", date.getMonthValue());
datas.put("day", date.getDayOfMonth());
//表格(多条数据格式):
List itemList = new ArrayList<>();
Map itemMap = new HashMap();
itemMap.put("goods", "笔记本电脑");
itemMap.put("num", "2");
itemMap.put("cost", "10000");
itemMap.put("remark", "按需采购");
itemList.add(itemMap);
itemMap = new HashMap();
itemMap.put("goods", "台式电脑");
itemMap.put("num", "1");
itemMap.put("cost", "8000");
itemMap.put("remark", "按需采购");
itemList.add(itemMap);
datas.put("item",itemList);
datas.put("total","10000");
//需要填充到word中的图片数据
ClassLoader classLoader = WordUtil.class.getClassLoader();
BufferedImage image = ImageIO.read(classLoader.getResourceAsStream("template/image.png"));
datas.put("image", new PictureRenderData(image.getWidth(), image.getHeight(), PictureType.PNG, image));
//模板文件流
InputStream tempStream = classLoader.getResourceAsStream("template/测试模板文件.docx");
//填充word:
byte[] bytes = WordUtil.fillWord(datas, tempStream);
//word转pdf:
File pdfFile = new File("生成的PDF文件" + System.currentTimeMillis() + ".pdf");
WordUtil.wordToPDF(new ByteArrayInputStream(bytes),new FileOutputStream(pdfFile));
}
项目依赖:
1、Word转Pdf的Jar包,在Maven中心仓库中不存在。此处我提供了优快云下载:
优快云下载: 点击此处下载Jar包
2、License.xml文件也提供了优快云下载:
优快云下载: 点击此处下载License文件
补充知识点:
1、Maven项目手动引入Jar包的编译、打包方式请看此篇文章:https://mp.youkuaiyun.com/mp_blog/creation/editor/125435777
2、Word转Pdf时,Linux系统会出现中文乱码问题(Window不存在);解决办法:Linux环境aspose插件word转pdf中文乱码解决方案_赵广陆的博客-优快云博客_aspose中文乱码