经历过多少踩坑,翻看过多少类似博客,下载过多少版本的Jar,才能摸索出正确的代码书写方式,才能实现项目经理需求分析书中的功能点。

本文借一次 JavaEE 生成PDF的颠簸的实现过程,描述中小公司程序员的坎坷成长之路。

俺上面只所以将成熟大公司排除在外的原因是,大公司一般都有成熟的产品线和技术积淀。

至少会有完善的建构师团队,有像扫地神僧那样的牛人隐士......

公司中初级程序员遇到问题,能找到以前实现过的类似功能的代码作为参照,也能咨询技术经理。

小公司是没有这种福分的,就像昨天早晨"生成PDF"需求到,工期一天,明日要给客户看。

第一反应是找谷歌,关键字 "Java生成PDF",博客不是一般的多,下面简述几种实现方式和实现过程中遇到的问题。

(目录已列在上面,通过搜索引擎进来的小伙伴,看看上面列表中是否有能解决你问题的,有点到相应的小节,没有就关闭看下一条搜索记录吧....)

1.IText 生成复杂PDF

谷歌中占比例最大的Java 生成PDF实现类库,也是许多技术博客中涉及到技术,官网:http://itextpdf.com/

开源中国中的介绍:http://www.oschina.net/p/itext,好嘞,既然都推荐那就采用这类库看看。

下载 Jar 也是琳琅满目,让你挑花眼,从 2.1--5.5 应有尽有,有些论坛下载东西还需要注册o(︶︿︶)o 唉。

这里采用的是最新的版本 5.5,仔细阅读下别人的技术博客或者是官方文档,编码起来确实不是很费劲。笔者将业务抽象实现的类如下:

public class createSimplePDF {
private Font FontChinese;
public void simplePDF() {
try {
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
FontChinese = new Font(bfChinese, 12, Font.NORMAL);
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("F:\\Garbage\\Hello simplePDF.pdf"));
document.open(); PdfPTable table = new PdfPTable(4);
table.addCell(getCell("姓名", 1, 1));
table.addCell(getCell("", 1, 1));
table.addCell(getCell("编号", 1, 1));
table.addCell(getCell("", 1, 1)); table.addCell(getCell("部门", 1, 1));
table.addCell(getCell("", 1, 1));
table.addCell(getCell("岗位名称", 1, 1));
table.addCell(getCell("", 1, 1)); table.addCell(getCell("到职日期", 1, 1));
table.addCell(getCell("", 1, 1));
table.addCell(getCell("预定离职日期", 1, 1));
table.addCell(getCell("", 1, 1)); table.addCell(getCell("事由", 1, 3));
table.addCell(getCell("", 3, 3)); table.addCell(getCell("部门意见", 1, 3));
table.addCell(getCell("", 3, 3));
document.add(table);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
} private PdfPCell getCell(String cellValue, int colspan, int rowSpan) {
PdfPCell cell = new PdfPCell();
try {
cell = new PdfPCell(new Phrase(cellValue, FontChinese));
cell.setRowspan(rowSpan);
cell.setColspan(colspan);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
} catch (Exception e) {
e.printStackTrace();
}
return cell;
}
}

2.IText添加对中文的支持

愉快的将代码编写完成,生成后中文不见了,注意是不见了,不是乱码。

仔细观察报错,发现IText需要添加另外itext-asian.jar去支持中文,那就添加吧。

因为自己IText使用的是最新的5.5版本,导致其他低版本的 itext-asian.jar 无法支持(具体原因是5.0以上的itext包名发生了变化),抛出的错误如下:

Font 'STSong-Light' with 'UniGB-UCS2-H' is not recognized

最终在一篇博客中寻获解决方法,尝试后奏效,就是上述代码中:

 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
FontChinese = new Font(bfChinese, 12, Font.NORMAL);

笔者这里将最新的IText.jar 和 配套的中文支持  itext-asian.jar,放置百度云盘,节省其他同学找 Jar 时间。

云盘地址:http://pan.baidu.com/s/1bqs4km  提取密码: 99eg

最终实现的截图如下:

其实项目中最终要实现的表格的样子比这个复杂的多,80%花费时间主要是在调整样式,编译输出--->看样式,到这里其实需求已经能够实现了。

笔者也是用这种方式实现的,毕竟是给客户演示的。

这里要感谢的是这位博主的博客,里面有详细的IText 设置段落,标题,表格,加密..........只要你能在生成PDF想到的,这里面基本上都有。

博客地址:http://rensanning.iteye.com/blog/1538689

3.iTextRenderer(Flying Saucer) HTML转PDF

Flying saucer 做为HTML渲染PDF的开源项目(老外起名字我也是醉了,想起一出是一出,HTML 渲染 PDF起个"飞行器")。

其中的核心类 iTextRenderer 支持将HTML生成PDF。

iTextRenderer 在依赖 iText 的基础上,单独实现了HTML渲染PDF,基本上能实现 CSS 2.1的整体性,并且完全符合 W3C 规范。

如果采用这种方式,编译输出调整样式什么的,就让它见鬼去吧。

具体的流程如下图:

这才是高大上的解决方案有木有,模版引擎现在也是玲琅满目(freemark,velocity.......),具体看你们项目吧。

这样就不用为繁琐的样式发愁了,定义模版前端查看,注入数据,生成PDF,核心代码:

                ITextRenderer iTextRenderer = new ITextRenderer();
iTextRenderer.getFontResolver().addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
iTextRenderer.setDocument(new File(currWebcontentPath + reviewHtmlPath).toURI().toString());
iTextRenderer.layout();
String pdfName = getPdfName(testVO);
OutputStream fileOutputStream = new FileOutputStream(currWebcontentPath + pdfPath + pdfName);
iTextRenderer.createPDF(fileOutputStream);
iTextRenderer.finishPDF();

