简体   繁体   English

标记约1500页时,iTextSharp内存不足异常

[英]iTextSharp Out of Memory Exception when stamping over ~1500 pages

I am attempting to create a single pdf document from a list of approximately 5000 forms that I am stamping from a list of objects in my ASP.NET MVC website written in C#. 我正在尝试从大约5000种表格创建单个pdf文档,这些表格是我用C#编写的ASP.NET MVC网站中的对象列表加盖的。 I am getting an Out of Memory Exception once I perform the stamping process of approximately 1500 forms. 一旦执行大约1500种表单的标记过程,就会收到“内存不足异常”。 If I restrict my list of objects to under 1500 objects I do not get the error. 如果我将对象列表限制在1500个以下,则不会出现此错误。

Here is the data object which mimics the form data: 这是模仿表单数据的数据对象:

public class MyPageData
{
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal DueAmount { get; set; }
    public decimal PaidAmount { get; set; }
}

The code to create the document. 创建文档的代码。 NOTE The template is a pdf form and the Stream is a FileStream object created with write access and no file sharing. 注意模板是pdf格式,流是具有写访问权限且没有文件共享的FileStream对象。

public class DocumentBuilder
{
    public static void FillDocument(IList<MyPageData> pages, string template, Stream outputFile)
    {
        using (Document document = new Document())
        {
            using (PdfSmartCopy copy = new PdfSmartCopy(document, outputFile))
            {
                document.Open();
                foreach (var page in pages)
                {
                    PdfReader reader = new PdfReader(StampPage(template, page));
                    copy.AddPage(copy.GetImportedPage(reader, 1));
                    copy.FreeReader(reader);
                }
            }
        }
    }

    private static byte[] StampPage(string template, MyPageData page)
    {
        PdfReader reader = new PdfReader(template);
        using (MemoryStream stream = new MemoryStream())
        {
            using (PdfStamper stamper = new PdfStamper(reader, stream))
            {
                AcroFields fields = stamper.AcroFields;
                FillFields(fields, page);
                stamper.FormFlattening = true;
                stamper.Writer.Flush();
            }
            return stream.ToArray();
        }
    }

    private static void FillFields(AcroFields fields, MyPageData page)
    {
        fields.SetField("Name", page.Name);
        fields.SetField("Description", page.Description);
        fields.SetField("DueAmount", page.DueAmount.ToString());
        fields.SetField("PaidAmout", page.PaidAmount.ToString());
    }
}

I have been all over the iText and iTextSharp document and I believe my code is correct. 我遍历了iText和iTextSharp文档,我相信我的代码是正确的。 I did attempt to zip the document as demonstrated Here but the error is still thrown when stamping. 我确实尝试按此处所示的方式压缩文档,但是在盖章时仍会引发错误。 Any thoughts or suggestion? 有什么想法或建议吗?

(not an answer - yet) (尚未找到答案)

I just tried your code with the following which runs 5,000 without issue for me. 我只是用下面的代码尝试了您的代码,该代码对我来说可以正常运行5,000。 The first block creates a template to match your's, the second block populates some sample data base on your class and the third actually implements your logic. 第一个块创建一个与您的模板匹配的模板,第二个块填充您的类的一些示例数据库,第三个块实际实现您的逻辑。 Is there anything drastically different between your code and this? 您的代码与此之间有什么大不同吗? Does this give you an OOM exception? 这会给您一个OOM异常吗?

//Creates our sample template
var templateFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "template.pdf");
using (var fs = new FileStream(templateFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, fs)) {
            doc.Open();

            var fields = new string[] { "Name", "Description", "DueAmount", "PaidAmout" };
            var y = 700;
            foreach (var f in fields) {
                var tf = new TextField(writer, new iTextSharp.text.Rectangle(100, y, 400, y + 50), f);
                writer.AddAnnotation(tf.GetTextField());
                y -= 200;
            }

            doc.Close();
        }
    }
}

//Create our final PDF
var pages = new List<MyPageData>();
for (decimal i = 0; i < 5000; i++) {
    pages.Add(new MyPageData() { Name = "Chris", Description = "Cheese", DueAmount = i, PaidAmount = i * 0.5m });
}

//Create our file
var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "output.pdf");
using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    DocumentBuilder.FillDocument(pages, templateFile, fs);
}

EDIT 编辑

I upped it to 75 fields and although it takes a lot longer I still don't get an OOM. 我将其扩展到75个字段,尽管花费了更长的时间,但我仍然没有获得OOM。 For testing, I changed your MyPageData class to: 为了进行测试,我将您的MyPageData类更改为:

public class MyPageData {
    public string[] StringData { get; set; }
}

And your DocumentBuilder 's FillFields to: 而您的DocumentBuilderFillFields可以:

private static void FillFields(AcroFields fields, MyPageData page) {
    var fieldCount = 75;
    for (var j = 0; j < fieldCount; j++) {
        fields.SetField("Field_" + j.ToString(), page.StringData[j]);
    }
}

And my template and sample data creation to: 我的模板和示例数据创建为:

var fieldCount = 75;

//Creates our sample template
var templateFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "template.pdf");
using (var fs = new FileStream(templateFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (var doc = new Document()) {
        using (var writer = PdfWriter.GetInstance(doc, fs)) {
            doc.Open();

            var y = 800;
            //Create 75 fields
            for (var j = 0; j < fieldCount; j++) {
                var tf = new TextField(writer, new iTextSharp.text.Rectangle(100, y, 400, y + 10), "Field_" + j.ToString());
                tf.Options = tf.Options | TextField.MULTILINE;
                writer.AddAnnotation(tf.GetTextField());
                y -= 10;
            }

            doc.Close();
        }
    }
}

//Create our sample data
var pages = new List<MyPageData>();
for (decimal i = 0; i < 5000; i++) {
    var stringData = new List<string>();
    for (var j = 0; j < fieldCount; j++) {
        stringData.Add("Data_" + j.ToString());
    }
    pages.Add(new MyPageData() { StringData = stringData.ToArray() });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 StringWriter内存超出范围异常 - StringWriter memory out of bounds exception System.Drawing.Image中的内存不足异常 - Out of memory exception in System.Drawing.Image 使用MVC的StringWriter上的内存不足异常,可以增加内存吗? - out of memory exception on StringWriter using MVC, can memory be increased? 遍历集合时的实体框架异常 - Entity Framework Exception when iterating over collection 异步上载和调整多个图像大小时的内存不足异常 - Out of Memory exception while uploading and resizing multiple images asynchronously 从MVC下载EPPlus Excel导致内存不足异常 - EPPlus Excel download from MVC causes an out of memory exception 内存不足异常或Oracle Unexcepted数据包读取错误 - Out of memory exception or Oracle Unexcepted packet read error 将数据从一个数据库复制到另一个数据库-内存不足异常 - Copying data from one database to another - Out of Memory Exception 如何增加分配的内存? {由于内存不足异常,功能评估被禁用。} - How to increase allocated memory ? {The function evaluation was disabled because of an out of memory exception.} 上载具有更大大小的文件,使用ajax和MVC抛出内存不足异常 - Upload file, which has more size, throwing out of memory exception using ajax and MVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM