使用iTextSharp将数据写入PDF效果很好,但Acrobat Reader在关闭文件时询问"是否要保存更改"

mar*_*arc 6 c# pdf-generation itextsharp

我正在使用iTextSharp 5.3.2.0将信息添加到包含W-2表单的现有PDF文件中.一切都运行良好,PDF文件在写入浏览器的响应流时看起来很棒; 但是,当用户完成查看PDF时,他会被问到"你想在关闭之前将更改保存到'W2.pdf'吗?" 每次他从网页上查看文档.

在试图缩小问题范围时,我实际上已经删除了所有修改但问题仍在继续.这是我的代码的简单版本,我的数据写入调用已注释掉:

PdfReader pdfReader = new PdfReader(dataSource.ReportTemplate);

using(MemoryStream outputStream = new MemoryStream())
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
{
   //dataSource.DrawDataFields(pdfStamper);
   pdfStamper.FormFlattening = true;
   return outputStream;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,"空"PDF被写入浏览器并且看起来不错,但是当我关闭Acrobat窗口时,我仍然会被问到"你想保存吗".

在这一点上,我认为源PDF文件有问题.但是,当我将PDF文件的原始字节发送回浏览器时,在使用下面的代码时,我不会被问到"你想保存"的问题.

byte[] bytes = File.ReadAllBytes(dataSource.ReportTemplate);

using (MemoryStream outputStream = new MemoryStream())
{
    outputStream.Write(bytes, 0, bytes.Length);
    return outputStream;
}
Run Code Online (Sandbox Code Playgroud)

我的结论是iTextSharp在打开它并将字节写入流中的过程中对PDF做了一些"坏事",但我是iTextSharp的新手,很容易丢失一些东西.

FWIW,这是我们正在讨论的Acobat Reader 10.1.4.

编辑:用作模板的原始PDF大小约为80K.如果我查看通过浏览器流式传输的临时文件,iTextSharp编写的PDF文件大约为150K.但是,当我对Acrobat Reader提出的"保存更改"问题回答"是"时,生成的文件再次大约为80K.iTextSharp肯定会对这个文件做一些意想不到的事情.

mar*_*arc 15

非工作:

public byte[] MergeDataByDrawing(int copies)
{
    PdfReader pdfReader = new PdfReader(reportTemplate);

    using (MemoryStream outputStream = new MemoryStream())
    using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
    {
        pdfStamper.FormFlattening = true;
        return outputStream.GetBuffer();
    }
} 
Run Code Online (Sandbox Code Playgroud)

工作:

public byte[] MergeDataByDrawing(int copies)
{
    PdfReader pdfReader = new PdfReader(reportTemplate);

    using (MemoryStream outputStream = new MemoryStream())
    using (PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream))
    {
        pdfStamper.FormFlattening = true;
        return outputStream.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎GetBuffer方法是个问题.我不明白为什么,但我会接受结果!

道德指向MKL给我一个想法,Fredrik在正确的时间为正确的例子.

  • `MemoryStream.GetBuffer()`可能会为流中包含的实际数据添加垃圾.[参见文档](http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer.aspx).因此,当使用iTextSharp时,总是调用`ToArray()`. (2认同)
  • PDF从下到上阅读.PDF Reader期望最终字节为'%% EOF`.如果在最后一次出现'%% EOF'之后添加了其他字节,一些读者会尝试修复此问题.`ToArray()`修复你的问题吗?在这种情况下,没有必要向我发送PDF.为了确保你有正确的解决方案,你可以比较`GetBuffer()`vs`ToArray()`产生的字节数.如果`ToArray()`产生更少的字节,你就解决了这个问题. (2认同)