原文: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相关推荐

  1. Java项目中利用Freemarker模板引擎导出--生成Word文档

    应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523 ...

  2. easyui java代码生成器,easyui+jdbc+xml模板开发自动化生成报表的java工具 - 贪吃蛇学院-专业IT技术平台...

    ps:看到有同学问了一下问题,做一下答复,该实现不是web项目,大家只需要将代码集成到web项目中即可,原项目太大,不便上传.还有 jar包自己找啊 呵呵 采用easyui+jdbc+xml模板生成报 ...

  3. java ee web pdf_Java EE Web高级开发案例 PDF扫描版[69MB]

    Java EE Web高级开发案例 内容简介: <Java EE Web高级开发案例>充分体现了高等职业教育的特点,突出了理论和实践的紧密结合,以充分掌握基本技术技能和必要的基本知识为出发 ...

  4. java txt转pdf_java实现TXT自动读取转换PDF并且加密水印

    package com.pdf.test; import java.io.*; import com.lowagie.text.*; import com.lowagie.text.Font; imp ...

  5. java 图片合成pdf_java将多张图片合并转为PDF

    所需jar包:com.lowagie.text package weaver.gy.util; import java.awt.image.BufferedImage; import java.io. ...

  6. java高级教程pdf_Java高级编程实用教程中文 PDF版_IT教程网

    资源名称:Java高级编程实用教程中文 PDF版 内容简介 本书是一本介绍Java高级编程的实用教程,面向具有一定Java编程基础的开发人员.本书通过对"项目"的分析.实现和讲解, ...

  7. java doc to pdf_Java实现doc或xls转PDF

    package com.example.demo.config; import java.io.*; import com.aspose.words.*; //引入aspose-words-15.8. ...

  8. java doc转pdf_java 完美解决 ppt/pptx 转pdf 源码

    需要的pom文件 第一个先来介绍pptx转pdf public class PptxToPDFConverter extends Converter{ // private static final ...

  9. java用模板生成word(docx)文档(含动态表格)

    生成word思路 用WPS或者office编辑好word的样式,然后另存为word xml文档,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Docx. 编 ...

  10. Word制作生成html模板替换动态值为占位符使用Java转为pdf文件

    引言 最近开发遇到一个需求,公司法务给了一个word合同模板,需要替换里面的动态值为具体业务数据,然后生成pdf文件进行电子签章. 在网上找寻各种方法,发现很多都是需要特定工具,或者代码不全运行不起来 ...

最新文章

  1. etcd 笔记(04)— etcd 网关与 gRPC 网关
  2. 开机f8修复电脑步骤_电脑无法启动,屏幕显示白色小横条,怎么办?可收藏以备不时之需...
  3. LeetCode Longest Repeating Character Replacement(滑动窗口)
  4. hadoop三个配置文件的参数含义说明
  5. 其实昨天去加班也没有干什么事情,就只有3个人
  6. DataSet DataTable操作
  7. Windows下静态链接库的使用
  8. 截获android屏幕服务,如何捕获android设备屏幕内容?
  9. 【Acwing 219. 剪纸游戏】
  10. php pdo dblib,PHP DBlib PDO问题
  11. oracle删除数据释放表空间流程
  12. 收藏 | 如何撰写好一篇论文?密歇根教授《撰写高影响力论文指南》
  13. linux rzsz安装
  14. OSAL动态内存分配
  15. 模拟器搭建之二:如何搭建 MTK 6589模拟器
  16. 黑苹果HIDPI开启问题
  17. Linux环境下向github上传代码(生成token、生成本地密钥)
  18. Sicily.1059. Exocenter of a Trian(求垂心,向量旋转)
  19. 更新mysql表结构,同步数据库表结构
  20. php获取当前周得周一_php获取本周一的日期实现方法

热门文章

  1. windows清理_10款欧美流行的Windows清理软件
  2. 广东大学计算机基础教材,21世纪高等学校计算机公共基础课规划教材:大学计算机基础(第2版)...
  3. android vlc m3u8,Exoplayer播放m3u8文件Android
  4. 六自由度机械臂研究(1)- 简介, 自由度与改装
  5. 基于php的人力资源管理系统,基于thinkPHP框架的人力资源管理系统
  6. Redis——修改redis配置文件,并使配置生效
  7. 如何在ppt中生成柱状图_Excel表格数据如何生成柱状图等-EXCEL如何制作柱状图?...
  8. MultiTracker 多目标跟踪算法
  9. 计算机信息安全攻防大赛,计算机学院举办校第六届网络攻防大赛
  10. 陈丹琦组最新力作:仅需dropout两次的对比学习框架