itextpdf目前使用的是5版本的
1.导入基础包
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<!--css高级样式支持-->
<!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-itext5 -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.5</version>
</dependency>
2.创建HTML模板
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>2</title>
<style>
/*这是将打印时的页面大小设置为A4大小,并保留好一定的边距 210×297mm*/
@page {
size: 21cm 29.7cm;
font-size: 14pt;
color: black;
line-height: 1.4;
text-align: justify;
margin: 0;
padding: 0;
}
body {
font-family: FZLanTingHei-L-GBK;
width: 21cm;
height: 29.7cm;
margin: 0;
padding: 0;
overflow: hidden;
}
img{
width: 21cm;
height: 29.7cm;
}
</style>
</head>
<body>
<div align="center">
<img src="1.png"></img>
</div>
</body>
</html>
3.ThymeleafUtils工具类
用户获取html模板和交互数据
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import java.util.Map;
public class ThymeleafUtils {
/**
* 服务端动态渲染html文件,并返回渲染后的html字符串
* @param path 需要渲染的html文件路径 如:"template/xxx/xxx.html"
* @param params 要传递的参数
* @return
*/
public static String getHtmlBody(String path, Map<String,Object> params) {
TemplateEngine templateEngine = new SpringTemplateEngine();
// 1.读取磁盘中的模板文件,设置引擎使用resolver
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
templateEngine.setTemplateResolver(resolver);
// 2. 设置映射数据
// 1. 利用thymeleaf中Context对象,存储模板中所用到的值
Context context = new Context();
context.setVariables(params);
//3.使用thymeleaf 向html文件内赋值,并获取渲染后的html代码
String content = templateEngine.process("templates/"+path,context);
return content;
}
}
4.创建itextpdf工具类HtmlToPdf
将HTML内容转为pdf,方法内有转为字节的,也有直接给路径写出PDF文件的,因为itextpdf默认是不支持中文的,需要手动加载中文。
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import javax.annotation.PostConstruct;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
@Component
public class HtmlToPdf {
@Value("${imagePath}")
private String imagePath;
public static String IMAGE_PATH;
private static final String FONT1 = "templates/方正兰亭细黑_GBK.TTF";
private static final String FONT2 = "templates/方正兰亭中黑_GBK.TTF";
@PostConstruct
public void init(){
IMAGE_PATH = this.imagePath;
}
/**
* 生成pdf
* @param content html内容
* @param newFile 路径
* @throws Exception
*/
public static void createPdf(String content,String newFile) throws Exception{
ITextRenderer render = new ITextRenderer();
ITextFontResolver fontResolver = render.getFontResolver();
fontResolver.addFont(FONT1, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont(FONT2, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// 解析html生成pdf
render.setDocumentFromString(content);
//解决图片相对路径的问题
render.getSharedContext().setBaseURL("file:"+IMAGE_PATH);
render.layout();
render.createPDF(new FileOutputStream(newFile));
}
/**
* 生成pdf
* @param content htm内容
* @return pdf流
* @throws Exception
*/
public static byte[] createPdf(String content) throws Exception{
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
ITextRenderer render = new ITextRenderer();
ITextFontResolver fontResolver = render.getFontResolver();
fontResolver.addFont(FONT1, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont(FONT2, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// 解析html生成pdf
render.setDocumentFromString(content);
//解决图片相对路径的问题
render.getSharedContext().setBaseURL("file:"+IMAGE_PATH);
render.layout();
render.createPDF(outputStream);
}catch (Exception e){
e.printStackTrace();
}
return outputStream.toByteArray();
}
/**
* 合并pdf
* @param bytes
* @param newFile
*/
public static void mergePdfFiles(List<byte[]> bytes, String newFile) {
try {
// 以第一个pdf作为基础,后面的每页信息逐渐累加
Document document = new Document(new PdfReader(bytes.get(0)).getPageSize(1));
PdfCopy copy = new PdfCopy(document, new FileOutputStream(newFile));
document.open();
for (byte[] aByte : bytes) {
PdfReader reader = new PdfReader(aByte);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
document.close();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
}
/**
* 合并pdf
* @param bytes
*/
public static byte[] mergePdfFiles(List<byte[]> bytes) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
// 以第一个pdf作为基础,后面的每页信息逐渐累加
Document document = new Document(new PdfReader(bytes.get(0)).getPageSize(1));
PdfCopy copy = new PdfCopy(document, outputStream);
document.open();
for (byte[] aByte : bytes) {
PdfReader reader = new PdfReader(aByte);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
document.close();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
return outputStream.toByteArray();
}
}
①.图片资源处理:
1.网络图片,
2.服务器资源图片,需要指定路径render.getSharedContext().setBaseURL("file:/home/image/");
3.base64图片
4.项目内图片,获取图片后转base64
ClassPathResource classPathResource = new ClassPathResource("static/images/1.jpg");
//绝对路径
classPathResource.getFile().getPath()
②多页PDF处理
使用mergePdfFiles方法可以对多个PDF流合并
5.使用
Map<String,Object> map = new HashMap<>();
String start = ThymeleafUtils.getHtmlBody("/1.html",map);
byte[] pdfByte = HtmlToPdf.createPdf(start);