项目在变,需求在变,不变的永远是敲击键盘的程序员.....

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 的其他属性不变,就能从容面对。

管道复制代码如下:

pubpc static void fileChannelCopy(File sources, File dest) {

try {

FileInputStream inputStream = new FileInputStream(sources);

FileOutputStream outputStream = new FileOutputStream(dest);

FileChannel fileChannepn = inputStream.getChannel();//得到对应的文件通道

FileChannel fileChannelout = outputStream.getChannel();//得到对应的文件通道

fileChannepn.transferTo(0, fileChannepn.size(), fileChannelout);//连接两个通道,并且从in通道读取,然后写入out通道

inputStream.close();

fileChannepn.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-pght", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

overContent.beginText();

overContent.setFontAndSize(font, 10);

overContent.setTextMatrix(200, 200);

overContent.showTextApgned(Element.ApGN_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.setpneWidth(5f);

overContent.elppse(250, 450, 350, 550);

overContent.stroke();

stamper.close();

以上这篇生成PDF全攻略之在已有PDF上添加内容的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

java pdf 修改内容_生成PDF全攻略之在已有PDF上添加内容的实现方法相关推荐

  1. XCode 4.2(4.1)真机调试及生成IPA全攻略

    XCode 4.2(4.1)真机调试及生成IPA全攻略 网上有不少关于xocde3.x真机调试的文章,但鲜有xcode4.2相关的资料  .参考了一些文章,终于可以在xcode4.2上进行真机调试了, ...

  2. Xcode 5 + iOS 7免证书(iDP)真机调试与生成IPA全攻略

    Xcode 5 + iOS 7免证书(iDP)真机调试与生成IPA全攻略 文章目录 1. 创建证书 2. 修改Xcode的配置文件 3. 准备自定义的生成后脚本 4. 修改工程设置 5. 旁门左道生成 ...

  3. iPad2 iOS 5.0.1+ Xcode 4.3 免证书(iDP)开发 + 真机调试 生成IPA全攻略

        欢迎转载,请务必注明出处:本文转载自 岳生博客 http://zhyuesheng.blog.163.com     参考了国内外多篇文章,本文所述攻略在以下开发环境下验证通过.      开 ...

  4. asp功放怎么装_汽车音响安装全攻略--功放篇

    汽车音响安装全攻略--功放篇 安装功放比安装接收机或扬声器更需要一些技巧,但并不意味着不可操作.事先了解注意事项,可以减少发生故障的机率. 安 装 第一步:作好准备工作 功放与接收机间必须保持至少90 ...

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

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

  6. [iOS] Xcode 5 + iOS 7免证书(iDP)真机调试与生成IPA全攻略

    众所周知,在Xcode上开发的程序只能在模拟器中运行,如果要放到真机上则要花费99美金购买开发者证书iDP.这严重阻碍了我等草根开发者探索的脚步.写个小程序,同学间分享一下这个小小的愿望都不能满足,自 ...

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

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

  8. Xcode 4.1/4.2/4.3/4.4/4.5 + iOS 5.1.1免证书(iDP)开发+真机调试+生成IPA全攻略

     开发环境使用的是目前为止最新的稳定版软件:Mac OS X Lion 10.7 + Xcode 4.1 目前Xcode 4.2 Preview版也已经发布,据说其修改方法跟4.1非常类似,只改动 ...

  9. python整数预测_时间序列预测全攻略(附带Python代码) | 36大数据

    介绍 时间序列(简称TS)被认为是分析领域比较少人知道的技能.(我也是几天前才知道它).但是你一定知道最近的小型编程马拉松就是基于时间序列发展起来的,我参加了这项活动去学习了解决时间序列问题的基本步骤 ...

最新文章

  1. Spring Cloud Greenwich版本已发布!
  2. [转]C++ 使用Makefile文件
  3. 命令行 sc delete 的使用(删除服务项)
  4. Python初识与简介【开篇】
  5. 有这个OCR程序,不用再买VIP了,Python 调用百度OCR API
  6. 尼日利亚年轻人推动该国登上比特币谷歌搜索排名榜首
  7. python提取日志内容_Python正则提取日志内容
  8. 图片放大像素模糊怎么变清晰?
  9. vue实战 —— 图书商城移动端项目
  10. 全球最顶级的十大创新公司
  11. U盘中毒乱码文件还能恢复吗?u盘中毒文件乱码怎么恢复?
  12. js html body onload,动态添加页面body OnLoad事件的简单js代码
  13. Android之ubuntu源码开发环境搭建笔记
  14. 单波段彩色变换(伪彩色密度分割)
  15. Licode—基于webrtc的SFU/MCU实现
  16. C语言《位段结构体、联合体》
  17. Linux下多显示器触屏调试与暂行解决方案
  18. kali linux 入门(1) 基于win10和docker的环境搭建
  19. 绵阳市谷歌高清卫星地图下载
  20. 解决NPM下载速度贼慢的方法

热门文章

  1. vite、vue3警告:Component inside <Transition> renders non-element root node that cannot be animated.
  2. 【解决方案】国标GB28181视频监控平台国标流媒体服务器EasyGBS如何实现安保行业日常巡查视频监控系统解决方案?
  3. find()和findIndex()区别和用法
  4. 系统服务器与手机关系,手机与云服务器交互
  5. iOS屏幕旋转及其基本适配方法
  6. 8个有用的表单构建工具,你一定要使用并收藏好
  7. 【Java多线程】(四)线程间通信
  8. 女性bmi计算器JAVA代码_简单的BMI计算器
  9. 拼多多店铺昨天还好好的,今天突然没流量,怎么回事?
  10. 2022 IDEA全家桶使用最新主题(免申请)