使用freemarker和itextpdf结合,将html转化为pdf
工作中遇到模板中的html,需要转化成pdf作为附件上传到系统
于是经过研究分析,得出用freemarker和itextpdf结合
maven需要导入包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itextpdf.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.8</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
新建FreemarkerUtils工具类
package com.example.common.util;
import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import freemarker.core.HTMLOutputFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import com.itextpdf.tool.xml.XMLWorkerHelper;
@Component
@Slf4j
public class FreemarkerUtils {
@Resource
private Configuration stringConfiguration;
private static final String FONT = "fonts/simhei.ttf";
/**
* 根据模板构建
* @param content 模板内容
* @param dataModel 模板数据
**/
public String buildByTemplate(String content, Map<String,Object> dataModel){
return buildByTemplate(content, dataModel, StrUtil.EMPTY);
}
/**
* 根据模板替换变量,得到变量替换后的内容
* @param content 模板内容
* @param dataModel 模板数据
* @param defaultString 构建失败返回的默认值
**/
public String buildByTemplate(String content, Map<String,Object> dataModel,String defaultString) {
try {
// stringConfiguration.setOutputFormat(HTMLOutputFormat.INSTANCE);
return FreeMarkerTemplateUtils.processTemplateIntoString(new Template("", content, stringConfiguration),
dataModel);
}catch (Exception e){
log.warn("解析模板失败", e);
}
return defaultString;
}
public void htmlToPdf(String content) {
// 创建一个Document对象
Document document = new Document();
try {
// 创建一个PdfWriter实例来写PDF文件
PdfWriter writer = PdfWriter.getInstance(document, Files.newOutputStream(Paths.get("E:\\张三测试.pdf")));
// 打开文档
document.open();
InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
FontProviderUtil fontProviderUtil = new FontProviderUtil();
// 读取HTML文件并将其转换为PDF
XMLWorkerHelper.getInstance().parseXHtml(writer, document,inputStream, null, StandardCharsets.UTF_8, fontProviderUtil);
// 关闭文档
document.close();
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
}
解决中文乱码和生成的pdf中文不显示问题
package com.example.common.util;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import lombok.extern.slf4j.Slf4j;
/**
* 字体
*/
@Slf4j
public class FontProviderUtil extends XMLWorkerFontProvider {
/**
* 黑体 常规
**/
public static final String SIMHEI_TTF = "fonts/simhei.ttf";
/**
* 解决乱码和中文在pdf不显示问题
* @param fontname the name of the font
* @param encoding the encoding of the font
* @param embedded true if the font is to be embedded in the PDF
* @param size the size of this font
* @param style the style of this font
* @param color the <CODE>BaseColor</CODE> of this font.
* @param cached true if the font comes from the cache or is added to
* the cache if new, false if the font is always created new
* @return
*/
@Override
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color, boolean cached) {
BaseFont bf = null;
try {
bf = BaseFont.createFont(SIMHEI_TTF, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
} catch (Exception e) {
log.info(e.getMessage());
e.printStackTrace();
}
Font font = new Font(bf, size, style, color);
font.setColor(color);
return font;
}
}
在业务层调用即可
freemarkerUtils.htmlToPdf(content);