保存 2 份 PDF 模板,第 2 个文件损坏 - iTextSharp

本文关键字:文件 损坏 iTextSharp PDF 模板 保存 | 更新日期: 2023-09-27 18:32:39

我有一个每页 60 个标签的 PDF 模板文件。 我的目标是根据需要制作模板的副本,填写表单数据,然后将文件合并到单个 PDF 中(或提供指向单个文件的链接......要么有效)

问题是无论日期如何,第二个PDF副本都会损坏。

工作流是用户选择一个日期。 当天的午餐订单被收集到一个通用列表中,该列表又用于填写模板上的表单字段。 在 60 时,该文件被保存为临时文件,并且模板的新副本用于接下来的 60 个名称,等等......

09/23/2013 至 09/25 有数据。 25日只有38个订单,所以这按预期工作。 在 09/24/2013 有超过 60 个订单, 第一页有效, 但第二页已损坏.

    private List<string> CreateLabels(DateTime orderDate)
{
    // create file name to save
    string fName = ConvertDateToStringName(orderDate) + ".pdf"; // example 09242013.pdf
    // to hold Temp File Names
    List<string> tempFNames = new List<string>(); 
    // Get path to template/save directory
    string path = Server.MapPath("~/admin/labels/");
    string pdfPath = path + "8195a.pdf"; // template file
    // Get the students and their lunch orders
    List<StudentLabel> labels = DalStudentLabel.GetStudentLabels(orderDate);

    // Get number of template pages needed
    decimal recCount = Convert.ToDecimal(labels.Count);
    decimal pages = Decimal.Divide(recCount, 60);
    int pagesNeeded = Convert.ToInt32(Math.Ceiling(pages));

    // Make the temp names
    for (int c = 0; c < pagesNeeded; c++)
    {
        tempFNames.Add(c.ToString() + fName); //just prepend a digit to the date string
    }
    //Create copies of the empty templates
    foreach (string tName in tempFNames)
    {
        try
        { File.Delete(path + tName); }
        catch { }
        File.Copy(pdfPath, path + tName);
    }
    // we know we need X pages and there is 60 per page
    int x = 0;
    // foreach page needed
    for (int pCount = 0; pCount < pagesNeeded; pCount++)
    {
        // Make a new page
        PdfReader newReader = new PdfReader(pdfPath);
        // pCount.ToString replicates temp names
        using (FileStream stream = new FileStream(path + pCount.ToString() + fName, FileMode.Open))
        {
            PdfStamper stamper = new PdfStamper(newReader, stream); 
            var form = stamper.AcroFields;
            var fieldKeys = form.Fields.Keys;
            StudentLabel lbl = null;
            string lblInfo = "";
            // fill in acro fields with lunch data
            foreach (string fieldKey in fieldKeys)
            {
                try
                {
                    lbl = labels[x];
                }
                catch 
                { 
                    break; 
                } // if we're out of labels, then we're done
                lblInfo = lbl.StudentName + "'n";
                lblInfo += lbl.Teacher + "'n";
                lblInfo += lbl.MenuItem;
                form.SetField(fieldKey, lblInfo);
                x++;
                if (x % 60 == 0)  // reached 60, time for new page
                {
                    break;
                }
            }
            stamper.Writer.CloseStream = false;
            stamper.FormFlattening = true;
            stamper.Close();
            newReader.Close();
            stream.Flush();
            stream.Close();
        }        
    }
    return tempFNames;
}

保存 2 份 PDF 模板,第 2 个文件损坏 - iTextSharp

为什么要

预先分配文件?我猜那是你的问题。您将PdfStamper绑定到PdfReader进行输入,并将同一 pdf 的精确副本绑定到FileStream对象以进行输出。PdfStamper将为您生成输出文件,您无需帮助。您正在尝试将新数据附加到现有文件中,我不太确定在这种情况下会发生什么(因为我从未真正见过有人这样做。

因此,请放弃整个File.Copy预分配,并将FileStream声明更改为:

using (FileStream stream = new FileStream(path + pCount.ToString() + fName, FileMode.Create, FileAccess.Write, FileShare.None))

显然,您还需要调整返回数组的填充方式。