简体   繁体   中英

An exception of type 'System.OutOfMemoryException' occurred in itextsharp.dll but was not handled in user code

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();

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM