Hintergrund: Ich muss meinen Vertriebsmitarbeitern ein wöchentliches Berichtspaket zur Verfügung stellen. Dieses Paket enthält mehrere (5-10) Kristallberichte.
Problem: Ich möchte einem Benutzer erlauben, alle Berichte auszuführen und auch nur einen einzigen Bericht auszuführen. Ich dachte, ich könnte dies tun, indem ich die Berichte erstelle und dann:
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");
}
Dies würde mir einen Ordner mit den Berichten zur Verfügung stellen, aber ich möchte jedem ein einzelnes PDF mit allen wöchentlichen Berichten per E-Mail senden. Also muss ich sie kombinieren.
Gibt es eine einfache Möglichkeit, dies zu tun, ohne weitere Steuerelemente von Drittanbietern zu installieren? Ich habe bereits DevExpress & CrystalReports und möchte lieber nicht zu viele hinzufügen.
Wäre es am besten, sie in der foreach-Schleife oder in einer separaten Schleife zu kombinieren? (oder ein anderer Weg)
Antworten:
Ich musste ein ähnliches Problem lösen und am Ende habe ich ein kleines PDF-Dienstprogramm erstellt, das das PDFSharp- Projekt verwendet, das im Wesentlichen MIT-lizenziert ist.
Der Code ist denkbar einfach. Ich brauchte ein Cmdline-Dienstprogramm, damit ich mehr Code zum Parsen der Argumente habe als für das Zusammenführen von PDFs:
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]); } }
quelle
Hier ist eine einzelne Funktion, mit der X PDF-Dateien mit PDFSharp zusammengeführt werden
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); } }
quelle
Dies ist etwas, das ich herausgefunden habe und mit Ihnen teilen wollte.
Hier können Sie mehrere PDFs in einem zusammenfügen (in der Reihenfolge der Eingabeliste).
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; } }
quelle
Ich habe iTextsharp mit c # verwendet, um PDF-Dateien zu kombinieren. Dies ist der Code, den ich verwendet habe.
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; } }
quelle
PDFsharp scheint das Zusammenführen mehrerer PDF-Dokumente zu einem zu ermöglichen.
Dasselbe ist auch mit ITextSharp möglich .
quelle
Hier gibt es bereits einige gute Antworten, aber ich dachte, ich könnte erwähnen, dass pdftk für diese Aufgabe nützlich sein könnte. Anstatt ein PDF direkt zu erstellen, können Sie jedes benötigte PDF erstellen und dann als Nachbearbeitung mit pdftk kombinieren. Dies kann sogar innerhalb Ihres Programms mit einem system () - oder ShellExecute () -Aufruf erfolgen.
quelle
Kombinieren Sie zwei
byte[]
mit iTextSharp bis Version 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; }
Anstelle der
byte[]
's ist es möglich, auchStream
' s zu bestehenquelle
Ich habe die beiden oben kombiniert, weil ich 3 pdfbytes zusammenführen und ein Byte zurückgeben musste
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(); }
quelle
Hier ist ein Beispiel mit 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(); } } }
Der PdfReader-Konstruktor weist viele Überladungen auf. Es ist möglich , den Parametertyp ersetzen
IEnumerable<string>
mitIEnumerable<Stream>
und es sollte auch funktionieren. Beachten Sie, dass die Methode den OutputStream nicht schließt, sondern diese Aufgabe an den Stream-Ersteller delegiert.quelle
Hier ist ein Link zu einem Beispiel mit PDFSharp und ConcatenateDocuments
quelle
Hier die Lösung http://www.wacdesigns.com/2008/10/03/merge-pdf-files-using-c Es verwendet kostenlose Open-Source-iTextSharp-Bibliothek http://sourceforge.net/projects/itextsharp
quelle
Ich habe das mit PDFBox gemacht. Ich nehme an, es funktioniert ähnlich wie iTextSharp.
quelle
Sie könnten pdf-shuffler gtk-apps.org versuchen
quelle
Ich weiß, dass viele Leute PDF Sharp empfohlen haben, aber es sieht nicht so aus, als ob das Projekt seit Juni 2008 aktualisiert wurde. Außerdem ist die Quelle nicht verfügbar.
Persönlich habe ich mit iTextSharp gespielt, mit dem man ziemlich einfach arbeiten konnte.
quelle
A bekommt Verfahren folgende
List
vonbyte
Array , das PDF istbyte
Array und gibt dann einbyte
Array.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(); } } }
Das Ergebnis der
PdfHelper.PdfConcat
Methode wird also an diePdfHelper.DownloadAsPdfFile
Methode übergeben.PS: Ein
NuGet
Paket mit dem Namen[PdfSharp][1]
muss installiert werden. Also imPackage Manage Console
Fenstertyp:quelle
Die folgende Methode führt zwei PDFs (f1 und f2) mit iTextSharp zusammen. Das zweite PDF wird nach einem bestimmten Index von f1 angehängt.
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(); } }
quelle
Um ein ähnliches Problem zu lösen, habe ich iTextSharp wie folgt verwendet:
//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();
quelle