Объедините два (или более) PDF - PullRequest
50 голосов
/ 30 апреля 2009

Справочная информация: Мне необходимо предоставить пакет еженедельных отчетов для моего торгового персонала. Этот пакет содержит несколько (5-10) отчетов о кристаллах.

Проблема: Я хотел бы разрешить пользователю запускать все отчеты, а также просто запускать один отчет. Я думал, что смогу сделать это, создав отчеты и выполнив:

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");
}

Это даст мне папку с отчетами, но я бы хотел отправить каждому по электронной почте один PDF со всеми еженедельными отчетами. Поэтому мне нужно объединить их.

Есть ли простой способ сделать это без установки каких-либо сторонних элементов управления? У меня уже есть DevExpress & CrystalReports, и я бы предпочел не добавлять их слишком много.

Было бы лучше объединить их в цикле foreach или в отдельном цикле? (или альтернативный способ)

Спасибо

Ответы [ 17 ]

79 голосов
/ 30 апреля 2009

Мне пришлось решить аналогичную проблему, и в итоге я создал небольшую утилиту pdfmerge, в которой используется проект PDFSharp , который по сути лицензирован MIT.

Код очень прост, мне нужна утилита 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]);
    }
}
25 голосов
/ 20 февраля 2014

Вот одна функция, которая объединит X количество PDF-файлов, используя PDFSharp

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);
    }
}
4 голосов
/ 30 апреля 2009

PDFsharp позволяет объединять несколько документов PDF в один.

И то же самое возможно с ITextSharp .

3 голосов
/ 03 марта 2014

Я использовал 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;
    }
}
3 голосов
/ 21 сентября 2016

Это то, что я понял, и хотел поделиться с вами.

    public static byte[] MergePdf(List<byte[]> pdfs)
    {
        List<PdfSharp.Pdf.PdfDocument> lstDocuments = new List<PdfSharp.Pdf.PdfDocument>();
        foreach (var pdf in pdfs)
        {
            lstDocuments.Add(PdfReader.Open(new MemoryStream(pdf), PdfDocumentOpenMode.Import));
        }

        using (PdfSharp.Pdf.PdfDocument outPdf = new PdfSharp.Pdf.PdfDocument())
        { 
            for(int i = 1; i<= lstDocuments.Count; i++)
            {
                foreach(PdfSharp.Pdf.PdfPage page in lstDocuments[i-1].Pages)
                {
                    outPdf.AddPage(page);
                }
            }

            MemoryStream stream = new MemoryStream();
            outPdf.Save(stream, false);
            byte[] bytes = stream.ToArray();

            return bytes;
        }           
    }
2 голосов
/ 01 мая 2009

Здесь уже есть несколько хороших ответов, но я подумал, что мог бы упомянуть, что pdftk может быть полезно для этой задачи. Вместо того, чтобы создавать один PDF-файл напрямую, вы можете создать каждый необходимый вам PDF-файл, а затем объединить их вместе в качестве пост-процесса с pdftk. Это можно сделать даже изнутри вашей программы, используя вызов system () или ShellExecute ().

1 голос
/ 12 декабря 2016

Я объединил два приведенных выше, потому что мне нужно было объединить 3 pdfbytes и вернуть байт

internal static byte[] mergePdfs(byte[] pdf1, byte[] pdf2,byte[] pdf3)
        {
            MemoryStream outStream = new MemoryStream();
            using (Document document = new Document())
            using (PdfCopy copy = new PdfCopy(document, outStream))
            {
                document.Open();
                copy.AddDocument(new PdfReader(pdf1));
                copy.AddDocument(new PdfReader(pdf2));
                copy.AddDocument(new PdfReader(pdf3));
            }
            return outStream.ToArray();
        } 
1 голос
/ 27 июня 2016

Объединение двух byte[] с использованием iTextSharp до версии 5.x:

internal static MemoryStream mergePdfs(byte[] pdf1, byte[] pdf2)
{
    MemoryStream outStream = new MemoryStream();
    using (Document document = new Document())
    using (PdfCopy copy = new PdfCopy(document, outStream))
    {
        document.Open();
        copy.AddDocument(new PdfReader(pdf1));
        copy.AddDocument(new PdfReader(pdf2));
    }
    return outStream;
}

Вместо byte[] можно также передать Stream

1 голос
/ 30 апреля 2009

Вот ссылка на пример с использованием PDFSharp и ConcatenateDocuments

1 голос
/ 01 мая 2009

Я знаю, что многие люди рекомендовали PDF Sharp, однако, похоже, что этот проект не обновлялся с июня 2008 года. Кроме того, источник недоступен.

Лично я играл с iTextSharp, с которым было довольно легко работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...