나는 모든 문서를 메모리에로드하거나 하나의 괴물 출력 PDF를 만들 필요가 없도록 스트리밍 방식으로 PDF 파일 (잠재적으로 그 중 1000 개)을 병합하려고합니다. 메모리에로드됩니다.iTextSharp를 사용하여 PDF 파일을 출력 스트림으로 병합
제 기능을 위해, 병합 할 모든 PDF가 들어있는 디렉토리 이름을 출력하려면 Stream
으로 작성하십시오.
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);
}
}
}
}
}
}
그러나이 코드를 실행하면 'System.ObjectDisposedException Exception : 닫힌 파일에 액세스 할 수 없습니다'라는 메시지가 나타납니다. 예외. 다음은 호출 스택입니다.
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
'PdfWriter'로 문서를 병합 하시겠습니까? 그 때문에 많은 문제가 발생합니다. [문서를 올바르게 병합하는 방법?] (http://developers.itextpdf.com/question/how-merge-documents-correctly) 참고 : 또한'PdfReader'를 암시 적으로 닫고 있습니다. 내가 너라면 iTextSharp를 사용하는 대신 C# 용 iText 7로 이동하겠다. 우리가 처음부터 iText를 다시 작성할 때 많은 것들이 향상되었습니다. –
@BrunoLowagie 귀하의 링크에서, 나는'PdfSmartCopy' 샘플을 사용한다고 가정합니까? 이 패턴을 따르는 경우, 생성 중에는 전체 출력 문서가 메모리에 있거나 출력 스트림에 '스트리밍'된 문서가 생성됩니까? – Terry
iText는 최대한 많은 페이지를 출력 스트림에 스트리밍하려고 시도하지만 독자 인스턴스를 해제하는 것과 같은 개념을 사용해야합니다. 'freeReader()'메소드를 찾는다. 이 방법을 사용하지 않으면 모든 리더 인스턴스가 많은 메모리를 소비합니다. –