这里面需要解决的问题还有生成的HTML存放的位置,然后就是跳转到下载页面了,如果你是JavaEE后端开发,这些问题应该都难不到你。

使用的iTextRenderer的jar同样也放到: http://pan.baidu.com/s/1kTOpM0R  提取密码: y9y2

具体参考的博客有:

http://www.tuicool.com/articles/qAFNFja

http://downpour.iteye.com/blog/509417

http://my.oschina.net/u/603602/blog/268611?fromerr=bxBuHc6W

生成 PDF 全攻略【1】初体验的更多相关文章

  1. 生成 PDF 全攻略【2】在已有PDF上添加内容

    项目在变,需求在变,不变的永远是敲击键盘的程序员..... PDF 生成后,有时候需要在PDF上面添加一些其他的内容,比如文字,图片.... 经历几次失败的尝试,终于获取到了正确的代码书写方式. 在此 ...

  2. Xcode 4.1~4.6 + iOS 5、iOS 6免证书(iDP)开发+真机调试+生成IPA全攻略

    原创文章,欢迎分享:未经许可,不得转载:版权所有,侵权必究 开发环境使用的是目前为止最新的稳定版软件:Mac OS X Lion 10.7 + Xcode 4.1 目前Xcode 4.2 Previe ...

  3. 用C#制作PDF文件全攻略

    用C#制作PDF文件全攻略 目  录 前    言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...

  4. 取代奶瓶Minidwep-gtk破解WPA 全攻略

    取代奶瓶Minidwep-gtk 破 WPA 全攻略  目录 1. CDlinux 下使用 minidwepgtk 获取握手包并使用自带的字典破解 2. 自带的字典破解不出密码时使用 U 盘外挂字典继 ...

  5. VS2013全攻略(安装,技巧,快捷键,插件)!

    工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)! 之前一篇<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥>承蒙大家喜爱和编辑推荐,在此 ...

  6. 裸眼3D全攻略3:拍摄3D—瞳距、镜距、视角偏转与空间感

    http://sd89.blog.163.com/blog/static/356041322014112532958728/ 3D图片的拍摄,与平面有着全新的不同要求,那就是空间感的表现. 简单来说, ...

  7. Android屏幕适配全攻略(最权威的官方适配指导)屏幕尺寸 屏幕分辨率 屏幕像素密度 dpdipdpisppx mdpihdpixdpixxdpi

    Android屏幕适配全攻略(最权威的官方适配指导)原创赵凯强 发布于2015-05-19 11:34:17 阅读数 153734 收藏展开 转载请注明出处:http://blog.csdn.net/ ...

  8. 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法

    若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...

  9. 从小工到专家 ——读《Java程序员职场全攻略》有感

    从小工到专家 ——读<Java程序员职场全攻略>有感   <Java程序员职场全攻略>是以故事的形式,向读者介绍Java程序员的职场经验.作者牛开复在北京从事软件开发,已经是一 ...

随机推荐

  1. (ios)MPMoviePlayerController首次播放视频的时候,没有控制条

    问题: 在视频播放时,现在控制条采用磨砂的效果,会遮罩部分视频 解决思路 1 播放器直接设置不带控制条,在app在 Foreground状态,默认播放器暂停,这样需要在获得Foreground事件,进 ...

  2. 简单看看这两个类 String和StringBuilder

    我记得以前在园子里面讨论这两个类的文章有很多很多,并且还拿出了很多的测试报告,在什么情况下,谁比谁快,在什么情况下,该用谁 不该用谁等等这些,我这里就不比较了,我就简单看看他们里面的内部实现,那就先看 ...

  3. HTML5游戏开发引擎,初识CreateJS

    CreateJS为CreateJS库,可以说是一款为HTML5游戏开发的引擎.打造 HTML5 游戏,构建新游戏,提供构建最新 HTML5 的技术.你可以通过这个网站学习如何构建跨平台和跨终端游戏.这 ...

  4. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

  5. 数据结构杂谈(二)简单有趣的地精排序Gnome sort

    很早之前便听说过地精排序的名字,今天自己看来一下,发现这是一种非常简单而且有趣的排序算法. 为什么叫地精排序? 地精排序在2000年由Dr. Hamid Sarbazi-Azad 提出的时候被称作 s ...

  6. 高性能MySQL笔记 第5章 创建高性能的索引

    索引(index),在MySQL中也被叫做键(key),是存储引擎用于快速找到记录的一种数据结构.索引优化是对查询性能优化最有效的手段.   5.1 索引基础   索引的类型   索引是在存储引擎层而 ...

  7. linux运维常用命令及知识

    1.查找当前目录下所有以.tar结尾的文件然后移动到指定目录: find . -name “*.tar” -exec mv {} ./backup/ ; 查找当前目录30天以前大于100M的LOG文件 ...

  8. [转]学习Nop中Routes的使用

    本文转自:http://www.cnblogs.com/miku/archive/2012/09/27/2706276.html 1. 映射路由 大型MVC项目为了扩展性,可维护性不能像一般项目在Gl ...

  9. SSH 整合及注意事项

    Spring 整合 hibernate 配置 1. spring 配置管理datasource 及 sessionFactory 1) 引入相关jdbc配置文件. <context:proper ...

  10. WPF学习笔记(一):数据绑定之元素到元素绑定

    前言 作为一只菜鸟,之前学了一段时间的WPF,但是没有总结,过了一学期发现好多东西都忘记了,很多东西还是需要记下来,以备后续复习. 数据绑定在事件中应用非常广泛,可以有效地减少代码量,那么什么是数据绑 ...