技术栈:springboot+thymeleaf+pdf引擎
1.导入对应的jar包,使用srpingboot快速实现
<!--引入thymeleaf相关的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--用于pdf的页面渲染自带webkit浏览器内核-->
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-pdfbox</artifactId>
<version>1.0.0</version>
</dependency>
2.生成模板的java代码实现,文件路径需要修改您对应的位置
/**
* 本地
*构建一个pdf
* @param templateName 模板名称
* @param variables 模板变量
* @throws Exception
*/
public static void buildResource( String templateName, Map<String, Object> variables) throws Exception {
//thymeleaf构造模板引擎;给html文件赋值
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
//默认是找classpath路径下的资源
resolver.setPrefix("testPDF/templates/");
resolver.setSuffix(".html");//模板文件后缀
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(resolver);
//构造上下文
Context context = new Context();
context.setVariable("templateName",templateName);
//设置变量
context.setVariables(variables);
//TODO 渲染模板,返回的生成的模板的字符串
String example = templateEngine.process("parent", context);
// 生成pdf文件地址
String pdfPath ="D://"+ new Random().nextInt(30) + "-" + System.nanoTime() + ".pdf";
File file = new File(pdfPath);
file.createNewFile();
FileOutputStream os = new FileOutputStream(file);
//构建pdf的预览
PdfRendererBuilder builder = new PdfRendererBuilder();
//设置字体支持中文
builder.useFont(new ClassPathResource("testPDF/fonts/simsun.ttf").getFile(), "simsun");
//使用快速渲染器
builder.useFastMode();
//String s = ResourceUtils.getURL("testPDF/templates/").toString(); 获取资源路径
String path = new ClassPathResource("/testPDF/templates").getPath();//获取项目下的资源路径
//withHtmlContent()参数一是模板,参数二模板的基础路径
builder.withHtmlContent(example,new ClassPathResource("/testPDF/templates").getPath());
//输出pdf的结果
builder.toStream(os);
builder.run();
//设置字符编码
PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
writer.flush();
writer.close();
}
/**
* TODO 通过接口接口请求生成pdf模板;有pdf预览窗口
* @param templateName
* @param variables
* @throws Exception
*/
public static void requestBuildResource(HttpServletResponse response, String templateName, Map<String, Object> variables) throws Exception {
//thymeleaf构造模板引擎;给html文件赋值
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
//默认是找classpath路径下的资源
resolver.setPrefix("testPDF/templates/");
resolver.setSuffix(".html");//模板文件后缀
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(resolver);
//构造上下文(Model)
Context context = new Context();
//设置变量
context.setVariables(variables);
//TODO 渲染模板,返回的生成的模板的字符串
String example = templateEngine.process(templateName, context);
//TODO 生成pdf,浏览器进行展示
response.setHeader("Content-Disposition", "filename=" + new String(("pdfFileName" + ".pdf").getBytes(), "iso8859-1"));
//生成pdf,浏览器不进行展示,默认附件下载;原因:attachment标记以附件方式下载保存
// response.setHeader("Content-Disposition", "attachment;fileName=" + new String(("templateName" + ".pdf").getBytes("gb2312"), "ISO8859-1"));
OutputStream os = response.getOutputStream();
//构建pdf的构造器
PdfRendererBuilder builder = new PdfRendererBuilder();
//设置字体支持中文
//
builder.useFont(new ClassPathResource("testPDF/fonts/simsun.ttf").getFile(), "simsun");
builder.useFastMode();
//withHtmlContent()参数:提供一个包含要转换为PDF的XHTML/XML的字符串
//ResourceUtils.getURL()获取资源的地址
builder.withHtmlContent(example, ResourceUtils.getURL("testPDF/templates/").toString());
//输出pdf的结果
builder.toStream(os);
builder.run();
//设置字符编码
PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
writer.flush();
writer.close();
}
/**
* 生成本地word
* @param variables 模板需要的数据
* @throws Exception
*/
public static void buildWord( Map<String, Object> variables) throws Exception {
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
//默认是找classpath路径下的资源
resolver.setPrefix("testPDF/templates/");
resolver.setSuffix(".html");//模板文件后缀
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(resolver);
//构造上下文
Context context = new Context();
context.setVariables(variables);
// 生成word文件地址
String pdfPath ="D://"+ new Random().nextInt(30) + "-" + System.nanoTime() + ".docx";
File file = new File(pdfPath);
file.createNewFile();
FileOutputStream os = new FileOutputStream(file);
try( PrintWriter writer = new PrintWriter(new OutputStreamWriter(os))) {
//TODO 参数一是模板;参数二:上下文数据模板需要读取的数据容器;参数三writer输出流是指定输出到那个地方
templateEngine.process("one",context, writer);
}catch (Exception e){
log.error("导出word文件出错啦:{}", e.getMessage());
}
}
/**
* 通过接口生成word
* @param response
* @param variables
* @throws Exception
*/
public static void requestbuildWord(HttpServletResponse response, Map<String, Object> variables) throws Exception {
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
//默认是找classpath路径下的资源
resolver.setPrefix("testPDF/templates/");
resolver.setSuffix(".html");//模板文件后缀
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(resolver);
//构造上下文
Context context = new Context();
context.setVariable("templateName", "one");
context.setVariables(variables);
// 生成word文件地址
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment;fileName=" + new String(("test" + ".xls").getBytes("gb2312"), "ISO8859-1"));
try( PrintWriter writer = new PrintWriter(new OutputStreamWriter(response.getOutputStream()))) {
//TODO 参数一是模板;参数二:上下文数据模板需要读取的数据容器;参数三writer输出流是指定输出到那个地方
templateEngine.process("parent",context, writer);
}catch (Exception e){
log.error("导出word文件出错啦:{}", e.getMessage());
}
}
3.thymeleaf模板代码,自定义模板需要了解thymeleaf语法,可自行搜索thymeleaf官网学习
注意导出pdf一定要用这个parent父页面,先引入执行,原因父页面设置的中文编码的使用,防止导出中文乱码
parent页面代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8"/>
<title >父页面</title>
<style>
@page {
size: A4;
@top-center {
content: element(header);
}
@bottom-center {
content: '自由行产品详情';
font-family: 'simsun', serif;
}
}
html, body {
font-family: 'simsun', serif;
}
table {
-fs-table-paginate: paginate;
border-collapse: collapse;
}
table, td, th {
border: 1px solid #555;
padding: 3px 5px;
}
th {
background-color: #eff3fa;
}
#page-header {
position: running(header);
border-bottom: 1px solid #555;
padding: 5px;
}
#page-header-text {
font-size: 16px;
}
#page-header-num:after {
float: right;
text-align: right;
content: counter(page) '/' counter(pages);
}
</style>
</head>
<body>
<div id="page-header">
<span id="page-header-text">kindleboy</span>
<span id="page-header-num"></span>
</div>
<div th:include="${templateName}::body"></div>
</body>
</html>
测试模板页面代码,自行编辑
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<div>
<p>测试导出pdf</p>
<p th:text="'weclcome to guangzhou,'+${user.username}">静态数据</p>
</div>
</body>
</html>
字体中文设置文件:simsun.ttf
下面链接获取设置simsun.tff文件链接
链接:https://pan.baidu.com/s/1FkGDX9VcM4XNAlLuvvDQmA
提取码:tdqa
注意功能发布到linux服务器上,读取字体文件一定要用流的方式读取simsun.tff文件,防止读取不了