使用 Java 在 PDF 中指定位置添加二维码

需求如下
1.监控a文件夹中的文件提取文件名前9位
2.需要自动屏蔽第二位,剩余8位数
3.生成为二维码-L纠错级别,码版本21*21的常用二维码
4.将二维码嵌入pdf每页的指定位置
5.导出新的pdf文件,并且将原来文件名称添加-已处理,文件输出新的文件
其中部分参数可配置方式完成(具体配置放下面)

public void addQRcodeToPDF() {
        try {
            String property = System.getProperty("user.dir");
            String configName = property + "/pdf.ini";
            Wini ini = new Wini(new File(configName));
            log.info("get pdf.ini {}", ini);
            String sleepTime = ini.get("SLEEP_TIME", "SLEEP_TIME");
            String initFilePath = ini.get("INIT_FILE_PATH", "INIT_FILE_PATH");

            // 以页面左下角为原点的 x 坐标
            float x = Float.parseFloat(ini.get("QR_LOCATION", "left"));
            // 以页面左下角为原点的 y 坐标
            float y = Float.parseFloat(ini.get("QR_LOCATION", "top"));
            float height = Float.parseFloat(ini.get("PDF_SIZE", "height"));
            String outputPath = ini.get("OUT_PUT_FILE_PATH", "OUT_PUT_FILE_PATH");
            File initFile = new File(initFilePath);
            File[] list = initFile.listFiles();
            if (initFile.exists() && initFile.isDirectory()) {
                for (File file : list) {
                    String fileName = file.getName();
                    if (fileName.contains("已处理")) {
                        continue;
                    }
                    // 构建保存文件的路径,将文件保存到目标文件夹
                    String outputFilePath = outputPath + fileName;

                    if (!isFirstNineDigits(fileName)) {
                        log.info("file name is not a 9-digit number, skip {}", fileName);
                        continue;
                    }

                    log.info("正在处理 pdf {} 文件", fileName);
                    String fileNumber = fileName.substring(0, 9);
                    String number = fileNumber.charAt(0) + fileNumber.substring(2);
                    BufferedImage bufferedImage = generateQRCode(number);

                    PdfReader reader = new PdfReader(file.getAbsolutePath());
                    Document document = new Document();
                    // 创建一个输出文件
                    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFilePath));

                    // 创建一个 Image 对象,用于插入到 PDF 中
                    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                        Image image = Image.getInstance(bufferedImage, null);

                        // 图像的宽度和高度(毫米)
                        float imageHeightMm = 8f;

                        // 将毫米转换为厘米
                        float mmToCm = 0.1f;

                        // 计算图像的左上角位置
                        float imageLeftCm = x * mmToCm;
                        float imageTopCm = height - (y * mmToCm) - (imageHeightMm * mmToCm);

                        image.setAbsolutePosition(imageLeftCm * 28.3465f, imageTopCm * 28.3465f);

                        // 获取当前页的 PdfContentByte
                        PdfContentByte content = stamper.getOverContent(i);
                        content.addImage(image);
                    }

                    stamper.close();
                    document.close();
                    reader.close();
                    log.info("PDF 更新成功,已保存到 {}", outputPath);
                    if (!file.exists()) {
                        log.error("源文件不存在 {}", fileName);
                        continue;
                    }
                    fileName = "已处理-" + fileName;

                    String path = file.getParentFile().getPath() + "/" + fileName;
                    File newFile = new File(path);
                    if (newFile.exists()) {
                        log.error("新文件名已存在。 {}", newFile.getName());
                        continue;
                    }
                    boolean success = file.renameTo(newFile);
                    if (!success) {
                        log.info("文件重命名失败 {}", fileName);
                    }
                }
            }
            log.info("本次任务完成!即将进行" + Integer.valueOf(sleepTime) + "秒休眠");
            Thread.sleep(Integer.valueOf(sleepTime));
        } catch (Exception e) {
            log.error("addQRcodeToPDF error!", e);
        }
    }

        public static boolean isFirstNineDigits(String str) {
        if (str == null || str.length() < 9) {
            return false;
        }

        String firstNineDigits = str.substring(0, 9);
        return firstNineDigits.matches("\\d+");
    }

    private static BufferedImage generateQRCode(String data) {
        try {
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.MARGIN, 0); // 设置二维码边距为0
            hints.put(EncodeHintType.ERROR_CORRECTION, com.google.zxing.qrcode.decoder.ErrorCorrectionLevel.L); // 设置纠错级别为L
                        //设置二维码尺寸为21像素
            BitMatrix matrix = new MultiFormatWriter().encode(data, BarcodeFormat.QR_CODE, 21, 21, hints);
            BufferedImage image = toBufferedImage(matrix);
            return image;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 将 BitMatrix 转换为 BufferedImage
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }

        return image;
    }

pom坐标

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.6</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
                        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.4.1</version> 
        </dependency>

pdf.ini配置

#线程休眠时间 -> 执行完一次之后休息10000毫秒
[SLEEP_TIME]
SLEEP_TIME = 10000
#要添加二维码的文件夹
[INIT_FILE_PATH]
INIT_FILE_PATH = /Users/admin/Downloads/1
#最终输出文件夹
[OUT_PUT_FILE_PATH]
OUT_PUT_FILE_PATH = /Users/admin/Downloads/2/
#二维码添加坐标 -> left距离PDF左边,top距离PDF顶部,单位毫米
[QR_LOCATION]
left=12
top=4.5
#pdf尺寸 -> width宽,height高,单位cm
[PDF_SIZE]
width=32
height=45.2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值