I'm writing a report with a lot of content, and the size of pdf is getting way bigger to write on the server memory.
Right now I'm running a test with over 5 million records (real production case), the data itself takes almost 4.5GB, the pdf is now writing the registries around the 3.5 million, and the memory use of the application is on 35GB.
It's running very slow now because the memory of the server is on 95% of use.
My code looks like that:
Console.WriteLine("Gathering Data");
DataTable dt = functionthatgathersdata();
Document document = new Document(PageSize.A4.Rotate(), 0f, 0f, 140f, 70f);
using (FileStream ms = new FileStream(@"E:\rel.pdf", FileMode.Create))
{
PdfWriter writer = PdfWriter.GetInstance(document, ms);
writer.PageEvent = new PageTemplateReport()
{
attr = "report header"
};
document.Open();
iTextSharp.text.Font font5 = iTextSharp.text.FontFactory.GetFont(FontFactory.HELVETICA, 8);
PdfPTable table = new PdfPTable(dt.Columns.Count - 1);
float[] widths = new float[] { 50f, 100f, 40f, 50f, 50f, 50f, 130f, 50f, 50f, 28f, 35f };
table.SetWidths(widths);
table.WidthPercentage = 95f;
table.HeaderRows = 1;
PdfPCell cell = new PdfPCell(new Phrase("Report"));
cell.Colspan = dt.Columns.Count - 1;
table.AddCell(new Phrase("col1", font5));
table.AddCell(new Phrase("col2", font5));
table.AddCell(new Phrase("col3", font5));
table.AddCell(new Phrase("col4", font5));
table.AddCell(new Phrase("col5", font5));
table.AddCell(new Phrase("col6", font5));
table.AddCell(new Phrase("col7", font5));
table.AddCell(new Phrase("col8", font5));
table.AddCell(new Phrase("col9", font5));
table.AddCell(new Phrase("col10", font5));
table.AddCell(new Phrase("col11", font5));
var i = 0;
foreach (DataRow r in dt.Rows)
{
i++;
Console.WriteLine(i.ToString() + " of " + dt.Rows.Count + " " + "size: " + ms.Length / 1024 + "KB");
if (dt.Rows.Count > 0)
{
table.AddCell(new Phrase(r[0].ToString(), font5));
table.AddCell(new Phrase(r[1].ToString(), font5));
table.AddCell(new Phrase(r[2].ToString(), font5));
table.AddCell(new Phrase(r[3].ToString(), font5));
table.AddCell(new Phrase(r[4].ToString(), font5));
table.AddCell(new Phrase(r[5].ToString(), font5));
table.AddCell(new Phrase(r[7].ToString(), font5));
table.AddCell(new Phrase(r[8].ToString(), font5));
table.AddCell(new Phrase("", font5));
table.AddCell(new Phrase(r[10].ToString(), font5));
table.AddCell(new Phrase((r[11].ToString() == string.Empty) ? "" : Convert.ToDecimal(r[11].ToString()).ToString("N2") + " KB", font5));
}
}
document.Add(table);
ms.Close();
}
For the data part I can solve the problem gathering chunks of data, writing it and them disposing to get another chunk.
For the pdf part, I want to know if there is a way to write the data directly on the disk, instead of manipulate it from memory.