PDF多页合并成一页 java实现

前景

当前需求:为了节约打印纸张,多个发票文件要合并成一个pdf,要求每页包含四个发票。
当前实现:仅实现每个PDF文件取第一页(若有需要自己调整下逻辑也很简单了)然后将4页的内容拼接到一页pdf里面。
上代码:


    /**
     * 合并PDF页
     * @param files 待合并的零散PDF文件
     * @param filePath 合并后的结果文件路径
     * @throws IOException PDF文件操作异常
     * @throws DocumentException PdfWriter实例时异常
     */
    public void mergePdfPage(File[] files, String filePath) throws IOException, DocumentException {
        final float spacing = 50f;
        Document doc = new Document();
        PdfWriter writer = null;
        PdfContentByte cb = null;
        for (int i = 1; i <= files.length; i++) {
            File file = files[i - 1];
            PdfReader reader = new PdfReader(file.getAbsolutePath());
            if (i == 1) {
                Rectangle pageSize = reader.getPageSize(1);
                //设置新的PDF文档页面大小,因为要放四个,比原文件的长宽都要大2倍,然后还加了个50f的调整间距
                doc.setPageSize(new RectangleReadOnly(pageSize.getWidth() * 2 + spacing, pageSize.getHeight() * 2 + spacing));
                doc.setMargins(0, 0, 0, 0);
                File newFile = new File(filePath);
                if (newFile.exists())
                    newFile.delete();
                writer = PdfWriter.getInstance(doc, Files.newOutputStream(newFile.toPath()));
                doc.open();
                cb = writer.getDirectContent();
            }
            //只取读取文档的第一页(若要读取所有页,这里加循环每页,且i的迭代逻辑要改下,当前业务先取第一页)
            PdfImportedPage page = writer.getImportedPage(reader, 1); // page #1
            float documentWidth = doc.getPageSize().getWidth() / 2;
            float documentHeight = doc.getPageSize().getHeight();

            float pageWidth = page.getWidth();
            float pageHeight = page.getHeight();

            //是否每页第四个文件
            float four = i % 4;
            //是否每页偶数文件
            float two = i % 2;

            float offsetY = 0f;
            //仅在1、5、9。。。个文件时创建新的page
            if (four == 1) {
                doc.newPage();
            }
            //仅在每页第一个与第二个文件设置y轴为当前页高的值(感觉坐标是从左下角开始的,往上为y,往右为x)
            if (four == 1 || (two == 0 && four != 0))
                offsetY = page.getHeight();

            float widthScale = documentWidth / pageWidth;
            float heightScale = documentHeight / pageHeight;
            float scale = Math.min(widthScale, heightScale);
            float offsetX = (documentWidth - (pageWidth * scale)) / 2;
            //偶数页放到右边
            if (two == 0)
                offsetX += documentWidth;
            cb.addTemplate(page, scale, 0, 0, scale, offsetX, offsetY);
        }
        doc.close();
    }

合并结果


参考 pdfbox-merge-2-portrait-pages-onto-a-single-side-by-side-landscape-page

posted on 2023-10-07 04:08  Jalan·Wang  阅读(688)  评论(0编辑  收藏  举报

导航