C# 从现有模板创建新的PDF——在AcROCAT席中的奇数行为

C# 从现有模板创建新的PDF——在AcROCAT席中的奇数行为,c#,.net,pdf,itextsharp,C#,.net,Pdf,Itextsharp,我正在从LibreOffice中创建的现有模板生成一个新的PDF。它包含一个文本框 < >代码编译并成功保存PDF到一个新文件后,如果我在AcabaLeader席XI中打开新创建的文档,它就正确地呈现,但是,即使我不修改最终文档,在关闭文档时,它会问“您想保存更改”文件名吗?PDF“在关闭之前”< /P> 我阅读了StackOverflow及其官方网站(iTextSharp)上的其他帖子,并找到了一个解决方案,可能是我以错误的方式实现的 public string spdftemplat

我正在从LibreOffice中创建的现有模板生成一个新的PDF。它包含一个文本框

< >代码编译并成功保存PDF到一个新文件后,如果我在AcabaLeader席XI中打开新创建的文档,它就正确地呈现,但是,即使我不修改最终文档,在关闭文档时,它会问“您想保存更改”文件名吗?PDF“在关闭之前”< /P> 我阅读了StackOverflow及其官方网站(iTextSharp)上的其他帖子,并找到了一个解决方案,可能是我以错误的方式实现的

    public string spdftemplate = @"C:\test\input.pdf";
    public string newFile = @"C:\test\output.pdf";

    private void FillFormsProperly()
    {

        PdfReader reader = new PdfReader(spdftemplate);
        byte[] bytes;
        using (MemoryStream ms = new MemoryStream())
        {
            PdfStamper stamper = new PdfStamper(reader, ms);

            #region ForTesting
            //PdfContentByte cb = stamper.GetOverContent(1);
            //ColumnText ct = new ColumnText(cb);
            //ct.SetSimpleColumn(100, 100, 500, 200);
            //ct.AddElement(new Paragraph("This was added using ColumnText"));
            //ct.Go();
            #endregion ForTesting

            AcroFields pdfFormFields = stamper.AcroFields;

            foreach (DictionaryEntry de in reader.AcroFields.Fields)
            {
                pdfFormFields.SetField(de.Key.ToString(), "test"); //"Text Box 1"
            }

            //string sTmp = "W-4 Completed for " + pdfFormFields.GetField("Text Box 1");
            //MessageBox.Show(sTmp, "Finished");

            //Flush the PdfStamper's buffer
            stamper.FormFlattening = true;
            stamper.Close();
            //Get the raw bytes of the PDF
            bytes = ms.ToArray();

        }

        //Do whatever you want with the bytes
        //Below I'm writing them to disk 
        using (FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            fs.Write(bytes, 0, bytes.Length);
        }
    }
我找到的最佳答案是:

上面的代码是我的(复制粘贴或多或少)实现


很明显,文件已损坏(但仍然可读),如何修复此问题?

Your input.pdf包含一个表单字段和标志
/true
。您的output.pdf不再包含字段(显然……您毕竟压平了表单),但它仍然包含该标志
/needAppearancess true

此标志告诉PDF查看器(Acrobat Reader)为某些表单字段生成外观流。因此,读取器检查所有字段以在必要时创建外观。之后,它移除该标志。因此,文件随之发生变化;即使没有字段,至少标志移除是一种改变

这让人想起去年2月在iText中修复的一个iText问题:

在某些情况下,Adobe Reader X会询问您是否希望在关闭扁平化PDF表单后“保存更改”。这是由于/AcroForm字典中存在一些不必要的条目(例如,在使用OOo创建表单时添加的条目)

(iText修订版5089,2012年2月29日,blowagie)

该变更已在iTextSharp版本323(2012年3月3日)33中移植到iTextSharp


因此,您可能需要更新您使用的iTextSharp版本。

如果需要,我可以附加模板。请同时提供输入模板和输出文档。输入:输出:似乎LibreOffice有罪,输入PDF也会提示保存文件对话框。因此,我已经用最新版本的OOo和LO对此进行了测试。使用最新版本的itextsharp 5.4.4-在output.pdf中找不到文档中留下的一些指纹。请检查您使用的库。