三分钟带你玩转PDF文件签名

需求

客户希望在 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指定文字位置插入图片

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值