什么?发票合并还在开会员?不如看看这个小程序【发票合并】【PDF合并】

2023-12-29 13:13:49

事出原因

最近涉及到电子普通发票报销。就会涉及到上传以及打印发票的问题。

开发票肯定是大于两个PDF。分开打印浪费纸张WPS的PDF合并转换的软件呢又需要会员无奈。小帅丶就依靠自己三脚猫的能耐,用Java(Apche PDFBox)实现了一下PDF合并。

Apache PDFBox 简介?

Apache PDFBox 是一个用于处理和操作 PDF 文件的开源 Java 库,它提供了丰富的功能和工具,用于创建、解析、操作和转换 PDF 文件。下面我们将介绍一下 Apache PDFBox 的优点、缺点以及类似的框架。

优点

  • 强大的功能:Apache PDFBox 提供了丰富的功能和工具,包括创建、解析、操作、转换各种 PDF 文件。它可以用于生成 PDF 文档、提取文本内容、合并和拆分 PDF 文件等各种操作。

  • 良好的文档支持:Apache PDFBox 配备了详尽的文档和示例,使开发人员可以快速上手并充分利用其功能。此外,它拥有一个活跃的开发者社区,用户可以从社区中获取支持和帮助。

  • 跨平台兼容性:作为一个基于 Java 的库,Apache PDFBox 具有极强的跨平台兼容性,可以在各种操作系统和开发环境中使用。

缺点

  • 学习曲线较陡峭:由于PDF文件的复杂性,Apache PDFBox 的使用可能需要一定的学习和实践。特别是对于处理 PDF 文件较为复杂的操作,可能需要一定的时间和精力。

  • 相对较大的库:由于其强大的功能,Apache PDFBox 的库文件相对较大,可能占用一定的存储空间。

类似框架

  • iText:iText是另一个流行的用于处理PDF文件的Java库,提供了类似的功能和工具。与Apache PDFBox相比,iText可能在一些高级特性和商业化支持方面更加成熟。

  • PDFTron:PDFTron是一家专注于PDF技术的公司,提供了丰富的PDF处理解决方案和工具。它的SDK包括了丰富的功能和工具,能够满足各种PDF处理需求。

总的来说,Apache PDFBox 是一个强大而灵活的 Java 库,适用于各种处理和操作 PDF 文件的场景。选择使用 PDF 处理库时,需要结合具体的功能需求、文档支持以及各项性能指标来进行综合考量。

信息来源:百度搜素

大致思路

1.PDF转图片,并进行缩放处理,DPI设定为300? ? ? ? ? ? ? ? ? ? ?

2.新建一个空白PDF(是提前创建好的哦~)? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

3.将第一步处理好的2个图片文件添加到空白PDF,设置透明度,缩放宽高比例符合A4大小,另存为PDF文件。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

大功告成!

温馨提示:需要额外字体支持~

https://download.csdn.net/download/u010651369/88671953

上代码

全部代码 全部代码https://gitee.com/xshuai/worktools/blob/master/src/main/java/cn/ydxiaoshuai/pdf/PDFMergerSample.java

/**
     * @Author 小帅丶
     * @Description 普通发票合并成一个PDF
     * @Date  2022年12月27日09:58:59
     * @param pdfParams - PDF数据
     * @param isGray - 是否进行灰度处理图片
     * @param grayType - 灰度类别
     * @return java.io.ByteArrayOutputStream
     **/
    public static ByteArrayOutputStream mergeInvoiceOnePDF(List<PDFParams> pdfParams,
                                                           boolean isGray, Integer grayType) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        if(pdfParams.size()>2){
            throw new Exception("PDF文件个数错误 最多不超过2个");
        }else{
            garyType(grayType);
            //先对PDF进行处理
            List<BufferedImage> allImg = new ArrayList<>();
            long startTime = System.currentTimeMillis();
            for (PDFParams pdfParam : pdfParams) {
                PDFUtils.setFonts(FontFormat.TTF, "STSong-Light", FONT_FILE);
                byte[] bytes = FileUtil.readBytes(pdfParam.getFilePath());
                String pdfBase = Base64Encoder.encode(bytes);
                List<BufferedImage> bufferedImages = PDFUtils.pdfToImage(pdfBase);
                BufferedImage invoiceBI = bufferedImages.get(0);
                if (isGray) {
                    invoiceBI = grayDealImage(invoiceBI, grayType);
                }
                allImg.add(invoiceBI);
            }
            System.out.println("PDF转图片耗时:" + (System.currentTimeMillis() - startTime));
            //开始合并图片到PDF
            if (!allImg.isEmpty()) {
                //合成后的文件
                PdfReader reader = new PdfReader(new FileInputStream(EMPTY_PDF));
                PdfStamper stamper = new PdfStamper(reader, outputStream);
                //将所有图片放在pdf文件的第1页
                PdfContentByte over = stamper.getOverContent(1);
                for (int i = 0; i < allImg.size(); i++) {
                    BufferedImage bufferedImage = allImg.get(i);
                    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                    ImageIO.write(bufferedImage, "jpg", outStream);
                    //图片转com.itextpdf.text.Image
                    com.itextpdf.text.Image contractSealImg = com.itextpdf.text.Image.getInstance(outStream.toByteArray());
                    over.saveState();
                    PdfGState pdfGState = new PdfGState();
                    //给图片设置透明度
                    pdfGState.setFillOpacity(1F);
                    over.setGState(pdfGState);
                    //缩放比例值
                    double scaleX = (double) DEFAULT_IMG_WIDTH / contractSealImg.getWidth();
                    //计算等比缩放的高度
                    float height = (float) (scaleX * contractSealImg.getHeight());
                    //设置图片位置
                    //PDF从底部左下角算为原点坐标
                    if (i == 0) {
                        contractSealImg.setAbsolutePosition(ABSOLUTE_X, ABSOLUTE_Y);
                    } else {
                        contractSealImg.setAbsolutePosition(ABSOLUTE_X, A4_72_HEIGHT - height);
                    }
                    //设置图片大小
                    contractSealImg.scaleAbsolute(DEFAULT_IMG_WIDTH, height);
                    //将图片添加到pdf文件
                    over.addImage(contractSealImg);
                    over.restoreState();
                    outStream.close();
                }
                stamper.setFormFlattening(true);
                stamper.close();
                reader.close();
                outputStream.close();
            }
            System.out.println("合成总耗时:" + (System.currentTimeMillis() - startTime));
            return outputStream;
        }

    }

?如何使用

小帅丶为了方便使用,将此功能实现发布在了微信小程序里面。搜索 小帅一点资讯

功能实现暂无涉及到商用内容,所以此功能呢,目前也是免费使用哦~

?也可以先看下视频操作。再进行体验哦~

温馨提示:理论上2张电子普通发票都可以合并哦?~

文章来源:https://blog.csdn.net/u010651369/article/details/135263033
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。