【问题标题】:Is there a straight forward way to append one PDF doc to another using iTextSharp?有没有一种直接的方法可以使用 iTextSharp 将一个 PDF 文档附加到另一个?
【发布时间】:2009-02-19 20:00:46
【问题描述】:

我在网上搜索了有关如何执行此操作的示例。我发现了一些似乎比他们需要的更多的参与。所以我的问题是,使用 iTextSharp,是否有一种相当简洁的方法可以将一个 PDF 文档附加到另一个文档?

最好这不会涉及第三个文件。只需打开第一个 PDF 文档,将第二个 PDF 文档附加到第一个 PDF 文档,然后将它们都关闭。

【问题讨论】:

    标签: c# pdf itextsharp


    【解决方案1】:

    我确实可能遗漏了一些东西,但我做了一些更简单的事情。我承认这个解决方案可能不会更新书签(就像迄今为止最好的答案一样),但它对我来说完美无缺。由于我将文档与可填写的表单合并,因此我使用了 PdfCopyFields 而不是 PdfCopy。

    这是代码(我已经剥离了所有错误处理以使实际代码更加可见,如果您打算使用该代码,请添加 try..finally 以关闭打开的资源):

        void MergePdfStreams(List<Stream> Source, Stream Dest)
        {
            PdfCopyFields copy = new PdfCopyFields(Dest);
    
            foreach (Stream source in Source)
            {
                PdfReader reader = new PdfReader(source);
                copy.AddDocument(reader);
            }
    
            copy.Close();
        }
    

    您可以传递任何流,无论是 FileStream、MemoryStream(在从数据库中读取 PDF 时很有用,不需要临时文件等)

    示例用法:

        void TestMergePdfStreams()
        {
            List<Stream> sources = new List<Stream>()
            {
                new FileStream("template1.pdf", FileMode.Open),
                new FileStream("template2.pdf", FileMode.Open),
                new MemoryStream((byte[])someDataRow["PDF_COLUMN_NAME"])
            };
    
            MergePdfStreams(sources, new FileStream("MergedOutput.pdf", FileMode.Create));
        }
    

    【讨论】:

    • 这非常适合尝试使用表单域合并/附加两个 PDF 文档!也简单多了!谢谢。
    • 这对我来说太棒了。我建议在 copy.AddDocument 调用之后调用 source.Close() 以允许在其他地方使用该文件。
    【解决方案2】:

    是的。我在 iText 论坛上看到过一个名为 PdfManipulation 的课程。但是,使用该类将涉及第三个文件。

    该类最初是在 VB.Net 中。我从post on vbforums.com 下载了它。不过貌似没有合并文件的功能,所以我根据那个类的代码写了一个。

    这是在没有 iTextSharp 的机器上编写的。这可能有错误。我什至不确定页码是基于 0 还是基于 1。但是试一试。

    public static void MergePdfFiles(IEnumerable<string> files, string output) {
        iTextSharp.text.Document doc;
        iTextSharp.text.pdf.PdfCopy pdfCpy;
    
        doc = new iTextSharp.text.Document();
        pdfCpy = new iTextSharp.text.pdf.PdfCopy(doc, new System.IO.FileStream(output, System.IO.FileMode.Create));
        doc.Open();
    
        foreach (string file in files) {
            // initialize a reader
            iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(file);
            int pageCount = reader.NumberOfPages;
    
            // set page size for the documents
            doc.SetPageSize(reader.GetPageSizeWithRotation(1));
    
            for (int pageNum = 1; pageNum <= pageCount; pageNum++) {
                iTextSharp.text.pdf.PdfImportedPage page = pdfCpy.GetImportedPage(reader, pageNum);
                pdfCpy.AddPage(page);
            }
    
            reader.Close();
        }
    
        doc.Close();
    }
    

    【讨论】:

    • 页码从 1 开始
    • 我的问题是我没有意识到我必须使用第三个文件,因为我无法读取/写入我已经读取的文件,所以我创建了第三个文件并将输出放在那里然后删除旧的源文件并将其替换为输出文件。以防有人遇到同样的问题
    【解决方案3】:

    好的,这不是直截了当的,但它可以工作并且速度惊人。 (并且它使用第三个文件,没有打开和追加之类的东西。)我在文档/示例中“发现”了这一点。代码如下:

    private void CombineMultiplePDFs( string[] fileNames, string outFile ) {
        int pageOffset = 0;
        ArrayList master = new ArrayList();
        int f = 0;
    
        Document document = null;
        PdfCopy writer = null;
        while ( f < fileNames.Length ) {
            // we create a reader for a certain document
            PdfReader reader = new PdfReader( fileNames[ f ] );
            reader.ConsolidateNamedDestinations();
            // we retrieve the total number of pages
            int n = reader.NumberOfPages;
            ArrayList bookmarks = SimpleBookmark.GetBookmark( reader );
            if ( bookmarks != null ) {
                if ( pageOffset != 0 ) {
                    SimpleBookmark.ShiftPageNumbers( bookmarks, pageOffset, null );
                }
                master.AddRange( bookmarks );
            }
            pageOffset += n;
    
            if ( f == 0 ) {
                // step 1: creation of a document-object
                document = new Document( reader.GetPageSizeWithRotation( 1 ) );
                // step 2: we create a writer that listens to the document
                writer = new PdfCopy( document, new FileStream( outFile, FileMode.Create ) );
                // step 3: we open the document
                document.Open();
            }
            // step 4: we add content
            for ( int i = 0; i < n; ) {
                ++i;
                if ( writer != null ) {
                    PdfImportedPage page = writer.GetImportedPage( reader, i );
                    writer.AddPage( page );
                }
            }
            PRAcroForm form = reader.AcroForm;
            if ( form != null && writer != null ) {
                writer.CopyAcroForm( reader );
            }
            f++;
        }
        if ( master.Count > 0 && writer != null ) {
            writer.Outlines = master;
        }
        // step 5: we close the document
        if ( document != null ) {
            document.Close();
        }
    }
    

    【讨论】:

      【解决方案4】:

      我不知道如何处理 PDF 文件,但对于 postscript,您只需连接文件即可。如果你安装了 pdf2ps 和 ps2pdf,下面的就可以了:

      pdf2ps file1.pdf file1.ps
      pdf2ps file2.pdf file2.ps
      cat file1.ps file2.ps > combined.ps
      ps2pdf combined.ps combined.pdf
      

      我不是 pdf2ps 或 ps2pdf 方面的专家。我只使用过 ps2pdf,当我这样做时,它会将文本保留为文本(我仍然可以从生成的 pdf 中选择和复制文本)。当我执行上述步骤(pdf->ps、combine、ps->pdf)时,我最终会得到一个类似于图像的 pdf。不知道为什么。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-11
        • 1970-01-01
        • 2023-02-02
        • 1970-01-01
        • 2012-04-04
        相关资源
        最近更新 更多