文章目录

  • 需求
  • 解决方案一
  • 解决方案二

需求

客户希望在 PDF 文件上,借助手写板完成签名操作,其中手写板是个可以把签名转成图片的的硬件,硬件部分由于来源繁多,此处略过,默认已经拿到图片签名。

解决方案一

问题的本质是需要在 PDF 文件上,在指定的坐标位置或者提前定义的关键字处,插入图片,可以使用 Aspose.PDF for Java 来实现。实现的代码如下:

  • model层
@Data
@ApiModel("pdf插入图片入参")
public class AddImageInPdfModel implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "待处理的pdf文件地址")private String pdfFilePath;@ApiModelProperty(value = "插入的base64图片")private String base64Pic;@ApiModelProperty(value = "第几页需要插入图片")private int pageNum;@ApiModelProperty(value = "底部x坐标")private float lowerLeftX;@ApiModelProperty(value = "底部y坐标")private float lowerLeftY;@ApiModelProperty(value = "第几个关键字位置需要插入图片", hidden = true)private int keywordNum;@ApiModelProperty(value = "关键字")private String keyword;@ApiModelProperty(value = "关键字位置:1-顺数 2-倒数", hidden = true)private int keywordType;
}
  • controller层
 @PostMapping("/addImageInPdf")@ApiOperation(value = "pdf插入图片", notes = "pdf插入图片")public ResultBean<String> addImageInPdf(@ApiParam(value = "pdf插入图片入参", required = true)@RequestBody AddImageInPdfModel addImageInPdfModel) {try {log.info("pdf插入图片入参:{}", addImageInPdfModel);String newPdfFilePath = pdfConvertService.addImageInPdf(addImageInPdfModel);return ResultBean.ok(newPdfFilePath);}catch (Exception e) {log.error("pdf插入图片失败:{}", e.getMessage(), e);return ResultBean.fail("pdf插入图片失败:" + e.getMessage());}}
  • service层
