利用Java动态生成 PDF 文档
利用Java动态生成 PDF 文档,则需要开源的API。首先我们先想象需求,在企业应用中,客户会提出一些复杂的需求,比如会针对具体的业务,构建比较典型的具备文档性质的内容,一般会导出PDF进行存档。那么目前最佳的解决方案,你可能会想到 iText ,对没错。。。 iText+(Velocity / Freemarker)可以实现。不过据我熟悉,iText本身提供的HTML解析器还是不够强大,许多HTML标签和属性无法识别,更悲催的是简单的CSS它不认识,排版调整样式会让你头大的。不要失望,接下来我就来介绍一个比较理想的解决方案 flying-saucer + iText + (Velocity / Freemarker)。
大家都知道 iText 是一个生成PDF文档的开源Java库,能够动态的从XML或者数据库生成PDF,同时还可以对文档进行加密,权限控制,甭且还支持Java/C#等。。。
flying-saucer也是导出PDF的一种解决方案并且是基于iText的开源API,并且实现了CSS解析器,能够很好的支持CSS2.1,以及少量的CSS3 生成PDF解决方案: Flying-Saucer + iText + Velocity
1. 第一步
将jar包放到你的工程里,需要的jar如下: bcprov-jdk15-140.jar
core-renderer.jar
iText-2.0.8.jar
iTextAsian.jar
velocity-1.4.jar Jar包下载地址:http://code.google.com/p/flying-saucer/downloads/list
2. 第二步
设计模版,进行排版调整样式,css样式也可以导入@import 等,通过Velocity模版引擎动态替换 页面内容,以下是模版内容:
<?xml version="1.0" encoding="UTF-8" ?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>PDF模版</title>
<style type="text/css">
<!--
body {
font: 100% Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
text-align: center;
color: #000000;
}
.oneColLiqCtrHdr #container {
width: 100%;
margin: 0 auto;
text-align: left;
}
div.header-left {display: none}
div.header-right {display: none}
div.footer-left {display: none}
div.footer-right {display: none}
@media print {
div.header-left {
display: block;
position: running(header-left);
}
div.header-right {
display: block;
position: running(header-right);
}
div.footer-left {
display: block;
position: running(footer-left);
}
div.footer-right {
display: block;
position: running(footer-right);
}
}
@page {
margin: 0.65in;
padding: 1em;
@top-left{
content:element(header-left);
};
@top-right {
content: element(header-right)
};
@bottom-left {
content: element(footer-left)
};
@bottom-right {
content: element(footer-right)
};
}
#pagenumber:before {
content: counter(page);
}
#pagecount:before {
content: counter(pages);
}
.tbClass {
width:100%;height:100%;
border-left:1px #000000 solid;
border-bottom:1px #000000 solid
}
.tbClass td {
border-top:1px #000000 solid;
border-right:1px #000000 solid
}
@page landscape{
size:841.9pt 595.3pt;
mso-page-orientation:landscape;
margin:89.85pt 72.0pt 89.85pt 72.0pt;
mso-header-margin:42.55pt;
mso-footer-margin:49.6pt;
mso-paper-source:0;
layout-grid:15.6pt;
}
div.landscape{
page:landscape;
}
@page portrait{
size:595.3pt 841.9pt;
margin:36.0pt 36.0pt 36.0pt 36.0pt;
mso-header-margin:42.55pt;
mso-footer-margin:49.6pt;
mso-paper-source:0;
layout-grid:16.3pt 0pt;
mso-layout-grid-char-alt:0;
}
div.portrait{
page:portrait;
}
-->
</style>
</head>
<body class="oneColLiqCtrHdr">
<div id="container">
<div id="header">
<!--***************页眉_start*****************-->
<div id="header-left" class="header-left" align="left">
页眉左侧
</div>
<div id="header-right" class="header-right">
页眉右侧
</div>
<!--***************页眉_end*****************-->
</div>
<div id="footer">
<!--***************页脚_start*****************-->
<div id="footer-left" class="footer-left" align="left">
页脚左侧
</div>
<div id="footer-right" class="footer-right" align="right">
页脚右侧
</div>
<!--***************页脚_endt*****************-->
</div>
<div id="mainContent">
<!-- start #mainContent -->
<div>内容1</div>
<div class="portrait" style="page-break-after:always"><!--分页-->
<div>内容2</div>
<div class="portrait" style="page-break-after:always"><!--分页-->
<div class="landscape">内容3 横向显示</div>
<!-- end #mainContent -->
</div>
</div>
</body>
</html>
3. 模版与业务数据整合
@SuppressWarnings("unchecked")
//打印业务数据对象baseInfo
public void getPdf(BASEINFO baseInfo) throws Exception{ String sysurl = PdfBO.class.getProtectionDomain().getCodeSource().getLocation().getPath();
sysurl = sysurl.substring(0,sysurl.indexOf("WEB-INF/",0));
sysurl = java.net.URLDecoder.decode(sysurl, "UTF-8");
//首先创建一个模板引擎的实例
VelocityEngine engine = new VelocityEngine();
//模版路径
String tempath = sysurl+"\\pdf\\template";
//设置参数
engine.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, tempath);
engine.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
engine.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
//初始化
engine.init();
//获得模板
Template template = engine.getTemplate("template.html");
//创建上下文,填充数据
VelocityContext context = new VelocityContext();
context.put("baseInfo",baseInfo);
PrintUtils pdfUtil = new PrintUtils();
context.put("PrintUtils", pdfUtil);
//现在,把模板和数据合并,输出到Writer
String vmpath = sysurl + "\\pdf\\template\\a.html";
Writer writer = new PrintWriter(new FileOutputStream(new File(vmpath)));
template.merge(context,writer);
writer.flush();
//生成PDF电子文档
String sysurl = PdfBO.class.getProtectionDomain().getCodeSource().getLocation().getPath();
sysurl = sysurl.substring(0,sysurl.indexOf("WEB-INF/",0));
sysurl = java.net.URLDecoder.decode(sysurl, "UTF-8");
//转换的文档路径
String inFileUrl = sysurl + "\\pdf\\template\\a.html";
String url = new File(inFileUrl).toURI().toURL().toString();
//转换后PDF文件的输出路径
String outFile_url_ = sysurl + "\\pdf\\doc\\a.pdf";
OutputStream output = new FileOutputStream(outFile_url_);
//实例ITextRenderer,加载html文档
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
//支持中文
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont("C:/Windows/Fonts/ARIALUNI.TTF",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//PDF页眉图片路径
renderer.getSharedContext().setBaseURL("file:"+sysurl+"\\images\\a.gif");
renderer.layout();
renderer.createPDF(output);
output.close();
PdfReader reader = new PdfReader(outFile_url_);
// 加水印后PDF文件输出路径
String filePath_stamper = sysurl + "\\pdf\\doc\\my.pdf";
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(filePath_stamper));
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB- UCS2-H",BaseFont.NOT_EMBEDDED);
int total = reader.getNumberOfPages() + 1;
//水印图片的路径
String imageFilePath = sysurl + "\\images\\b.gif";
Image image = Image.getInstance(imageFilePath);
image.setAbsolutePosition(20, 50);
image.scalePercent(50);
PdfContentByte under;
for (int i = 1; i < total; i++) {
under = stamper.getUnderContent(i);
under.addImage(image);
under.beginText();
under.setColorFill(Color.CYAN);
under.setFontAndSize(base, 30);
under.endText();
}
stamper.close();}
}
5、生成PDF完成
利用Java动态生成 PDF 文档的更多相关文章
- 手把手教你使用 Java 在线生成 pdf 文档
一.介绍 在实际的业务开发的时候,研发人员往往会碰到很多这样的一些场景,需要提供相关的电子凭证信息给用户,例如网银/支付宝/微信购物支付的电子发票.订单的库存打印单.各种电子签署合同等等,以方便用户查 ...
- [转载]Java动态生成word文档(图文并茂)
很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功 ...
- [原创]Java动态生成word文档(图文并茂)
很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功 ...
- 自动把动态的jsp页面(或静态html)生成PDF文档,并且上传至服务器
置顶2017年11月06日 14:41:04 阅读数:2311 这几天,任务中有一个难点是把一个打印页面自动给生成PDF文档,并且上传至服务器,然而公司框架只有手动上传文档,打印时可以保存为PDF在本 ...
- qt 利用 HTML 生成PDF文档,不能显示jpg图片
利用 QPrinter 和html 生成 pdf文档 其中用html语句有显示图片的语句 但只能显示png格式的图片,不能显示jpg格式图片. 经过排查:语法,文件路径等都正确,最终在stack ov ...
- Java 动态生成 PDF 文件
每片文章前来首小诗: 今日夕阳伴薄雾,印着雪墙笑开颜.我心仿佛出窗前,浮在半腰望西天. --泥沙砖瓦浆木匠 需求: 项目里面有需要java动态生成 PDF 文件,提供下载.今天我找了下有关了,系 ...
- Spring Boot集成JasperReports生成PDF文档
由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲染生成PDF文档.本人文采欠缺,写作能力 ...
- 使用PHP生成PDF文档
原文:使用PHP生成PDF文档 实际工作中,我们要使用PHP动态的创建PDF文档,目前有许多开源的PHP创建PDF的类库,今天我给大家来介绍一款优秀的PDF库,它就是TCPDF,TCPDF是一个用于快 ...
- C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例
C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...
随机推荐
- Maven常用命令
开发中常用的命令: 1. mvn compile 编译源代码2. mvn test-compile 编译测试代码3. mvn test 运行测试4. mvn package 打包,根据pom.xml打 ...
- 敏捷转型历程 - Sprint3 Grooming
我: Tech Leader 团队:团队成员分布在两个城市,我所在的城市包括我有4个成员,另外一个城市包括SM有7个成员.另外由于我们的BA离职了,我暂代IT 的PO 职位.PM和我在一个城市,但他不 ...
- SVN的使用
- Microsoft Visual Studio 2015 下载、注册、安装过程、功能列表、问题解决
PS:请看看回复.可能会有文章里没有提到的问题.也许会对你有帮助哦~ 先上一张最终的截图吧: VS2015正式版出了,虽然没有Ultimate旗舰版,不过也是好激动的说.哈哈.可能有的小伙伴,由于工作 ...
- 烂泥:VMWare Workation双网卡配置IP地址
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前几天给一个客户做远程项目实施,客户那边的服务器是Windows OS的,我们这边的业务 ...
- Spring mvc @initBinder 类型转化器的使用
一.单日期格式 因为是用注解完完成的后台访问,所以必须在大配置中配置包扫描器: 1.applicactionContext.xml <?xml version="1.0" e ...
- Vim新手入门资料和一些Vim实用小技巧
一些网络上质量较高的Vim资料 从我07年接触Vim以来,已经过去了8个年头,期间看过很多的Vim文章,我自己觉得非常不错,而且创作时间也比较近的文章有如下这些. Vim入门 目前为阿里巴巴高级技术专 ...
- linux笔记
1 动态查看日志 tail -f filename tail -1000f filename 2 解压当前目录内容为xxx.zip zip -r xxx.zip ./* 3 查看内存使用情况 fre ...
- seajs的使用
写在前面 seajs是什么? Seajs是一个js文件加载器. 遵循 CMD 规范模块化开发,依赖的自动加载.配置的简洁清晰. 用于Web开发的模块加载工具,提供简单.极致的模块化体验 一:使用 文件 ...
- join和split的区别
join() 方法用于把数组中的所有元素放入一个字符串.元素是通过指定的分隔符进行分隔的. <script> var a=new Array(); a[0]="XHTML&quo ...