【PDF合并】滴滴出行电子发票及行程报销单【一页打印】

事出原因

最近本职工作繁忙。可能偶尔晚上还需要打车回家,打车就涉及到个人优先支付车费的问题(为什么不开通企业账号,我也不知道,问BOSS去)。就会涉及到上传以及打印发票的问题。

滴滴发票,给的是两个PDF。分开打印浪费纸张。PDF合并转换的软件呢又需要会员无奈。小帅丶就依靠自己三脚猫的能耐,用Java(iText)实现了一下PDF合并。还支持灰度、去除顶部广告操作哦~。

iText简介 

 在企业的信息系统中,报表处理一直占比较重要的作用,iText是一种生成PDF报表的Java组件。通过在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超链接显示或下载得到生成的报表,这样就很好解决了B/S系统的报表处理问题。

    iText是著名的开放源码的站点SourceForge一个项目,是用于生成PDF文档的一个Java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。iText的安装非常方便,下载iText.jar文件后,只需要在系统的CLASSPATH中加入iText.jar的路径,在程序中就可以使用iText类库了。

信息来源:https://baike.baidu.com/item/Itext/4692931

大致思路

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

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

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

大功告成!

上代码

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

/**
     * @Author 小帅丶
     * @Description 滴滴打车发票和行程单合并版成一个PDF
     * @Date  2022/5/12 19:05
     * @param pdfParams - PDF数据
     * @param isBanner - 是否保存行程单顶部滴滴企业宣传图
     * @param isGray - 是否进行灰度处理图片
     * @param grayType - 灰度类别
     * @return java.io.ByteArrayOutputStream
     **/
    public static ByteArrayOutputStream mergeDiDiInvoiceAndTravelToOnePDF(List<PDFParams> pdfParams, boolean isBanner,
                                                                                   boolean isGray, Integer grayType) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        switch (grayType) {
            case BufferedImage.TYPE_INT_RGB:
            case BufferedImage.TYPE_INT_ARGB:
            case BufferedImage.TYPE_INT_ARGB_PRE:
            case BufferedImage.TYPE_INT_BGR:
            case BufferedImage.TYPE_3BYTE_BGR:
            case BufferedImage.TYPE_4BYTE_ABGR:
            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
            case BufferedImage.TYPE_BYTE_GRAY:
            case BufferedImage.TYPE_USHORT_GRAY:
            case BufferedImage.TYPE_BYTE_BINARY:
            case BufferedImage.TYPE_BYTE_INDEXED:
            case BufferedImage.TYPE_USHORT_555_RGB:
                break;
            default:
                throw new Exception("Unknown image type " +
                        grayType);
        }
        //先对PDF进行处理
        BufferedImage invoiceBI;
        BufferedImage travelBI;
        Map<PDFType, BufferedImage> allImg = new HashMap<>();
        long startTime = System.currentTimeMillis();
        for (PDFParams pdfParam : pdfParams) {
            boolean isDiDi = getPDFContent(pdfParam.getFilePath(),pdfParam.getPdfType());
            if(isDiDi){
                if (pdfParam.getPdfType().equals(PDFType.INVOICE)) {
                    invoiceBI = PDFToImageSample.pdfToBufferedImage(pdfParam.getFilePath(), DEFAULT_DPI).get(0);
                    if (isGray) {
                        invoiceBI = grayDealImage(invoiceBI, grayType);
                    }
                    allImg.put(PDFType.INVOICE, invoiceBI);
                }
                if (pdfParam.getPdfType().equals(PDFType.TRAVEL_ITINERARY)) {
                    travelBI = PDFToImageSample.pdfToBufferedImage(pdfParam.getFilePath(), DEFAULT_DPI).get(0);
                    if (isBanner) {
                        travelBI = travelBI.getSubimage(0, 0, travelBI.getWidth(), travelBI.getHeight() - TRAVEL_B);
                    } else {
                        travelBI = travelBI.getSubimage(0, TRAVEL_Y, travelBI.getWidth(), travelBI.getHeight() - TRAVEL_H);
                    }
                    if (isGray) {
                        travelBI = grayDealImage(travelBI, grayType);
                    }
                    allImg.put(PDFType.TRAVEL_ITINERARY, travelBI);
                }
            }else{
                throw new Exception("非滴滴发票 或 行程单,请检查PDF内容");
            }
        }
        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 (Map.Entry<PDFType, BufferedImage> billImg : allImg.entrySet()) {
                BufferedImage bufferedImage = billImg.getValue();
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, "jpg", outStream);
                //图片
                com.itextpdf.text.Image contractSealImg = com.itextpdf.text.Image.getInstance(outStream.toByteArray());
                over.saveState();
                PdfGState pdfGState = new PdfGState();
                //给图片设置透明度
                pdfGState.setFillOpacity(1F);
                over.setGState(pdfGState);
                Integer width = DEFAULT_IMG_WIDTH;
                //缩放比例值
                double scaleX = (double) width / bufferedImage.getWidth();
                //计算等比缩放的高度
                Integer height = (int) (scaleX * bufferedImage.getHeight());
                //设置图片位置
                if (billImg.getKey().equals(PDFType.INVOICE)) {
                    contractSealImg.setAbsolutePosition(ABSOLUTE_X, (width + height) / 2);
                }
                if (billImg.getKey().equals(PDFType.TRAVEL_ITINERARY)) {
                    if (isBanner) {
                        contractSealImg.setAbsolutePosition(ABSOLUTE_X, 0);
                    } else {
                        contractSealImg.setAbsolutePosition(ABSOLUTE_X, height / 2);
                    }
                }
                //设置图片大小
                contractSealImg.scaleAbsolute(width, height);
                //将图片添加到pdf文件
                over.addImage(contractSealImg);
                over.restoreState();
            }
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
            outputStream.close();
        }
        System.out.println("合成总耗时:" + (System.currentTimeMillis() - startTime));
        return outputStream;
    }

 如何使用

小帅丶为了方便,将此功能实现发布在了微信小程序里面。搜索 小帅一点资讯 或者 点击下方卡片 即可直达体验哦!

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

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

温馨提示:目前只支持滴滴出行电子发票及行程报销单合并哦​~

【PDF合并】滴滴出行电子发票及行程报销单【一页打印】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小帅丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值