Объедините два (или более) 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 ]

0 голосов
/ 14 июня 2019

Чтобы решить подобную проблему, я использовал iTextSharp так:

//Create the document which will contain the combined PDF's
Document document = new Document();

//Create a writer for de document
PdfCopy writer = new PdfCopy(document, new FileStream(OutPutFilePath, FileMode.Create));
if (writer == null)
{
     return;
}

//Open the document
document.Open();

//Get the files you want to combine
string[] filePaths = Directory.GetFiles(DirectoryPathWhereYouHaveYourFiles);
foreach (string filePath in filePaths)
{
     //Read the PDF file
     using (PdfReader reader = new PdfReader(vls_FilePath))
     {
         //Add the file to the combined one
         writer.AddDocument(reader);
     }
}

//Finally close the document and writer
writer.Close();
document.Close();
0 голосов
/ 17 августа 2018

Следующий метод объединяет два файла PDF (f1 и f2), используя iTextSharp. Второй pdf добавляется после определенного индекса f1.

 string f1 = "D:\\a.pdf";
 string f2 = "D:\\Iso.pdf";
 string outfile = "D:\\c.pdf";
 appendPagesFromPdf(f1, f2, outfile, 3);




  public static void appendPagesFromPdf(String f1,string f2, String destinationFile, int startingindex)
        {
            PdfReader p1 = new PdfReader(f1);
            PdfReader p2 = new PdfReader(f2);
            int l1 = p1.NumberOfPages, l2 = p2.NumberOfPages;


            //Create our destination file
            using (FileStream fs = new FileStream(destinationFile, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                Document doc = new Document();

                PdfWriter w = PdfWriter.GetInstance(doc, fs);
                doc.Open();
                for (int page = 1; page <= startingindex; page++)
                {
                    doc.NewPage();
                    w.DirectContent.AddTemplate(w.GetImportedPage(p1, page), 0, 0);
                    //Used to pull individual pages from our source

                }//  copied pages from first pdf till startingIndex
                for (int i = 1; i <= l2;i++)
                {
                    doc.NewPage();
                    w.DirectContent.AddTemplate(w.GetImportedPage(p2, i), 0, 0);
                }// merges second pdf after startingIndex
                for (int i = startingindex+1; i <= l1;i++)
                {
                    doc.NewPage();
                    w.DirectContent.AddTemplate(w.GetImportedPage(p1, i), 0, 0);
                }// continuing from where we left in pdf1 

                doc.Close();
                p1.Close();
                p2.Close();

            }
        }
0 голосов
/ 06 сентября 2017

Вот пример использования iTextSharp

public static void MergePdf(Stream outputPdfStream, IEnumerable<string> pdfFilePaths)
{
    using (var document = new Document())
    using (var pdfCopy = new PdfCopy(document, outputPdfStream))
    {
        pdfCopy.CloseStream = false;
        try
        {
            document.Open();
            foreach (var pdfFilePath in pdfFilePaths)
            {
                using (var pdfReader = new PdfReader(pdfFilePath))
                {
                    pdfCopy.AddDocument(pdfReader);
                    pdfReader.Close();
                }
            }
        }
        finally
        {
            document?.Close();
        }
    }
}

Конструктор PdfReader имеет много перегрузок. Можно заменить тип параметра IEnumerable<string> на IEnumerable<Stream>, и он также должен работать. Обратите внимание, что метод не закрывает OutputStream, он делегирует эту задачу создателю Stream.

0 голосов
/ 30 мая 2017

Следующий метод получает массив List из byte, который является массивом PDF byte, а затем возвращает массив byte.

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

public static class PdfHelper
{
    public static byte[] PdfConcat(List<byte[]> lstPdfBytes)
    {
        byte[] res;

        using (var outPdf = new PdfDocument())
        {
            foreach (var pdf in lstPdfBytes)
            {
                using (var pdfStream = new MemoryStream(pdf))
                using (var pdfDoc = PdfReader.Open(pdfStream, PdfDocumentOpenMode.Import))
                    for (var i = 0; i < pdfDoc.PageCount; i++)
                        outPdf.AddPage(pdfDoc.Pages[i]);
            }

            using (var memoryStreamOut = new MemoryStream())
            {
                outPdf.Save(memoryStreamOut, false);

                res = Stream2Bytes(memoryStreamOut);
            }
        }

        return res;
    }

    public static void DownloadAsPdfFile(string fileName, byte[] content)
    {
        var ms = new MemoryStream(content);

        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.ContentType = "application/pdf";
        HttpContext.Current.Response.AddHeader("content-disposition", $"attachment;filename={fileName}.pdf");
        HttpContext.Current.Response.Buffer = true;
        ms.WriteTo(HttpContext.Current.Response.OutputStream);
        HttpContext.Current.Response.End();
    }

    private static byte[] Stream2Bytes(Stream input)
    {
        var buffer = new byte[input.Length];
        using (var ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                ms.Write(buffer, 0, read);

            return ms.ToArray();
        }
    }
}

Итак, результат метода PdfHelper.PdfConcat передается методу PdfHelper.DownloadAsPdfFile.

PS: NuGet пакет с именем [PdfSharp][1] должен быть установлен. Так в Package Manage Console окне типа:

Install-Package PdfSharp

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

Вы можете попробовать pdf-shuffler gtk-apps.org

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

Я сделал это с PDFBox. Я полагаю, что это работает так же, как iTextSharp.

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

Здесь решение http://www.wacdesigns.com/2008/10/03/merge-pdf-files-using-c Он использует бесплатную библиотеку iTextSharp с открытым исходным кодом http://sourceforge.net/projects/itextsharp

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