基于FreeMarker模板引擎生成Word并导出PDF
1.导入相关maven
xml
<!-- FreeMarker模板引擎 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
<dependency>
<groupId>aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>19.5</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>4.0.5</version>
</dependency>
2.FreeMarker渲染数据导出word
java
/**
* Word文档生成工具类
*/
public class WordDocumentGenerator {
/**
* 使用FreeMarker生成Word文档
*/
public static byte[] generateWordDocumentAsBytes(String templatePath, Map<String, Object> root)
throws IOException, TemplateException {
// 创建FreeMarker配置
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setDefaultEncoding("UTF-8");
// 设置模板加载路径
ClassPathResource resource = new ClassPathResource(templatePath);
File templateFile = resource.getFile();
String templateDir = templateFile.getParent();
String templateName = templateFile.getName();
cfg.setDirectoryForTemplateLoading(new File(templateDir));
// 加载模板
Template template = cfg.getTemplate(templateName, "UTF-8");
// 使用ByteArrayOutputStream获取字节流
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Writer out = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
template.process(root, out);
out.close();
return outputStream.toByteArray();
}
public static InputStream generateWordDocumentAsStream(String templatePath, Map<String, Object> root)
throws IOException, TemplateException {
byte[] bytes = generateWordDocumentAsBytes(templatePath, root);
return new ByteArrayInputStream(bytes);
}
/**
* 使用FreeMarker生成Word文档并返回Base64编码的字符串
*/
public static String generateWordDocumentAsBase64(String templatePath, Map<String, Object> root)
throws IOException, TemplateException {
byte[] bytes = generateWordDocumentAsBytes(templatePath, root);
return Base64.getEncoder().encodeToString(bytes);
}
/**
* 使用FreeMarker生成Word文档并保存到指定路径
*/
public static void generateWordDocument(String templatePath, String outputPath, Map<String, Object> root)
throws IOException, TemplateException {
// 创建FreeMarker配置
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setDefaultEncoding("UTF-8");
// 设置模板加载路径
File templateFile = new File(templatePath);
String templateDir = templateFile.getParent();
String templateName = templateFile.getName();
cfg.setDirectoryForTemplateLoading(new File(templateDir));
// 加载模板
Template template = cfg.getTemplate(templateName, "UTF-8");
// 创建输出目录(如果不存在)
File outputFile = new File(outputPath);
outputFile.getParentFile().mkdirs();
// 写入文件
try (Writer fileWriter = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFile), "UTF-8"))) {
template.process(root, fileWriter);
}
}
3.导出PDF
说明:因为FreeMarker导出的word文档,本质还是xml文件,所以这里要用到aspose工具,支持xml文件 转化为pdf.
1.安装许可证,不然会出现导出会有水印。
license.xml
xml
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>
AsposeWordToPDFGenerator.java
java
public class AsposeWordToPDFGenerator {
public static boolean getLicense() {
boolean result = false;
try {
// license.xml应放在..\WebRoot\WEB-INF\classes路径下
InputStream is = WordDocumentGenerator.class.getClassLoader().getResourceAsStream("license.xml");
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
WordDocumentGenerator *
* @param inputStream
* @param outputStream
* @param saveTo SaveFormat {@link SaveFormat }
*/
public static void conversion(InputStream inputStream, OutputStream outputStream, int saveTo) {
// 验证License 若不验证则转化出的pdf文档会有水印产生
if (!getLicense()) {
return;
}
try {
// Address是将要被转化的word文档
Document document = new Document(inputStream);
// 设置字体文件夹路径(根据实际字体存放位置修改)
String fontPath = AsposeWordToPDFGenerator.class.getClassLoader().getResource("Fonts").getPath();
FontSettings fontSettings = new FontSettings();
fontSettings.setFontsFolder(fontPath,true);
document.setFontSettings(fontSettings);
for (Section section : document.getSections()) {
PageSetup pageSetup = section.getPageSetup();
pageSetup.setTopMargin(20); // 上边距
pageSetup.setPaperSize(PaperSize.A4);
TableCollection tables = section.getBody().getTables();
for (Table table : tables) {
table.setAllowAutoFit(false);
RowCollection rows = table.getRows();
for (Row row : rows) {
CellCollection cells = row.getCells();
for (Cell cell : cells) {
CellFormat cellFormat = cell.getCellFormat();
cellFormat.setFitText(false);
cellFormat.setWrapText(true);
}
}
}
}
// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
document.save(outputStream, saveTo);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("word转pdf失败");
}
}
/**
* Word 转 PDF 并返回 base64 编码
* @param inputStream Word 文档输入流
* @return PDF 文件的 base64 编码字符串,转换失败返回 null
*/
public static String convertToBase64(InputStream inputStream) {
if (!getLicense()) {
return null;
}
try (java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream()) {
Document document = new Document(inputStream);
// 设置字体路径(使用类路径)
String fontPath = AsposeWordToPDFGenerator.class.getClassLoader().getResource("Fonts").getPath();
FontSettings fontSettings = new FontSettings();
fontSettings.setFontsFolder(fontPath, true);
document.setFontSettings(fontSettings);
for (Section section : document.getSections()) {
PageSetup pageSetup = section.getPageSetup();
pageSetup.setTopMargin(20);
pageSetup.setPaperSize(PaperSize.A4);
TableCollection tables = section.getBody().getTables();
for (Table table : tables) {
table.setAllowAutoFit(false);
RowCollection rows = table.getRows();
for (Row row : rows) {
CellCollection cells = row.getCells();
for (Cell cell : cells) {
CellFormat cellFormat = cell.getCellFormat();
cellFormat.setFitText(false);
cellFormat.setWrapText(true);
}
}
}
}
document.save(outputStream, SaveFormat.PDF);
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("word 转 pdf 失败");
}
}
}