import com.aspose.pdf.TextFragment;
import com.aspose.pdf.TextFragmentAbsorber;
import com.aspose.pdf.TextFragmentCollection;
import com.aspose.pdf.facades.PdfFileMend;......public String addImageInPdf(AddImageInPdfModel addImageInPdfModel) throws Exception {String pdfFilePath = addImageInPdfModel.getPdfFilePath();PdfFileMend mender = new PdfFileMend();mender.bindPdf(pdfFilePath);// 将图片写到磁盘String imgDir = FileConfigConstant.ROOT_PATH + "writSign" + File.separator + "picture" + AttachmentUtil.createUploadFileSavePath();Files.createDirectories(Paths.get(imgDir));String imgName = IdUtil.simpleUUID() + ".png";String imgPath = FilePathUtil.joinPath(imgDir, imgName);log.info("pdf插入的图片地址:{}", imgPath);BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(imgPath));BufferedImage bufferedImage = ImgUtil.toImage(addImageInPdfModel.getBase64Pic());float picHeight = bufferedImage.getHeight();float picWidth = bufferedImage.getWidth();log.info("图片高度:{}", picHeight);log.info("图片宽度:{}", picWidth);boolean pic = ImageIO.write(bufferedImage, "png", new File(imgPath));if(pic == false){log.info("转换失败");}String keyword = addImageInPdfModel.getKeyword();if (StringUtils.isNotBlank(keyword)){//关键字签章if (NumConstant.INT_ZERO == addImageInPdfModel.getKeywordNum()){List<float[]> positions = PdfKeywordFinder.findKeywordPostions(pdfFilePath, keyword);if (positions != null && positions.size() > 0) {for (float[] position : positions) {System.out.print("pageNum: " + (int) position[0]);System.out.print("\tx:" + position[1]);System.out.println("\ty: " + position[2]);int pageNum = (int)position[0];float lowerLeftX = position[1];float lowerLeftY = position[2];float upperRightX = lowerLeftX + picWidth;float upperRightY = lowerLeftY + picHeight;mender.addImage(imgPath, pageNum, lowerLeftX, lowerLeftY, upperRightX, upperRightY);}}}else {float[] positions = PdfKeywordFinder.getAddImagePositionXY(pdfFilePath, keyword, addImageInPdfModel.getKeywordNum(), addImageInPdfModel.getKeywordType());int pageNum = (int)positions[0];float lowerLeftX = positions[1];float lowerLeftY = positions[2];float upperRightX = lowerLeftX + picWidth;float upperRightY = lowerLeftY + picHeight;log.info("插入图片的位置,lowerLeftX:{},lowerLeftY:{},upperRightX:{},upperRightY:{}", lowerLeftX, lowerLeftY, upperRightX, upperRightY);mender.addImage(imgPath, pageNum, lowerLeftX, lowerLeftY, upperRightX, upperRightY);}}else {//位置签章float lowerLeftX = addImageInPdfModel.getLowerLeftX();float lowerLeftY = addImageInPdfModel.getLowerLeftY();float upperRightX = lowerLeftX + picWidth;float upperRightY = lowerLeftY + picHeight;log.info("插入图片的位置,lowerLeftX:{},lowerLeftY:{},upperRightX:{},upperRightY:{}", lowerLeftX, lowerLeftY, upperRightX, upperRightY);mender.addImage(imgPath, addImageInPdfModel.getPageNum(), lowerLeftX, lowerLeftY, upperRightX, upperRightY);}//构造新的pdf文件路径String newPdfFilePath = pdfFilePath.replace(FileUtil.mainName(pdfFilePath), IdUtil.simpleUUID() + "_publicSign-" + DateUtil.currentSeconds());log.info("签名后的pdf文件路径:{}", newPdfFilePath);mender.save(newPdfFilePath);out.close();mender.close();return newPdfFilePath;}

解决方案二

也可以使用 itext 库对 PDF 进行关键字签名操作,参考地址如下:
使用itext对pdf指定文字位置插入图片

三分钟带你玩转PDF文件签名相关推荐

  1. 三分钟带你玩转直播带货套路,附带直播脚本文案资料包丨国仁网络

    无直播不营销,早已成了公认的营销趋势. 几乎所有的品牌.商家.创业者都在探索直播带货之路,但是大多数人的直播之路走得并不顺利. 一场成功的直播,涉及到的运营细节多达几十个.如果没有前期的准备和策划,动 ...

  2. 这就是你日日夜夜想要的docker!!!---------三分钟带你玩转docker命令

    文章目录 docker version 查看版本信息 docker inspect 查看镜像全部信息 docker search 搜索镜像 docker pull 下载镜像 docker images ...

  3. mysql和oracle冲突吗_三分钟带你分清MySQL 和Oracle之间的误区

    原标题:三分钟带你分清MySQL 和Oracle之间的误区 来自:华为云开发者社区 摘要:MySQL和Oracle,别再傻傻分不清. MySQL 和Oracle 在开发中的使用是随处可见的,那就简单去 ...

  4. 来吧,1分钟带你玩转Kafka

    [摘要] Kafka让人又爱又恨?来吧,一分钟带你玩转它 说起Kafka,许多使用者对它是又爱又恨.Kafka是一种分布式的.基于发布/订阅的消息系统,其极致体验让人欲罢不能,但操心的运维.复杂的安全 ...

  5. 三分钟带你看懂prototype原型——ES6进阶

    三分钟带你看懂prototype原型--ES6进阶 1. prototype 定义 2. new 构造函数 3. 存储 4. prototype 作用 1. prototype 定义 在JS中的类的实 ...

  6. 三分钟带你弄懂slot插槽——vue进阶

    文章目录 三分钟带你弄懂slot插槽--vue进阶 一.概述 程序员之死 什么是 slot插槽? 2.6.0 版本中的 slot 二.具名插槽 例子 效果图 代码 三.小惊喜 三分钟带你弄懂slot插 ...

  7. 三分钟带你看懂HDMI接口的PCB设计

    三分钟带你看懂HDMI接口的PCB设计 本文主要讲解的是HDMI的设计,包括作用和运用的总结,希望大家看了以后能轻松的应对各种HDMI方案的PCB设计. 一.什么是HDMI? 高清晰度多媒体接口(英文 ...

  8. 三分钟带你读懂 BERT

    本文为 AI 研习社编译的技术博客,原标题 : BERT Technology introduced in 3-minutes 作者 | Suleiman Khan, Ph.D. 翻译 | 胡瑛皓.s ...

  9. 建网站的最简单方法(三分钟带后台)

    建网站的最简单方法(三分钟带后台) 准备材料 服务器或者本地环境 安装过程 准备材料 织梦二次开发模板或者Ecshop二次开发模板等(我以织梦为例讲解) 如果是本地需要下载ComsenzEXP或者Wa ...

最新文章

  1. Hibernate从入门到精通(十)多对多单向关联映射
  2. swift4.2 - 一个自定义view弹框
  3. python easy install_Python 安装easy_install详解
  4. 获取滚动文本框TextArea焦点位置信息
  5. SDN精华问答 | SDN的核心技术是什么?
  6. [ES6] 细化ES6之 -- 变量的解构赋值
  7. python环境下数据操作_在windows环境下使用Python操作spatialite数据库
  8. unity 自动生成脚本
  9. LAMMPS实例教程—In文件详解
  10. 素描构图中的对比与调和
  11. netware php_Linux中NetWare客户端简易安装说明(转)
  12. <Safari浏览器插件>使json代码能格式化显示
  13. Prometheus监控学习笔记之Prometheus普罗米修斯监控入门
  14. Python等待所有线程任务完成
  15. CorelDRAW VBA - 读取XML文件,根据内容批量创建图形
  16. 第四次面试----华数电力科技有限公司
  17. Electron如何支持ESM模块
  18. SKR!虎扑66万JRS大战3300万吴亦凡护卫队,别逼我拿Python
  19. 圆柱体积在线计算机,(完整版)圆柱体积计算练习题.docx
  20. shell 向 awk 传参

热门文章

  1. [Java]Spring Ioc讲解,不怕你不懂
  2. Icpc 沈阳 Bitwise Exclusive-OR Sequence
  3. 六方面的学习,帮你走上业务架构师之路
  4. Omar Loves Candies
  5. win10 系统 Internet Connection Sharing (ICS) 服务无法关闭-问题解决
  6. bag of tricks for image classification with convolutional neural networks
  7. python抓取腾讯视频弹幕_Python实战 | 如何抓取腾讯视频弹幕
  8. revit 二次开发之创建图纸和放置视图
  9. 二维泊松方程数值解-五点差分法-共轭梯度法-python实现
  10. 观察者模式Observer -- 深入理解