生成 PDF 全攻略【2】在已有PDF上添加内容
项目在变,需求在变,不变的永远是敲击键盘的程序员.....
PDF 生成后,有时候需要在PDF上面添加一些其他的内容,比如文字,图片....
经历几次失败的尝试,终于获取到了正确的代码书写方式。
在此记录总结,方便下次以不变应万变,需要的 jar 请移步:生成PDF全攻略
PdfReader reader = new PdfReader("E:\\A.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\\B.pdf"));
PdfContentByte overContent = stamper.getOverContent(1);
上述的这段代码算是在原有 PDF 上面添加内容的核心代码,具体流程如下
- 如果看官老爷够仔细的话,该代码是将原 A.pdf 读取,然后将它写入 B.pdf,然后操作 B.pdf。
- 可能有的看官老爷会说,将 A 读取,然后在写入 A 中,这样肯定是不行的,在读取的时候 A 已经被加载了,不能进行修改。
- 我不喜欢这种方式,因为原 PDF 的信息已经存储在数据库中,其中包括 PDF 的服务器路径、旧名称、新名称、类型......
- 这样就会多出一次数据库变更操作,因为这里PDF名称需要变更,而且鬼知道后续需求还会怎么变。
- 这里急需 只在 PDF 中添加内容,其他的什么都不变,将代码稍微调整了一下。
FileUtil.fileChannelCopy(A.pdf,A + "tmp".pdf));
PdfReader reader = new PdfReader(A + "tmp".pdf);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(A.pdf));
PdfContentByte overContent = stamper.getOverContent(1);
代码流程就变做下面这个样子
- 这里引入了管道复制文件,将A 复制一份,读取副本,然后写回到原 PDF A 中,最后当然需要删除副本文件。
- 到这里,无论后续需求怎么变,保证了pdf 的其他属性不变,就能从容面对。
管道复制代码如下:
public static void fileChannelCopy(File sources, File dest) {
try {
FileInputStream inputStream = new FileInputStream(sources);
FileOutputStream outputStream = new FileOutputStream(dest);
FileChannel fileChannelin = inputStream.getChannel();//得到对应的文件通道
FileChannel fileChannelout = outputStream.getChannel();//得到对应的文件通道
fileChannelin.transferTo(0, fileChannelin.size(), fileChannelout);//连接两个通道,并且从in通道读取,然后写入out通道 inputStream.close();
fileChannelin.close();
outputStream.close();
fileChannelout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
完整的在已有PDF添加其他内容代码如下:
FileUtil.fileChannelCopy(new File("E:\\A.pdf"),new File("E:\\A+"tmp".pdf"));
PdfReader reader = new PdfReader("E:\\A+"tmp".pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("E:\\A.pdf"));
PdfContentByte overContent = stamper.getOverContent(1); //添加文字
BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
overContent.beginText();
overContent.setFontAndSize(font, 10);
overContent.setTextMatrix(200, 200);
overContent.showTextAligned(Element.ALIGN_CENTER,"需要添加的文字",580,530,0);
overContent.endText(); //添加图片
PdfDictionary pdfDictionary = reader.getPageN(1);
PdfObject pdfObject = pdfDictionary.get(new PdfName("MediaBox"));
PdfArray pdfArray = (PdfArray) pdfObject;
Image image = Image.getInstance("D:\\1.jpg");
image.setAbsolutePosition(100,100);
overContent.addImage(image); //添加一个红圈
overContent.setRGBColorStroke(0xFF, 0x00, 0x00);
overContent.setLineWidth(5f);
overContent.ellipse(250, 450, 350, 550);
overContent.stroke();
stamper.close();
生成 PDF 全攻略【2】在已有PDF上添加内容的更多相关文章
- 生成 PDF 全攻略【1】初体验
经历过多少踩坑,翻看过多少类似博客,下载过多少版本的Jar,才能摸索出正确的代码书写方式,才能实现项目经理需求分析书中的功能点. 本文借一次 JavaEE 生成PDF的颠簸的实现过程,描述中小公司程序 ...
- Xcode 4.1~4.6 + iOS 5、iOS 6免证书(iDP)开发+真机调试+生成IPA全攻略
原创文章,欢迎分享:未经许可,不得转载:版权所有,侵权必究 开发环境使用的是目前为止最新的稳定版软件:Mac OS X Lion 10.7 + Xcode 4.1 目前Xcode 4.2 Previe ...
- Windows Socket五种I/O模型——代码全攻略(转)
Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操 ...
- 用C#制作PDF文件全攻略
用C#制作PDF文件全攻略 目 录 前 言... 3 第一部分 iText的简单应用... 4 第一章 创建一个Document 4 第一步 创建一个Document实例:... 5 第二步 ...
- 取代奶瓶Minidwep-gtk破解WPA 全攻略
取代奶瓶Minidwep-gtk 破 WPA 全攻略 目录 1. CDlinux 下使用 minidwepgtk 获取握手包并使用自带的字典破解 2. 自带的字典破解不出密码时使用 U 盘外挂字典继 ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
- Moon.Orm3.8技术全攻略
Moon.ORM技术全攻略 一.绪论 本文主要是针对Moon.ORM的技术的讨论及其使用使用指导.如有其它疑问,请留言.本文主要针对Moon.ORM3.9版本,同时将会对4.0做一个技术预览.本文从 ...
- MyEclipse优化全攻略
(0) 吐槽 Eclipse仅仅是个半成品有木有?什么都须要自己安装插件,新手非常难用有木有? 安装上插件以后了版本号兼容和各种问题烦死人有木有? 都怪碎片和版本号乱公布有木有? IntelliJ I ...
- VSCode插件开发全攻略(六)开发调试技巧
更多文章请戳VSCode插件开发全攻略系列目录导航. 前言 在介绍完一些比较简单的内容点之后,我觉得有必要先和大家介绍一些开发中遇到的一些细节问题以及技巧,特别是后面一章节将要介绍WebView的知识 ...
随机推荐
- nth-child和:nth-of-type的区别
:nth-of-type为什么要叫:nth-of-type?因为它是以"type"来区分的.也就是说:ele:nth-of-type(n)是指父元素下第n个ele元素, 而ele: ...
- Android中的AlertDialog使用示例一(警告对话框)
在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,AlertDialog实现方法为建造者模式. ...
- IOS开发基础知识--碎片25
1:使用@protocol实现delegate和datasource模式 #import <UIKit/UIKit.h> @protocol MyViewDataSource,MyView ...
- IT软件人员的技术学习内容(写给技术迷茫中的你) - 项目管理系列文章
前面笔者曾经写过一篇关于IT从业者的职业道路文章(见笔者文:IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章).然后有读者提建议说写写技术方面的路线,所以就有了本文.本文从初学者到思想 ...
- Spring 4 集成Apache CXF开发JAX-RS Web Service
什么是JAX-RS 在JSR-311规范中定义,即Java API for RESTful Web Services,一套Java API,用于开发 RESTful风格的Webservice. 工程概 ...
- SQL Server 监控统计阻塞脚本信息
数据库产生阻塞(Blocking)的本质原因 :SQL语句连续持有锁的时间过长 ,数目过多, 粒度过大.阻塞是事务隔离带来的副作用,它是不可避免的,而且是一个数据库系统常见的现象. 但是阻塞的 ...
- StarkSoft题库管理系统(二)--生成word格式试卷
一.功能介绍 1.自定义试题库管理系统目录.难易程度,题型,知识库等. 2.试题录入. 3.强大的试题编辑功能,并与通常应用编辑工具有共通. 4.灵活的试卷构造功能,用户可自定 ...
- Openstack基本命令
Openstack有数量众多的命令行工具(CLI),用来执行各式各样的管理任务,例如VM管理.存储管理.网络管理.本文描述用Openstack CLI工具执行如下任务: 设置环境变量 使用内置帮助 创 ...
- [iOS]坑爹的ALAsset(Assets Library Framework)
Assets Library Framework 可以用来做iOS上的多选器,选照片视频啥的啦就不介绍了. 目前的项目有点类似dropbox,可以选择设备内的照片然后帮你上传文件,使用了Assets ...
- linux下使用denyhosts防止ssh暴力破解
1.DenyHosts介绍 DenyHosts是Python语言写的一个程序,它会分析sshd的日志文件(/var/log/secure),当发现重 复的攻击时就会记录IP到/etc/hosts.de ...