2013-03-18 2 views
2

하나의 PdfTable로 구성된 ITextSharp를 사용하여 PDF를 만듭니다. 불행히도 특정 데이터 세트의 경우 메모리가 부족하여 많은 수의 PdfPCell이 작성되어 메모리 부족 현상이 발생합니다 (메모리 사용량을 프로파일 링했습니다 - 저는 거의 백만 개의 셀을가집니다)많은 셀이있는 PdfPTable의 메모리 소비를 줄이는 방법

그런 경우 메모리 사용을 줄일 수있는 방법이 있습니까?

Document document = Document(); 
FileStream stream = new FileStream(fileName,FileMode.Create);         
pdfWriter = PdfWriter.GetInstance(document, stream); 
document.Open(); 
PdfPTable table = new PdfPTable(nbColumnToDisplay); 
foreach (GridViewRow row in gridView.Rows) 
{ 
    j = 0; 
    for (int i = 0; i < gridView.HeaderRow.Cells.Count; i++) 
    { 
     PdfPCell cell = new PdfPCell(new Phrase(text)); 
     table.AddCell(cell); 
    } 
} 
document.Add(table); 
document.Close(); 
+1

코드를 공유 할 수 있습니까? –

답변

4

iTextSharp가 있습니다 내가

PDFWriter를가하여 FileStream을 기반으로합니다 (각 행 후) 여러 지점에서 세척 및 전체 압축 시도했습니다

코드는 거의 다음과 같습니다 PdfPTable이 구현하는 ILargeElement이라는 매우 멋진 인터페이스입니다. 문서에 따르면

/** 
* Interface implemented by Element objects that can potentially consume 
* a lot of memory. Objects implementing the LargeElement interface can 
* be added to a Document more than once. If you have invoked setCompleted(false), 
* they will be added partially and the content that was added will be 
* removed until you've invoked setCompleted(true); 
* @since iText 2.0.8 
*/ 

것은 그래서 당신이해야 할 모든 당신이 당신의 PdfPTable을 만든 후이며, false로 Complete 속성을 설정합니다. 내부 루프에서는 매번 한 번씩 테이블을 추가하여 메모리를 지우는 카운터의 일부 형식을 수행합니다. 그런 다음 루프 끝에 Complete을 true로 설정하고 한 번 더 추가하십시오.

다음은이를 보여주는 샘플 코드입니다. 카운터 검사를하지 않으면이 코드는 내 컴퓨터에서 약 500MB의 RAM을 사용합니다. 카운터가 1,000 개의 항목을 모두 확인하면 16MB RAM으로 줄어 듭니다. 당신은 카운터에 대한 자신의 달콤한 자리를 찾아야하고 그것은 평균적으로 각 셀에 얼마나 많은 텍스트를 추가하는지에 달려 있습니다.

string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "table.pdf"); 
Document document = new Document(); 
FileStream stream = new FileStream(fileName, FileMode.Create); 
var pdfWriter = PdfWriter.GetInstance(document, stream); 
document.Open(); 

PdfPTable table = new PdfPTable(4); 
table.Complete = false; 
for (int i = 0; i < 1000000; i++) { 
    PdfPCell cell = new PdfPCell(new Phrase(i.ToString())); 
    table.AddCell(cell); 
    if (i > 0 && i % 1000 == 0) { 
     Console.WriteLine(i); 
     document.Add(table); 
    } 
} 
table.Complete = true; 
document.Add(table); 
document.Close(); 
+0

+1 - 좋아 보이지만 버전 5.xxx에서만 사용 가능합니다. 4.5 버전이지만 업그레이드를 시도했지만 더 이상 라이브러리의 일부가 아니므로 RTFWriter를 잃어 버렸습니다! :-( –

+1

이 코드를 이식하는 것이 좋습니다. https://code.google.com/p/itextsharpmplmaint/source/browse/itext/iTextSharp/text/rtf/?r=49a4718630aae3eec4dee5180f0068381c5011b7#rtf –

+1

이 접근법은 iTextSharp에서 작동합니다 4.1.2 ILargeElement 인터페이스 사용하기 table.ElementComplete 속성이 있습니다 – dlxeon

0

PdfPTable pdftbale = 새로운 PdfPTable (gridview.HeaderRow.Cells.Count);

foreach (TableCell tabhead in gridview.HeaderRow.Cells) 
    { 
     PdfPCell pdfcell1 = new PdfPCell(new Phrase(tabhead.Text)); 
     pdftbale.AddCell(pdfcell1); 
    } 

    foreach (GridViewRow gd in gridview.Rows) 
    { 
     foreach (TableCell tab in gd.Cells) 
     { 
      PdfPCell pdfcell = new PdfPCell(new Phrase(tab.Text)); 
      pdftbale.AddCell(pdfcell); 
     } 
    } 

    iTextSharp.text.Document pdfDocument = new iTextSharp.text.Document(PageSize.A4, 10f, 10f, 10f, 10f); 
    PdfWriter.GetInstance(pdfDocument, new FileStream(Server.MapPath("~/pdf/" + DateTime.Now.ToString("ddMMyyyyhhmmss") + ".pdf"), FileMode.Create)); 
    pdfDocument.Open(); 
    pdfDocument.Add(pdftbale); 
    pdfDocument.Close(); 
+1

SO에 오신 것을 환영하며 답변 해 주셔서 감사합니다. 코드에 약간의 설명을 추가해 주시겠습니까? – Francesco

관련 문제