itext合并横纵不同的pdf,并且生成页码。页码可以按照关键字跳页,双面打印补空白页

1 篇文章 0 订阅
  /**
     * 把多个pdf合并成一个pdf,使用新的分页,可以跳页。
     *
     * @param streamOfPDFFiles 需要合并的所有文件
     * @param outputStream     合并后的流
     * @param paginate         是否显示页码
     * @param patchPageFlag    是否补齐偶数页
     */
    public static void concatPDFsByPage(List<InputStream> streamOfPDFFiles, OutputStream outputStream, boolean paginate, boolean patchPageFlag) {
        log.info("concatPDFsByPage.....s");
        Document document = new Document();
        try {
            List<Map<String, Object>> pdfReaderList = Lists.newArrayList();
            int totalPages = 0;
            //遍历每一个pdf流。把不需要页码的index找出来。{pdf流,[1,2,3,4]}
            ByteArrayOutputStream byteArrayOutputStream = null;
            for (InputStream pdf : streamOfPDFFiles) {
                byteArrayOutputStream = new ByteArrayOutputStream();
                try {
                    byte[] buff = new byte[1024];
                    int rc = 0;
                    while ((rc = pdf.read(buff, 0, buff.length)) > 0) {
                        byteArrayOutputStream.write(buff, 0, rc);
                    }
                    //获取有标记的页面index。
                    List<Integer> disablePage = PdfUtils.getExceptPage(byteArrayOutputStream.toByteArray(), "disablePage");
                    //定义一个reader 来接收
                    PdfReader pdfReader = null;
                    if (disablePage.size() > 0) {
                        pdfReader = new PdfReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
                    } else {
                        pdfReader = new PdfReader(byteArrayOutputStream.toByteArray());
                    }
                    Map<String, Object> map = new HashMap<>(16);
                    map.put("disablePage", disablePage);
                    map.put("pdfReader", pdfReader);
                    pdfReaderList.add(map);
                    //总页数累加,需要减去不要页码的
                    totalPages += (pdfReader.getNumberOfPages() - disablePage.size());
                    pdf.close();
                    byteArrayOutputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (pdf != null) {
                            pdf.close();
                        }
                        if (byteArrayOutputStream != null) {
                            byteArrayOutputStream.close();
                        }
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }
            }
            //设置字体之类的
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            BaseFont bf = BaseFont.createFont(ConstantReport.fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            PdfContentByte cb = writer.getDirectContent();
            PdfImportedPage page;
            int currentPageNumber = 0;
            //游标
            int pageOfCurrentReaderPDF = 0;
            for (Map map : pdfReaderList) {
                //排除的页码
                List<Integer> disablePage = (List<Integer>) map.get("disablePage");
                //内衬页页,用来标记页码的。pageOfCurrentReaderPDF  也可以。
                int pageNumber = 0;
                PdfReader pdfReader = (PdfReader) map.get("pdfReader");
                int numberOfPages = pdfReader.getNumberOfPages();
                while (pageOfCurrentReaderPDF < numberOfPages) {
                    //变量累加
                    pageOfCurrentReaderPDF++;
                    currentPageNumber++;
                    pageNumber++;
                    //获取原pdf的方向,并且设置新的页的方向
                    document.setPageSize(pdfReader.getPageSize(pdfReader.getPageN(pageOfCurrentReaderPDF)));
                    document.newPage();
                    page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);
                    if (paginate) {
                        //如果排除页数组包含当前页。那么就pass,不生成页码
                        if (!disablePage.contains(pageNumber)) {
                            cb.beginText();
                            cb.setFontAndSize(bf, 11);
                            cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "第 " + (currentPageNumber) + "  页  共  " + (totalPages) + "  页", ConstantReport.pageFooterX, ConstantReport.pageFooterY, 0);
                            cb.endText();
                        } else {
                            //如果包含排除页,那么就减一
                            currentPageNumber--;
                        }
                    }
                }
                if (patchPageFlag) {
                    log.info("当前pdf总页数:{},准备增加空白页?:{}", numberOfPages, numberOfPages % 2 > 0);
                    //如果总页数是奇数,那么补空白页
                    if (numberOfPages % 2 > 0) {
                        document.newPage();
                        writer.setPageEmpty(false);
                        log.info("已经增加空白页");
                    }
                }
                pageOfCurrentReaderPDF = 0;
            }
            outputStream.flush();
            document.close();
            outputStream.close();
            log.info("concatPDFsByPage.....e");
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (document.isOpen()) {
                document.close();
            }
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

应项目要求,使用帆软生成pdf后,需要把多个分项pdf,合成一个总体报告,并且过滤掉部分pdf,不合成,并且合成后需要生成页码,并且页码要可以跳pdf生成。比如第一张需要页码,第二张不需要页码,第三张需要。
分享给大家,如果有更好的方法,欢迎分享。
2020年5月15日 新增:
1、优化流关闭
2、增加新需求,为了能双面打印,新增空白页。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值