0

I am using iTextSharp to create pdf. I have 100k records, but I am getting following exception:

An exception of type 'System.OutOfMemoryException' occurred in itextsharp.dll but was not handled in user code At the line: bodyTable.AddCell(currentProperty.GetValue(lst, null).ToString());

Code is:

var doc = new Document(pageSize);

PdfWriter.GetInstance(doc, stream);
doc.Open();

//Get exportable count
int columns = 0;

Type currentType = list[0].GetType();

//PREPARE HEADER
//foreach visible columns check if current object has proerpty
//else search in inner properties
foreach (var visibleColumn in visibleColumns)
{
    if (currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
    {
        columns++;
    }
    else
    {
        //check child property objects
        var childProperties = currentType.GetProperties();
        foreach (var prop in childProperties)
        {
            if (prop.PropertyType.BaseType == typeof(BaseEntity))
            {
                if (prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
                {
                    columns++;
                    break;
                }
            }
        }
    }
}


//header
var headerTable = new PdfPTable(columns);
headerTable.WidthPercentage = 100f;

foreach (var visibleColumn in visibleColumns)
{
    if (currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
    {
        //headerTable.AddCell(prop.Name);
        headerTable.AddCell(visibleColumn.Value);
    }
    else
    {
        //check child property objects
        var childProperties = currentType.GetProperties();
        foreach (var prop in childProperties)
        {
            if (prop.PropertyType.BaseType == typeof(BaseEntity))
            {
                if (prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null)
                {
                    //headerTable.AddCell(prop.Name);
                    headerTable.AddCell(visibleColumn.Value);
                    break;
                }
            }
        }
    }
}

doc.Add(headerTable);

var bodyTable = new PdfPTable(columns);
bodyTable.Complete = false;
bodyTable.WidthPercentage = 100f;

//PREPARE DATA
foreach (var lst in list)
{
    int col = 1;
    foreach (var visibleColumn in visibleColumns)
    {
        var currentProperty = currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key);
        if (currentProperty != null)
        {
            if (currentProperty.GetValue(lst, null) != null)
                bodyTable.AddCell(currentProperty.GetValue(lst, null).ToString());
            else
                bodyTable.AddCell(string.Empty);

            col++;
        }
        else
        {
            //check child property objects
            var childProperties = currentType.GetProperties().Where(p => p.PropertyType.BaseType == typeof(BaseEntity));
            foreach (var prop in childProperties)
            {
                currentProperty = prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key);
                if (currentProperty != null)
                {
                    var currentPropertyObjectValue = prop.GetValue(lst, null);
                    if (currentPropertyObjectValue != null)
                    {
                        bodyTable.AddCell(currentProperty.GetValue(currentPropertyObjectValue, null).ToString());
                    }
                    else
                    {
                        bodyTable.AddCell(string.Empty);
                    }
                    break;
                }
            }
        }
    }
}

doc.Add(bodyTable);

doc.Close();
3
  • A stack trace would be useful. Also, what's the size of the data involved. One lakh == 10000 right? But how big is each record? How much memory does the system have in total? Perhaps it is a genuine case of the computer running out of memory. Commented May 24, 2016 at 7:19
  • one lakh = 100000. Means 100000 rows and 40 columns. Each cell containing approx 20 character data. My System is having 8 GB RAM. Commented May 24, 2016 at 7:27
  • What is a lakh? I have never heard that word before. Commented May 24, 2016 at 17:49

1 Answer 1

1

A back of the envelope computation of the memory requirements given the data you provided for memory consumption gives 100000 * 40 * (2*20+4) = 167MBs. Well within your memory limit, but it is just a lower bound. I imagine each Cell object is pretty big. If each cell would have a 512 byte overhead you could be well looking at 2GB taken. I reckon it might be even more, as PDF is a complex beast.

So you might realistically be looking at a situation where you are actually running out of memory. If not your computers, then at least the bit C# has set aside for its own thing.

I would do one thing first - check memory consumption like here. You might even do well to try with 10, 100, 1000, 10000, 100000 rows and see up until what number of rows the program works.

You could perhaps try a different thing altogether. If you're trying to print a nicely formatted table with a lot of data, perhaps you could output an HTML document, which can be done incrementally and which you can do by just writing stuff to a file, rather than using a third party library. You can then "print" that HTML document to PDF. StackOverflow to the rescue again with this problem.

Sign up to request clarification or add additional context in comments.

2 Comments

It's not Java but .NET, so you may want to modify your answer.
@AmedeeVanGasse oops, that's a funny mistake to make. Thanks for pointing it out. I changed the suggestions to C#. Like before, it's not a solution, but rather some avenues for investigation which might help Sachin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.