1、添加maven依赖
<!-- itext -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.0</version>
</dependency>
<!-- renderer -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
<!--freemarker-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<!-- hutool 用到了模板引擎和工具类 -->
<!-- 官方文档:https://www.javajike.com/book/hutool/chapter13/8601729e6eee0c3a901fc95a303d639d.html -->
<!-- 官方API文档:https://apidoc.gitee.com/loolly/hutool/ -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.0</version>
</dependency>
<!-- commons-text 用到反转义-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.8</version>
</dependency>
<!-- guava 用了一些工具方法-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
2、准备模板文件和字体文件
- 模板文件 demo.ftl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"></meta>
<title>Title</title>
</head>
<body style = 'font-family:Microsoft YaHei;'>
<h1>PDF Demo</h1>
<h3>${user.name!'未知'}</h3>
<h3>${user.age!'未知'}</h3>
<h3>${user.gender!'未知'}</h3>
</body>
</html>
- 字体文件 MicrosoftYaHei.ttf,百度下载一个吧,商用的话应该需授权...
3、生成PDF代码
支持中文。实际使用需注意 自定义的模板文件、字体文件和填充的数据,并对下方示例代码进行修改和封装。
package com.example.demo.test;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.template.Engine;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Slf4j
public class Demo {
//PDF保存路径
public static String pdf_save_path = "/opt/demo/pdf/export/";
//PDF字体路径
public static String pdf_font_path = "/opt/demo/pdf/tmpl/font/MicrosoftYaHei.ttf";
//模板路径
public static String pdf_tmpl_path = "/opt/demo/pdf/tmpl/";
//模板名称
public static String pdf_tmpl_name = "demo.ftl";
//PDF加密密钥
public static String pdf_secret = "qwe123!@#.";
public static void main(String[] args) {
//读取模板
Engine engine = TemplateUtil.createEngine(new TemplateConfig(pdf_tmpl_path, TemplateConfig.ResourceMode.FILE));
Template template = engine.getTemplate(pdf_tmpl_name);
HashMap<String, Object> data = Maps.newHashMap();
//添加数据
HashMap<String, Object> user = Maps.newHashMap();
user.put("name","admin");
user.put("age","18");
user.put("gender","男");
data.put("user",user);
//根据模板和数据生成html
String html = template.render(data);
//对html内容进行反转义,例如将“和”转为双引号,防止XML解析异常
html = StringEscapeUtils.unescapeHtml4(html);
String fileName = "demo.pdf";
try (BufferedOutputStream out = FileUtil.getOutputStream(pdf_save_path + fileName);
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ITextRenderer iTextRenderer = new ITextRenderer();
iTextRenderer.getFontResolver().addFont(pdf_font_path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
iTextRenderer.setDocumentFromString(html);
iTextRenderer.layout();
iTextRenderer.createPDF(baos);
iTextRenderer.finishPDF();
//添加水印(可添加多个)
ArrayList<String> texts = Lists.newArrayList(DateUtil.now(), "我是水印1", "我是水印2");
InputStream in = new ByteArrayInputStream(baos.toByteArray());
baos.flush();
addWaterMark(in, out, texts);
System.out.println("success!");
} catch (Exception e) {
log.error("=====创建pdf异常:", e);
}
}
/**
* 添加水印
*
* @param arr
*/
public static void addWaterMark(InputStream in, OutputStream out, List<String> arr) throws DocumentException, IOException {
PdfReader pdfReader = new PdfReader(in);
PdfStamper pdfStamper = new PdfStamper(pdfReader, out);
pdfStamper.setEncryption(null, pdf_secret.getBytes(), PdfWriter.ENCRYPTION_AES_128, false);
int pages = pdfReader.getNumberOfPages() + 1;
// 设置水印透明度
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f);
for (int i = 1; i < pages; i++) {
PdfContentByte underContent = pdfStamper.getOverContent(i);
underContent.beginText();
underContent.setFontAndSize(BaseFont.createFont(pdf_font_path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 12);
underContent.setGState(gs);
underContent.setColorFill(Color.blue);
for (int m = 0; m < 6; m++) {
for (int j = 0; j < 6; j++) {
for (int n = 0; n < arr.size(); n++) {
underContent.showTextAlignedKerned(Element.ALIGN_LEFT, arr.get(n), 100 * j, (n + 1) * 20 + 200 * m, 45);
}
}
}
underContent.endText();
underContent.stroke();
}
pdfStamper.close();
pdfReader.close();
}
}
4、查看PDF

本文介绍了如何结合Itext和Freemarker库将HTML内容转换成PDF文档。首先,添加了必要的Maven依赖;接着,准备了FTL模板文件和中文字体MicrosoftYaHei.ttf;然后,展示了生成PDF的代码示例,特别强调了代码需根据实际需求调整;最后,可以查看生成的PDF文档。
4264

被折叠的 条评论
为什么被折叠?



