使用 iText 合并不同宽度的 pdf 文档

Posted

技术标签:

【中文标题】使用 iText 合并不同宽度的 pdf 文档【英文标题】:Merge pdf documents of different width using iText 【发布时间】:2014-10-25 14:33:58 【问题描述】:

我在使用 iText 合并不同宽度的文档时遇到问题。

下面是我用来合并的代码。

        public static void doMerge(List<InputStream> list, OutputStream outputStream) throws Exception 

            Rectangle pagesize = new Rectangle(1700f, 20f);


            com.itextpdf.text.Document document = new com.itextpdf.text.Document(pagesize);

            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            document.setPageSize(pagesize);
            com.itextpdf.text.pdf.PdfContentByte cb = writer.getDirectContent();

            for (InputStream in : list)
                PdfReader reader = new PdfReader(in);
                for (int i = 1; i <= reader.getNumberOfPages(); i++)
                    document.newPage();
                    //import the page from source pdf
                    com.itextpdf.text.pdf.PdfImportedPage page = writer.getImportedPage(reader, i);

                    //calculate the y for merging it from top
                    float y = document.getPageSize().getHeight() - page.getHeight();
                    //add the page to the destination pdf

                    cb.addTemplate(page, 0, y);

                
                reader.close();
                in.close();
            

            outputStream.flush();
            document.close();
            outputStream.close();
        

pdf 的第一页宽 14 英寸,高 13 英寸。文档上的所有其他页面总是比它小。

我想将所有文档完全合并到一个文档中。

我不知道如何设置单个合并文档的宽度和高度。

我认为Rectangle pagesize = new Rectangle(1700f, 20f); 应该这样做,但它不起作用意味着如果将其更改为Rectangle pagesize = new Rectangle(1700f, 200f);,则文档无效。

请进一步指导我。

【问题讨论】:

您想保留原始 PDF 的尺寸吗?在这种情况下,您应该改用PdfCopy 【参考方案1】:

使用 itext 5.5 版,我们可以使用 PdfCopy.addDocument 方法更轻松地合并 pdf:

            package tn.com.sf.za.rd.controller;

            import java.io.FileOutputStream;
            import java.io.IOException;

            import com.itextpdf.text.Document;
            import com.itextpdf.text.DocumentException;
            import com.itextpdf.text.pdf.PdfCopy;
            import com.itextpdf.text.pdf.PdfReader;

            public class ReportMerging 

                public static void main(String[] args) throws DocumentException, IOException 

                    String DOC_ONE_PATH = "D:/s.zaghdoudi/tmp/one.pdf";
                    String DOC_TWO_PATH = "D:/s.zaghdoudi/tmp/two.pdf";
                    String DOC_THREE_PATH = "D:/s.zaghdoudi/tmp/three.pdf";
                    Document document = new Document();
                    PdfCopy copy = new PdfCopy(document, new FileOutputStream(DOC_THREE_PATH));
                    document.open();
                    PdfReader readerOne = new PdfReader(DOC_ONE_PATH);
                    PdfReader readerTwo = new PdfReader(DOC_TWO_PATH);
                    copy.addDocument(readerOne);
                    copy.addDocument(readerTwo);
                    document.close();
                

            

【讨论】:

没错。更新版本的 iText 允许您一次添加完整的文档。【参考方案2】:

使用PdfWriter 类合并文档违背了官方 文档中给出的所有建议,尽管有非官方 示例可能会诱使您写得不好代码。我希望您能理解,我觉得这些不好的例子比您更烦人。

请查看chapter 6 of my book 中的表 6.1。它为您提供了一个概述,显示何时使用哪个类。在这种情况下,您应该使用PdfCopy

String[] files =  MovieLinks1.RESULT, MovieHistory.RESULT ;
// step 1
Document document = new Document();
// step 2
PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
PdfReader reader;
int n;
// loop over the documents you want to concatenate
for (int i = 0; i < files.length; i++) 
    reader = new PdfReader(files[i]);
    // loop over the pages in that document
    n = reader.getNumberOfPages();
    for (int page = 0; page < n; ) 
        copy.addPage(copy.getImportedPage(reader, ++page));
    
    copy.freeReader(reader);
    reader.close();

// step 5
document.close();

如果您使用的是最新版本的 iText,您甚至可以使用 addDocument() 方法,在这种情况下您无需遍历所有页面。如果涉及表格,您还需要特别小心。 Sandbox 中有几个示例演示了新功能(可追溯到本书编写之后)。

【讨论】:

以上是关于使用 iText 合并不同宽度的 pdf 文档的主要内容,如果未能解决你的问题,请参考以下文章

itext7 pdf与书签合并

Itext:用条形码分隔符分割pdf文档

iText 使用相同的代码生成不同的 pdf

itext - pdf复选框填充不同

如何使用 C# 合并包含所有者密码的 PDF 文档

java合并PDF,itext.jar