是否有任何方法可以使用ABCpdf抑制“关闭之前是否要保存对xxx.pdf的更改”对话框

时间:2014-12-10 16:47:02

标签: abcpdf

我们正在使用ABCpdf阅读adobe表单模板,使用从数据库中检索的值填充表单字段并将其修改为单个PDF文档,并将文档作为文件流在HTTP响应中发送回ASP.net MVC中的用户应用

这种方法工作正常,PDF文档正在成功生成。但是,当用户选择打开生成的PDF文件并尝试将其关闭时,系统会在Adobe Acrobat中提示“是否要在关闭前保存对xxx.pdf的更改”对话框。有没有办法使用ABC pdf来抑制此消息?

以下是我们用于生成PDF的代码。

public byte[] GeneratePDF(Employee employee, String TemplatePath)
    {
        string[] FieldNames;
        Doc theDoc;
        MemoryStream MSgeneratedPDFFile = new MemoryStream();

        //Get the PDF Template and read all the form fields inside the template
        theDoc = new Doc();
        theDoc.Read(HttpContext.Current.Server.MapPath(TemplatePath));
        FieldNames = theDoc.Form.GetFieldNames();

        //Navigate through each Form field and populate employee details 
        foreach (string FieldName in FieldNames)
        {
            Field theField = theDoc.Form[FieldName];
            switch (FieldName)
            {
                case "Your_First_Name":
                    theField.Value = employee.FirstName;
                    break;
                default:
                    theField.Value = theField.Name;
                    break;
            }
            //Remove Form Fields and replace them with text
            theField.Focus();
            theDoc.Color.String = "240 240 255";
            theDoc.FillRect();
            theDoc.Rect.Height = 12;
            theDoc.Color.String = "220 0 0";
            theDoc.AddText(theField.Value);
            theDoc.Delete(theField.ID);
        }

        return theDoc.GetData();
    }

2 个答案:

答案 0 :(得分:2)

今天我也遇到了这个问题,但是使用了没有表单字段的PDF。我运行了@CharlieNoTomatoes代码,并确认FieldNames集合肯定为空。

我遍历了代码的各个阶段,发现如果将PDF保存到文件系统并从那里打开就可以了。从而将其范围缩小到采用abcpdf数据流并将其直接发送给用户的代码(我通常不会费心将其保存到磁盘上)。在WebSuperGoo docs中发现了此错误,这表明我的服务器可能在响应中发送了一些额外的垃圾,导致文件损坏。

添加Response.End();对我有用。生成的PDF文件不再显示该消息。

byte[] theData = _thisPdf.Doc.GetData();
var curr = HttpContext.Current;
curr.Response.Clear();
curr.Response.ContentType = "application/pdf";
curr.Response.AddHeader("Content-Disposition", "attachment; filename=blah.pdf");
curr.Response.Charset = "UTF-8";
curr.Response.AddHeader("content-length", theData.Length.ToString());
curr.Response.BinaryWrite(theData);
curr.Response.End();

答案 1 :(得分:0)

我也遇到了这个问题。我发现了关于"外观流的暗示" here

  
      
  1. PDF包含表单字段,交互式表单字典中的NeedAppearances条目设置为true。这意味着符合标准的PDF阅读器将生成PDF中表单字段所需的外观流,因此启用了“保存”按钮。如果NeedAppearances条目设置为false,则符合要求的PDF阅读器不应生成任何新的外观流。有关PDF文件中的外观流以及如何使用Debenu Quick PDF Library控制它们的更多信息。
  2.   

所以,我寻找"外观" websupergoo doc中的内容,并且能够设置一些表单属性并调用字段方法来摆脱"保存更改"信息。在上面的代码示例中,它看起来像这样:

编辑:在使用AddImageHtml创建PDF后通过快速且有用的WebSuperGoo支持来交换电子邮件,并通过设置表单NeedAppearances标志修复了WASN&#T; T,我添加了关于Catalog和Atom的行,用于删除在AddImageHtml期间设置的核心文档NeedAppearances标志。

public byte[] GeneratePDF(Employee employee, String TemplatePath)
{
    string[] FieldNames;
    Doc theDoc;
    MemoryStream MSgeneratedPDFFile = new MemoryStream();

    //Get the PDF Template and read all the form fields inside the template
    theDoc = new Doc();
    theDoc.Read(HttpContext.Current.Server.MapPath(TemplatePath));
    FieldNames = theDoc.Form.GetFieldNames();

    //Tell PDF viewer to not create its own appearances
    theDoc.Form.NeedAppearances = false;
    //Generate appearances when needed
    theDoc.Form.GenerateAppearances = true;

    //Navigate through each Form field and populate employee details 
    foreach (string FieldName in FieldNames)
    {
        Field theField = theDoc.Form[FieldName];
        switch (FieldName)
        {
            case "Your_First_Name":
                theField.Value = employee.FirstName;
                break;
            default:
                theField.Value = theField.Name;
                break;
        }

        //Update the appearance for the field
        theField.UpdateAppearance();

        //Remove Form Fields and replace them with text
        theField.Focus();
        theDoc.Color.String = "240 240 255";
        theDoc.FillRect();
        theDoc.Rect.Height = 12;
        theDoc.Color.String = "220 0 0";
        theDoc.AddText(theField.Value);
        theDoc.Delete(theField.ID);
    }

    Catalog cat = theDoc.ObjectSoup.Catalog;
    Atom.RemoveItem(cat.Resolve(Atom.GetItem(cat.Atom, "AcroForm")), "NeedAppearances");

    return theDoc.GetData();
}