C# 合并两个(或更多)PDF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/808670/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:04:07  来源:igfitidea点击:

Combine two (or more) PDF's

c#.netwinformspdf

提问by Nathan Koop

Background:I need to provide a weekly report package for my sales staff. This package contains several (5-10) crystal reports.

背景:我需要为我的销售人员提供每周报告包。这个包包含几个(5-10)个水晶报告。

Problem:I would like to allow a user to run all reports and also just run a single report. I was thinking I could do this by creating the reports and then doing:

问题:我想允许用户运行所有报告,也只运行一个报告。我想我可以通过创建报告然后执行以下操作来做到这一点:

List<ReportClass> reports = new List<ReportClass>();
reports.Add(new WeeklyReport1());
reports.Add(new WeeklyReport2());
reports.Add(new WeeklyReport3());
<snip>

foreach (ReportClass report in reports)
{
    report.ExportToDisk(ExportFormatType.PortableDocFormat, @"c:\reports\" + report.ResourceName + ".pdf");
}

This would provide me a folder full of the reports, but I would like to email everyone a single PDF with all the weekly reports. So I need to combine them.

这将为我提供一个装满报告的文件夹,但我想通过电子邮件向每个人发送一个包含所有每周报告的 PDF。所以我需要把它们结合起来。

Is there an easy way to do this without install any more third party controls? I already have DevExpress & CrystalReports and I'd prefer not to add too many more.

有没有一种简单的方法可以在不安装更多第三方控件的情况下做到这一点?我已经有了 DevExpress 和 CrystalReports,我不想再添加太多。

Would it be best to combine them in the foreach loop or in a seperate loop? (or an alternate way)

最好将它们组合在 foreach 循环中还是单独的循环中?(或另一种方式)

采纳答案by Andrew Burns

I had to solve a similar problem and what I ended up doing was creating a small pdfmerge utility that uses the PDFSharpproject which is essentially MIT licensed.

我不得不解决一个类似的问题,我最终做的是创建一个小的 pdfmerge 实用程序,它使用本质上是 MIT 许可的PDFSharp项目。

The code is dead simple, I needed a cmdline utility so I have more code dedicated to parsing the arguments than I do for the PDF merging:

代码非常简单,我需要一个 cmdline 实用程序,因此与 PDF 合并相比,我有更多的代码专门用于解析参数:

using (PdfDocument one = PdfReader.Open("file1.pdf", PdfDocumentOpenMode.Import))
using (PdfDocument two = PdfReader.Open("file2.pdf", PdfDocumentOpenMode.Import))
using (PdfDocument outPdf = new PdfDocument())
{                
    CopyPages(one, outPdf);
    CopyPages(two, outPdf);

    outPdf.Save("file1and2.pdf");
}

void CopyPages(PdfDocument from, PdfDocument to)
{
    for (int i = 0; i < from.PageCount; i++)
    {
        to.AddPage(from.Pages[i]);
    }
}

回答by M4N

PDFsharpseems to allow merging multiple PDF documents into one.

PDFsharp似乎允许将多个 PDF 文档合并为一个。

And the same is also possible with ITextSharp.

同样也可以使用ITextSharp

回答by northpole

Here is a link to an example using PDFSharp and ConcatenateDocuments

这是使用PDFSharp 和 ConcatenateDocuments的示例的链接

回答by Dmitri Kouminov

回答by trendl

I've done this with PDFBox. I suppose it works similarly to iTextSharp.

我已经用 PDFBox 做到了这一点。我想它的工作原理类似于 iTextSharp。

回答by trendl

回答by NotMe

I know a lot of people have recommended PDF Sharp, however it doesn't look like that project has been updated since june of 2008. Further, source isn't available.

我知道很多人都推荐了 PDF Sharp,但该项目似乎自 2008 年 6 月以来没有更新。此外,源不可用。

Personally, I've been playing with iTextSharp which has been pretty easy to work with.

就个人而言,我一直在使用 iTextSharp,它非常易于使用。

回答by Naaff

There's some good answers here already, but I thought I might mention that pdftkmight be useful for this task. Instead of producing one PDF directly, you could produce each PDF you need and then combine them together as a post-process with pdftk. This could even be done from within your program using a system() or ShellExecute() call.

这里已经有一些很好的答案,但我想我可能会提到pdftk可能对这项任务有用。您可以生成您需要的每个 PDF,然后将它们组合在一起作为使用 pdftk 的后处理,而不是直接生成一个 PDF。这甚至可以在您的程序中使用 system() 或 ShellExecute() 调用来完成。

回答by JustMaier

Here is a single function that will merge X amount of PDFs using PDFSharp

这是一个使用 PDFSharp 合并 X 数量 PDF 的函数

using PdfSharp;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;

public static void MergePDFs(string targetPath, params string[] pdfs) {
    using(PdfDocument targetDoc = new PdfDocument()){
        foreach (string pdf in pdfs) {
            using (PdfDocument pdfDoc = PdfReader.Open(pdf, PdfDocumentOpenMode.Import)) {
                for (int i = 0; i < pdfDoc.PageCount; i++) {
                    targetDoc.AddPage(pdfDoc.Pages[i]);
                }
            }
        }
        targetDoc.Save(targetPath);
    }
}

回答by Sajitha Rathnayake

I used iTextsharp with c# to combine pdf files. This is the code I used.

我使用 iTextsharp 和 c# 来组合 pdf 文件。这是我使用的代码。

string[] lstFiles=new string[3];
    lstFiles[0]=@"C:/pdf/1.pdf";
    lstFiles[1]=@"C:/pdf/2.pdf";
    lstFiles[2]=@"C:/pdf/3.pdf";

    PdfReader reader = null;
    Document sourceDocument = null;
    PdfCopy pdfCopyProvider = null;
    PdfImportedPage importedPage;
    string outputPdfPath=@"C:/pdf/new.pdf";


    sourceDocument = new Document();
    pdfCopyProvider = new PdfCopy(sourceDocument, new System.IO.FileStream(outputPdfPath, System.IO.FileMode.Create));

    //Open the output file
    sourceDocument.Open();

    try
    {
        //Loop through the files list
        for (int f = 0; f < lstFiles.Length-1; f++)
        {
            int pages =get_pageCcount(lstFiles[f]);

            reader = new PdfReader(lstFiles[f]);
            //Add pages of current file
            for (int i = 1; i <= pages; i++)
            {
                importedPage = pdfCopyProvider.GetImportedPage(reader, i);
                pdfCopyProvider.AddPage(importedPage);
            }

            reader.Close();
         }
        //At the end save the output file
        sourceDocument.Close();
    }
    catch (Exception ex)
    {
        throw ex;
    }


private int get_pageCcount(string file)
{
    using (StreamReader sr = new StreamReader(File.OpenRead(file)))
    {
        Regex regex = new Regex(@"/Type\s*/Page[^s]");
        MatchCollection matches = regex.Matches(sr.ReadToEnd());

        return matches.Count;
    }
}