业务希望实现一个类似于电子签章的功能,但又不想花钱买电子签章服务。那么如何在 PDF 上签章图片呢?我们拆分一下问题:

  1. 如何添加图片到 PDF 图片上?
  2. 如何在固定位置上添加图片?

Apache 提供了pdfbox解决方案,我们就利用它去实现我们要做功能。

添加依赖

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version>
</dependency>

获取需要盖章的坐标信息

public class GetCharLocationAndSize extends PDFTextStripper {

private List<InserImageToPDF.Position> positions;

    public GetCharLocationAndSize() throws IOException {
    }

    public GetCharLocationAndSize(List<InserImageToPDF.Position> positions) throws IOException {
        super();
        this.positions=positions;
    }
    @Override
    protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
        super.writeString(text, textPositions);
        if(text.equals("合同签章处")){
            for (TextPosition position : textPositions) {
                System.out.println(position.getXDirAdj() + "," + position.getYDirAdj());
                positions.add(new InserImageToPDF.Position(position.getXDirAdj(), position.getYDirAdj()));
            }
        }

    }
}

填充图片到 PDF 文件

public class InsertImageToPDF {

    public String getFile() {
        return getClass().getResource("/demo.pdf").getFile();
    }

    public String getImage() {
        return getClass().getResource("/out.png").getFile();
    }


    public static void main(String[] args) throws IOException, URISyntaxException {

        PDDocument document = PDDocument.load(new File(new InserImageToPDF().getFile()));

        List<Position> positions = new ArrayList<>();

        PDFTextStripper stripper = new GetCharLocationAndSize(positions);
        stripper.setSortByPosition(true);
        stripper.setStartPage(0);
        stripper.setEndPage(document.getNumberOfPages());
        Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
        stripper.writeText(document, dummy);


        // 加载图像文件
        PDImageXObject image = PDImageXObject.createFromFileByContent(new File(new InserImageToPDF().getImage()), document);

        // 在指定位置插入图像
        PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
        contentStream.drawImage(image, positions.get(0).getX(), positions.get(0).getY(), image.getWidth(), image.getHeight());
        // 关闭流
        contentStream.close();

        // 保存修改后的PDF文件
        document.save("one-more-jpg.pdf");

        // 关闭文档
        document.close();
        System.out.println("PDF created successfully.");
    }

    @Data
    public static class Position {

        public Position(float x, float y) {
            this.x = x;
            this.y = y;
        }

        private float x;
        private float y;
    }
}

以上只是一个 DEMO,具体实现需要结合实际需求进行处理。


迹_Jason
1k 声望65 粉丝

feeling主义者,追求极致的简约,创造最好的用户体验