Ich versuche, PDF-Dateien (potenziell 1000 von ihnen) in einer Streaming-Mode zu verschmelzen, so dass ich nicht alle Dokumente in den Speicher laden oder erstellen Sie ein Monster PDF-Ausgabe ist in den Speicher geladen.PDF-Dateien mit iTextSharp in Ausgabe-Stream verschmelzen
Für meine Funktion gebe ich einfach einen Verzeichnisnamen, der alle PDFs enthält zusammen mit einer Ausgabe Stream
zu schreiben, um zu schreiben.
private void MergePDFDocuments(string batchFilesFolder, Stream outputStream)
{
using (var batchDocument = new iTextSharp.text.Document())
using (var writer = iTextSharp.text.pdf.PdfWriter.GetInstance(batchDocument, outputStream))
{
batchDocument.Open();
var cb = writer.DirectContent;
foreach (var file in new DirectoryInfo(batchFilesFolder).GetFiles("*.pdf"))
{
// we create a reader for the document
using (var reader = new iTextSharp.text.pdf.PdfReader(file.FullName))
{
int i = 0;
while (i < reader.NumberOfPages)
{
i++;
batchDocument.SetPageSize(reader.GetPageSizeWithRotation(1));
batchDocument.NewPage();
var page = writer.GetImportedPage(reader, i);
var rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
}
}
}
}
Allerdings, wenn ich diesen Code ausführen, erhalte ich eine ‚System.ObjectDisposedException Ausnahme: Es kann keine geschlossene Datei zugreifen zu können.‘ Ausnahme. Hier ist der Aufruf-Stack.
at System.IO.__Error.FileNotOpen()
at System.IO.FileStream.get_Position()
at iTextSharp.text.io.RAFRandomAccessSource.Get(Int64 position, Byte[] bytes, Int32 off, Int32 len)
at iTextSharp.text.io.IndependentRandomAccessSource.Get(Int64 position, Byte[] bytes, Int32 off, Int32 len)
at iTextSharp.text.pdf.RandomAccessFileOrArray.Read(Byte[] b, Int32 off, Int32 len)
at iTextSharp.text.pdf.RandomAccessFileOrArray.ReadFully(Byte[] b, Int32 off, Int32 len)
at iTextSharp.text.pdf.RandomAccessFileOrArray.ReadFully(Byte[] b)
at iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw(PRStream stream, RandomAccessFileOrArray file)
at iTextSharp.text.pdf.PdfReader.GetStreamBytesRaw(PRStream stream)
at iTextSharp.text.pdf.PRStream.ToPdf(PdfWriter writer, Stream os)
at iTextSharp.text.pdf.PdfIndirectObject.WriteTo(Stream os)
at iTextSharp.text.pdf.PdfWriter.PdfBody.Write(PdfIndirectObject indirect, Int32 refNumber, Int32 generation)
at iTextSharp.text.pdf.PdfWriter.PdfBody.Add(PdfObject objecta, Int32 refNumber, Int32 generation, Boolean inObjStm)
at iTextSharp.text.pdf.PdfWriter.AddToBody(PdfObject objecta, PdfIndirectReference refa)
at iTextSharp.text.pdf.PdfReaderInstance.WriteAllPages()
at iTextSharp.text.pdf.PdfWriter.AddSharedObjectsToBody()
at iTextSharp.text.pdf.PdfWriter.Close()
at iTextSharp.text.pdf.PdfDocument.Close()
at iTextSharp.text.pdf.PdfWriter.Close()
at iTextSharp.text.DocWriter.Dispose()
at BTR.Evolution.Legacy.Jobs.BatchDocGen.MergePDFDocuments(String batchFilesFolder, Stream outputStream) in C:\BTR\Source\Evolution\BTR.Evolution\Legacy.Jobs\BatchDocGen.cs:line 598
Dokument mit 'PdfWriter' zusammenführen? Das verursacht viele Probleme. Siehe [Wie Dokumente korrekt zusammengeführt werden?] (Http://developers.itextpdf.com/question/how-merge-documents-correctly) Außerdem: Sie schließen den 'PdfReader' implizit. Wenn ich Sie wäre, würde ich zu iText 7 für C# bewegen, anstatt iTextSharp zu verwenden. Viele Dinge haben sich verbessert, als wir iText von Grund auf neu geschrieben haben. –
@BrunoLowagie Von Ihrem Link nehme ich an, ich würde das 'PdfSmartCopy'-Beispiel verwenden? Wenn dieses Muster folgt, befindet sich das gesamte Ausgabedokument während der Erstellung im Speicher oder wird das Dokument in die Ausgabe "Stream" gestreamt? – Terry
iText wird versuchen, so viele Seiten wie möglich in den Ausgabestream zu streamen, aber Sie müssen Konzepte wie das Freigeben der Leserinstanz verwenden. Suchen Sie nach der 'freeReader()' Methode. Wenn Sie diese Methode nicht verwenden, verbrauchen alle Ihre Reader-Instanzen viel Speicher. –