java生成 动态 pdf_java根据模板HTML动态生成PDF
原文:https://segmentfault.com/a/1190000009160184
一、需求说明:根据业务需要,需要在服务器端生成可动态配置的PDF文档,方便数据可视化查看。
二、解决方案:
iText+FreeMarker+JFreeChart生成可动态配置的PDF文档
iText有很强大的PDF处理能力,但是样式和排版不好控制,直接写PDF文档,数据的动态渲染很麻烦。
FreeMarker能配置动态的html模板,正好解决了样式、动态渲染和排版问题。
JFreeChart有这方便的画图API,能画出简单的折线、柱状和饼图,基本能满足需要。
三、实现功能:
1、能动态配置PDF文档内容
2、支持中文字体显示的动态配置
3、设置自定义的页眉页脚信息
4、能动态生成业务图片
5、完成PDF的分页和图片的嵌入
四、主要代码结构说明:
1、component包:PDF生成的组件 对外提供的是PDFKit工具类和HeaderFooterBuilder接口,其中PDFKit负责PDF的生成,HeaderFooterBuilder负责自定义页眉页脚信息。
2、builder包:负责PDF模板之外的额外信息填写,这里主要是页眉页脚的定制。
3、chart包:JFreeChart的画图工具包,目前只有一个线形图。
4、test包:测试工具类
5、util包:FreeMarker等工具类。
五、关键代码说明:
1、模板配置
font-family: pingfang sc light;
}
.center{
text-align: center;
width: 100%;
}
${templateName}
iText官网:${ITEXTUrl}
FreeMarker官网:${freeMarkerUrl}
JFreeChart教程:${JFreeChartUrl}
${item}
#list>
百度图标
气温变化对比图
2、获取模板内容并填充数据
/**
* @description 获取模板
*/
public static String getContent(String fileName,Object data){
String templatePath=getPDFTemplatePath(fileName);//根据PDF名称查找对应的模板名称
String templateFileName=getTemplateName(templatePath);
String templateFilePath=getTemplatePath(templatePath);
if(StringUtils.isEmpty(templatePath)){
throw new FreeMarkerException("templatePath can not be empty!");
}
try{
Configuration config = new Configuration(Configuration.VERSION_2_3_25);//FreeMarker配置
config.setDefaultEncoding("UTF-8");
config.setDirectoryForTemplateLoading(new File(templateFilePath));//注意这里是模板所在文件夹,不是文件
config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
config.setLogTemplateExceptions(false);
Template template = config.getTemplate(templateFileName);//根据模板名称 获取对应模板
StringWriter writer = new StringWriter();
template.process(data, writer);//模板和数据的匹配
writer.flush();
String html = writer.toString();
return html;
}catch (Exception ex){
throw new FreeMarkerException("FreeMarkerUtil process fail",ex);
}
}
3、导出模板到PDF文件
/**
* @description 导出pdf到文件
* @param fileName 输出PDF文件名
* @param data 模板所需要的数据
*
*/
public String exportToFile(String fileName,Object data){
String htmlData= FreeMarkerUtil.getContent(fileName, data);//获取FreeMarker的模板数据
if(StringUtils.isEmpty(saveFilePath)){
saveFilePath=getDefaultSavePath(fileName);//设置PDF文件输出路径
}
File file=new File(saveFilePath);
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
FileOutputStream outputStream=null;
try{
//设置输出路径
outputStream=new FileOutputStream(saveFilePath);
//设置文档大小
Document document = new Document(PageSize.A4);//IText新建PDF文档
PdfWriter writer = PdfWriter.getInstance(document, outputStream);//设置文档和输出流的关系
//设置页眉页脚
PDFBuilder builder = new PDFBuilder(headerFooterBuilder,data);
builder.setPresentFontSize(10);
writer.setPageEvent(builder);
//输出为PDF文件
convertToPDF(writer,document,htmlData);
}catch(Exception ex){
throw new PDFException("PDF export to File fail",ex);
}finally{
IOUtils.closeQuietly(outputStream);
}
return saveFilePath;
}
4、测试工具类
public String createPDF(Object data, String fileName){
//pdf保存路径
try {
//设置自定义PDF页眉页脚工具类
PDFHeaderFooter headerFooter=new PDFHeaderFooter();
PDFKit kit=new PDFKit();
kit.setHeaderFooterBuilder(headerFooter);
//设置输出路径
kit.setSaveFilePath("/Users/fgm/Desktop/pdf/hello.pdf”);//设置出书路径
String saveFilePath=kit.exportToFile(fileName,data);
return saveFilePath;
} catch (Exception e) {
log.error("PDF生成失败{}", ExceptionUtils.getFullStackTrace(e));
return null;
}
}
public static void main(String[] args) {
ReportKit360 kit=new ReportKit360();
TemplateBO templateBO=new TemplateBO();//配置模板数据
templateBO.setTemplateName("Hello iText! Hello freemarker! Hello jFreeChart!");
templateBO.setFreeMarkerUrl("http://www.zheng-hang.com/chm/freemarker2_3_24/ref_directive_if.html");
templateBO.setITEXTUrl("http://developers.itextpdf.com/examples-itext5");
templateBO.setJFreeChartUrl("http://www.yiibai.com/jfreechart/jfreechart_referenced_apis.html");
templateBO.setImageUrl("https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png");
List scores=new ArrayList();
scores.add("90");
scores.add("95");
scores.add("98");
templateBO.setScores(scores);
List lineList=getTemperatureLineList();
TemperatureLineChart lineChart=new TemperatureLineChart();
String picUrl=lineChart.draw(lineList,0);//自定义的数据画图
templateBO.setPicUrl(picUrl);
String path= kit.createPDF(templateBO,"hello.pdf");
System.out.println(path);
}
六、生成效果图:
七、项目完整代码
1、github地址:https://github.com/superad/pdf-kit
2、项目git地址:git@github.com:superad/pdf-kit.git
八、遇到的坑:
1、FreeMarker配置模板文件样式,在实际PDF生成过程中,可能会出现一些不一致的情形,目前解决方法,就是换种方式调整样式。
2、字体文件放在resource下,在打包时会报错,运行mvn -X compile 会看到详细错误:
这是字体文件是二进制的,而maven项目中配置了资源文件的过滤,不能识别二进制文件导致的,
plugins中增加下面这个配置就好了:
src/main/resources
true
org.apache.maven.plugins
maven-resources-plugin
2.7
UTF-8
ttf
3、PDF分页配置:
在ftl文件中,增加分页标签:
九、 完整maven配置:
com.itextpdf
itextpdf
5.4.2
com.itextpdf.tool
xmlworker
5.4.1
com.itextpdf
itext-asian
5.2.0
org.xhtmlrenderer
flying-saucer-pdf
9.0.3
org.freemarker
freemarker
2.3.26-incubating
jfreechart
jfreechart
1.0.0
ch.qos.logback
logback-core
1.0.13
ch.qos.logback
logback-classic
1.0.13
ch.qos.logback
logback-access
1.0.13
org.slf4j
slf4j-api
1.7.5
org.slf4j
log4j-over-slf4j
1.7.21
com.google.guava
guava
20.0
org.projectlombok
lombok
1.14.8
org.apache.commons
commons-io
1.3.2
commons-lang
commons-lang
2.6
java生成 动态 pdf_java根据模板HTML动态生成PDF相关推荐
- Java项目中利用Freemarker模板引擎导出--生成Word文档
应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523 ...
- easyui java代码生成器,easyui+jdbc+xml模板开发自动化生成报表的java工具 - 贪吃蛇学院-专业IT技术平台...
ps:看到有同学问了一下问题,做一下答复,该实现不是web项目,大家只需要将代码集成到web项目中即可,原项目太大,不便上传.还有 jar包自己找啊 呵呵 采用easyui+jdbc+xml模板生成报 ...
- java ee web pdf_Java EE Web高级开发案例 PDF扫描版[69MB]
Java EE Web高级开发案例 内容简介: <Java EE Web高级开发案例>充分体现了高等职业教育的特点,突出了理论和实践的紧密结合,以充分掌握基本技术技能和必要的基本知识为出发 ...
- java txt转pdf_java实现TXT自动读取转换PDF并且加密水印
package com.pdf.test; import java.io.*; import com.lowagie.text.*; import com.lowagie.text.Font; imp ...
- java 图片合成pdf_java将多张图片合并转为PDF
所需jar包:com.lowagie.text package weaver.gy.util; import java.awt.image.BufferedImage; import java.io. ...
- java高级教程pdf_Java高级编程实用教程中文 PDF版_IT教程网
资源名称:Java高级编程实用教程中文 PDF版 内容简介 本书是一本介绍Java高级编程的实用教程,面向具有一定Java编程基础的开发人员.本书通过对"项目"的分析.实现和讲解, ...
- java doc to pdf_Java实现doc或xls转PDF
package com.example.demo.config; import java.io.*; import com.aspose.words.*; //引入aspose-words-15.8. ...
- java doc转pdf_java 完美解决 ppt/pptx 转pdf 源码
需要的pom文件 第一个先来介绍pptx转pdf public class PptxToPDFConverter extends Converter{ // private static final ...
- java用模板生成word(docx)文档(含动态表格)
生成word思路 用WPS或者office编辑好word的样式,然后另存为word xml文档,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Docx. 编 ...
- Word制作生成html模板替换动态值为占位符使用Java转为pdf文件
引言 最近开发遇到一个需求,公司法务给了一个word合同模板,需要替换里面的动态值为具体业务数据,然后生成pdf文件进行电子签章. 在网上找寻各种方法,发现很多都是需要特定工具,或者代码不全运行不起来 ...
最新文章
- etcd 笔记(04)— etcd 网关与 gRPC 网关
- 开机f8修复电脑步骤_电脑无法启动,屏幕显示白色小横条,怎么办?可收藏以备不时之需...
- LeetCode Longest Repeating Character Replacement(滑动窗口)
- hadoop三个配置文件的参数含义说明
- 其实昨天去加班也没有干什么事情,就只有3个人
- DataSet DataTable操作
- Windows下静态链接库的使用
- 截获android屏幕服务,如何捕获android设备屏幕内容?
- 【Acwing 219. 剪纸游戏】
- php pdo dblib,PHP DBlib PDO问题
- oracle删除数据释放表空间流程
- 收藏 | 如何撰写好一篇论文?密歇根教授《撰写高影响力论文指南》
- linux rzsz安装
- OSAL动态内存分配
- 模拟器搭建之二:如何搭建 MTK 6589模拟器
- 黑苹果HIDPI开启问题
- Linux环境下向github上传代码(生成token、生成本地密钥)
- Sicily.1059. Exocenter of a Trian(求垂心,向量旋转)
- 更新mysql表结构,同步数据库表结构
- php获取当前周得周一_php获取本周一的日期实现方法
热门文章
- windows清理_10款欧美流行的Windows清理软件
- 广东大学计算机基础教材,21世纪高等学校计算机公共基础课规划教材:大学计算机基础(第2版)...
- android vlc m3u8,Exoplayer播放m3u8文件Android
- 六自由度机械臂研究(1)- 简介, 自由度与改装
- 基于php的人力资源管理系统,基于thinkPHP框架的人力资源管理系统
- Redis——修改redis配置文件,并使配置生效
- 如何在ppt中生成柱状图_Excel表格数据如何生成柱状图等-EXCEL如何制作柱状图?...
- MultiTracker 多目标跟踪算法
- 计算机信息安全攻防大赛,计算机学院举办校第六届网络攻防大赛
- 陈丹琦组最新力作:仅需dropout两次的对比学习框架