自学内容网 自学内容网

Java 实现给pdf文件指定位置盖章功能

Java 实现给pdf文件指定位置盖章功能

开发中遇到一个需求, 需要给用户上传的的pdf文件, 指定位置上盖公章的功能, 经过调研和对比, 最终确定实现思路.

这里是使用pdf文件中的关键字进行章子的定位, 之所以这样考虑是因为如果直接写死坐标的话, 可能会出现因pdf大小, 缩放, 盖章位置变更的原因, 导致公章位置错位. 所以选择了根据关键字定位的方式.

下面列出具体的实现方式:

  1. 使用的是Java语言, 使用Maven管理依赖, 下面是操作pdf所依赖的库的坐标

    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.12</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext-asian</artifactId>
        <version>5.2.0</version>
    </dependency>
    
  2. 下面是具体的代码逻辑

    • CustomRenderListener, 自定义渲染监听器, 实现查找关键字自有逻辑

      import com.itextpdf.awt.geom.Rectangle2D.Float;
      import com.itextpdf.text.pdf.parser.ImageRenderInfo;
      import com.itextpdf.text.pdf.parser.RenderListener;
      import com.itextpdf.text.pdf.parser.TextRenderInfo;
      import lombok.Data;
      
      /**
       * pdf关键词帮助类
       *
       * @author wdhcr
       */
      @Data
      public class CustomRenderListener implements RenderListener {
      
        // 坐标
          private float[] coordinate = null;
      
        // 关键字
          private String keyWord;
      
        // pdf当前页
          private int page;
      
          @Override
          public void beginTextBlock() {
          }
      
          @Override
          public void endTextBlock() {
          }
      
          @Override
          public void renderImage(ImageRenderInfo arg0) {
          }
      
          @Override
          public void renderText(TextRenderInfo textRenderInfo) {
              String text = textRenderInfo.getText();
              if (null != text && text.contains(keyWord)) {
                  Float boundingRange = textRenderInfo.getBaseline().getBoundingRectange();
                  coordinate = new float[3];
                  coordinate[0] = boundingRange.x;
                  coordinate[1] = boundingRange.y;
                  coordinate[2] = page;
              }
          }
      }
      
    • 获取关键字坐标的工具类

      import com.itextpdf.text.Image;
      import com.itextpdf.text.pdf.PdfContentByte;
      import com.itextpdf.text.pdf.PdfGState;
      import com.itextpdf.text.pdf.PdfReader;
      import com.itextpdf.text.pdf.PdfStamper;
      import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
      import lombok.SneakyThrows;
      import lombok.extern.slf4j.Slf4j;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.OutputStream;
      
      /**
       * Pdf定位工具类
       * @author wdhcr
       */
      public class PdfUtils {
          @SneakyThrows
          public static void stampToPdf(InputStream pdfInputStream, String keyWords, InputStream sealInputStream, OutputStream outputStream) {
              byte[] sealBytes = sealInputStream.readAllBytes();
              PdfReader reader = new PdfReader(pdfInputStream);
              float[] xyz = PdfUtils.getKeyWords(reader, keyWords);
              if (xyz == null) {
                  throw new RuntimeException("未找到盖章位置");
              }
              PdfStamper stamper = new PdfStamper(reader, outputStream);
              // 将印章图片放在pdf文件的第?页
              PdfContentByte over = stamper.getOverContent((int) xyz[2]);
              // 需要插入的图片
              Image contractSealImg = Image.getInstance(sealBytes);
              // 保存状态
              over.saveState();
              // 图片处理
              PdfGState pdfGState = new PdfGState();
              // 给图片设置透明度,一般不需要
              pdfGState.setFillOpacity(0.8F);
              over.setGState(pdfGState);
              contractSealImg.setAbsolutePosition(xyz[0], xyz[1]);
              // 设置图片大小
              contractSealImg.scaleAbsolute(100, 100);
              // 将图片添加到pdf文件
              over.addImage(contractSealImg);
              over.restoreState();
              stamper.setFormFlattening(true);
              // 关闭流
              stamper.close();
              reader.close();
          }
      }
      
    • 测试demo

          @SneakyThrows
          public static void main(String[] args) {
              FileInputStream pdfInputStream = new FileInputStream("/Users/Desktop/报告模版.pdf");
              FileInputStream sealInputStream = new FileInputStream("/Users/Desktop/dbd.png");
              FileOutputStream fileOutputStream = new FileOutputStream("/Users/Desktop/报告模版盖章.pdf");
              // 关键字为: 签发日期
              PdfUtils.stampToPdf(pdfInputStream, "签发日期", sealInputStream, fileOutputStream);
              fileOutputStream.close();
              pdfInputStream.close();
              sealInputStream.close();
              System.out.println("盖章完成");
      
          }
      
    • 公章如图所示

      seal

    • 报告模版如下:

      image-20241211145537180

    • 盖完章后

      image-20241211145618814


原文地址:https://blog.csdn.net/weixin_45089791/article/details/144401312

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!