C# 是否有一种直接的方法可以使用iTextSharp将一个PDF文档附加到另一个PDF文档?

C# 是否有一种直接的方法可以使用iTextSharp将一个PDF文档附加到另一个PDF文档?,c#,pdf,itextsharp,C#,Pdf,Itextsharp,我在网上搜寻了一些关于如何做到这一点的例子。我发现有一些似乎比他们需要的更为复杂。所以我的问题是,使用iTextSharp,是否有一种相当简洁的方式将一个PDF文档附加到另一个PDF文档 这最好不涉及第三个文件。只需打开第一个PDF文档,将第二个PDF文档附加到第一个PDF文档,然后同时关闭它们。是。我在iText论坛上看到了一个名为PdfManipulation的类。不过,使用该类将涉及第三个文件 该类最初是在VB.Net中创建的。我从网上下载的。显然,它没有merge files函数,所以我

我在网上搜寻了一些关于如何做到这一点的例子。我发现有一些似乎比他们需要的更为复杂。所以我的问题是,使用iTextSharp,是否有一种相当简洁的方式将一个PDF文档附加到另一个PDF文档


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

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

该类最初是在VB.Net中创建的。我从网上下载的。显然,它没有merge files函数,所以我根据该类中的代码编写了一个

这是在一台没有iTextSharp的机器上写的。这可能有bug。我甚至不确定页码是基于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();
}
publicstaticvoidmergepdffiles(IEnumerable文件,字符串输出){
iTextSharp.text.Document文档;
iTextSharp.text.pdf.PdfCopy pdfCpy;
doc=新的iTextSharp.text.Document();
pdfCpy=new iTextSharp.text.pdf.PdfCopy(doc,new System.IO.FileStream(output,System.IO.FileMode.Create));
doc.Open();
foreach(文件中的字符串文件){
//初始化读取器
iTextSharp.text.pdf.PdfReader=新的iTextSharp.text.pdf.PdfReader(文件);
int pageCount=reader.NumberOfPages;
//设置文档的页面大小
doc.SetPageSize(reader.GetPageSizeWithRotation(1));

对于(int pageNum=1;pageNum我不知道如何处理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。不知道为什么。

好的,它不是直接的,但它工作起来非常快。(并且它使用了第三个文件,没有打开和附加之类的东西。)我在文档/示例中“发现”了这一点。代码如下:

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();
    }
}
    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();
    }
private void combinemultiplePDF(字符串[]文件名,字符串输出文件){
int pageOffset=0;
ArrayList master=新的ArrayList();
int f=0;
单据=空;
PdfCopy writer=null;
while(f0&&writer!=null){
作者:大纲=大师;
}
//步骤5:我们关闭文档
如果(文档!=null){
document.Close();
}
}

我可能真的遗漏了一些东西,但我做了一些简单得多的事情。我承认这个解决方案可能不会更新书签(正如目前为止的最佳答案一样),但它对我来说完美无瑕。因为我将文档与可填充表单合并,所以我使用了PdfCopyFields而不是PdfCopy

下面是代码(我已经剥离了所有错误处理,以使实际代码更为可见,添加一个try..finally来关闭打开的资源,如果您计划使用代码):

void MergePdfStreams(列出源、流目的)
{
PdfCopyFields copy=新的PdfCopyFields(目的地);
foreach(源中的流源)
{
PdfReader reader=新PdfReader(源);
副本。添加文件(读卡器);
}
copy.Close();
}
您可以传递任何流,无论是文件流还是内存流(从数据库读取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));
    }
void TestMergePdfStreams()
{
列表源=新列表()
{
新的文件流(“template1.pdf”,FileMode.Open),
新的文件流(“template2.pdf”,FileMode.Open),
新MemoryStream((字节[])someDataRow[“PDF\u列\u名称”])
};
MergePdfStreams(sources,newfilestream(“MergedOutput.pdf”,FileMode.Create));
}

这非常适合尝试合并/附加两个带有表单字段的PDF文档!也非常简单!谢谢。这对我来说太棒了。我建议调用source.Close()在调用copy.AddDocument以允许在其他地方使用该文件之后。页码是以1为基础的。我的问题是,我没有意识到我必须使用第三个文件,因为我无法读取/写入我已经读取的文件,所以我创建了第三个文件并将输出放在那里,然后删除旧的源文件并将其替换为输出文件。如果有人运行