PDF主机容器回调

10
根据这个SO解决方案(在此处来通知客户单击PDF文档中的事件,当客户使用this.myPDF.submitForm("localhost/Handler.ashx?r=2)函数提交PDF时,如何通知客户端呢?
PDF文件是在用户控件内创建,然后呈现为HTML对象:
string container = ("<object data='/myfile.pdf' type='application/pdf'></object>");

所附的PDF文件中的JS文件是这样处理的:

 var webClient = new WebClient();
 string htmlContent = webClient.DownloadString(fileurl + "pdf_script.js");
 PdfAction action = PdfAction.JavaScript(htmlContnent, pdfstamper.Writer);
 pdfstamper.Writer.SetOpenAction(action);

而且 js 文件的内容:

this.disclosed = true;
if (this.external && this.hostContainer) {

function onMessageFunc(stringArray) {
     try {
          this.myPDF.submitForm("http://localhost/Handler.ashx?EmpNo=12345" + "#FDF", false);

        }
        catch (e) {

        }
    }
    function onErrorFunc(e) {
        console.show();
        console.println(e.toString());
    }
    try {
        if (!this.hostContainer.messageHandler);
        this.hostContainer.messageHandler = new Object();
        this.hostContainer.messageHandler.myPDF = this;
        this.hostContainer.messageHandler.onMessage = onMessageFunc;
        this.hostContainer.messageHandler.onError = onErrorFunc;
        this.hostContainer.messageHandler.onDisclose = function () { return true; };
    }
    catch (e) {
        onErrorFunc(e);
    }
}

当调用submitForm时,PDF内容(表单字段)会成功保存,并通过以下方式在PDF中显示警报:

message = "%FDF-1.2
                   1 0 obj
                   <<
                   /FDF
                   <<
                      /Status("Success!")
                   >>
                   >>
                   endobj
                   trailer
                   <</Root 1 0 R>>
           %%EOF");
return message;
我试图做的是让PDF在客户端提交表单后回调客户端,以一种触发主机中函数的方式来告知客户端表单已经提交,而非弹出警报框的形式。主机可以是容器、iframe、object等。

1
我缺少关于这一步骤的一些信息:“当submitForm调用成功创建PDF并通过执行以下操作在PDF中显示警报时:”。我假设服务器上创建了一个PDF并在客户端上显示,但也许我是错的。也许服务器正在返回FDF文件。你能澄清一下吗? - Bruno Lowagie
1
哎呀,我的错误,submitForm调用是用来保存PDF内容而不是创建它,它已经在用户控件中呈现并嵌入到<object>中了。抱歉,我已经更正了问题,并添加了有关如何呈现PDF的更多细节。 - Maya
我不理解上面的代码中为什么会有 "if (!this.hostContainer.messageHandler);" 这一行,为什么这一行末尾有一个分号?这是一个错误吗?如果不是,那么这一行的目的是什么?非常感谢! - John Henckel
1个回答

5
你用的FDF响应我不熟悉,所以从你的问题中学到了新知识。我已经研究了AcroJS参考和PDF参考中的FDF规范,现在对你的代码有了更好的理解。谢谢你。
我假设你已经知道如何通过从PDF调用JavaScript来触发HTML文件中的JavaScript消息。请参考HTML和PDF之间的JavaScript通信文章中的createMessageHandler()
我理解你的问题是:“如何在成功提交数据后调用此方法?”
如果有一个解决方案,它将涉及JavaScript。我看到可以在FDF文件中添加JavaScript,但我不确定该JavaScript是否可以“与”HTML交互。我不确定是否可以从FDF响应中调用初始PDF中的JavaScript函数。如果可能,您应该像/Status条目一样向您的PDF中添加JavaScript条目。
该条目的值是一个字典,类似于:
<<
/Before (app.alert\("before!"\))
/After (app.alert\("after"\))
/Doc [/MyDocScript1, (myFunc1\(\)),
      /MyDocScript2, (myFunc2\(\))
>>

在您的情况下,我会移除/Before和/Doc键。我认为您不需要它们,我会将字典缩小为:
<<
/After (talkToHtml\(\))
>>

talkToHtml() 是PDF中已经存在的一个方法:

function talkToHtml() {
    var names = new Array();
    names[0] = "Success!";
    try{
        this.hostContainer.postMessage(names);
    }
    catch(e){
        app.alert(e.message);
    }
}

我不知道这是否有效。我自己从未尝试过。我的答案是基于规格的。

我不确定您是否真的需要使用FDF。您是否尝试将JavaScript添加到submitForm()方法中?类似于:

this.myPDF.submitForm({
    cURL: "http://localhost/Handler.ashx?EmpNo=12345",
    cSubmitAs: "FDF",
    oJavaScript: {
        Before: 'app.alert("before!")',
        After: 'app.alert("after")',
        Doc: ["MyDocScript1", "myFunc1()",
              "MyDocScript2", "myFunc2()" ]
    }
});

如果您提交为FDF,则此方法才有效。如果您提交HTML查询字符串,则我认为没有解决方案。

如果您想知道什么是MyDocScript1MyDocScript2

文档定义了一个数组,用于定义要添加到文档名称字典中JavaScript条目中定义的其他JavaScript脚本。该数组包含一些成对排列的元素,每个成对的第一个元素是名称,第二个元素是一个文本字符串或文本流,用于定义与该名称对应的脚本。所有定义的脚本都将被添加到名称字典中已经定义的脚本之后执行,并在执行Before条目中定义的脚本之前执行。(ISO-32000-1 表格245)

我不确定所有这些内容是否在实践中都能正常工作。请告诉我结果。


最后,现在实际上这个已经可以工作了,客户端和PDF可以双向通信,如果您想要更新答案,我必须修改/After行为:/JavaScript << /After (saveComplete()) >>。谢谢,你得到了赏金! - Maya
@Maya:我想达到相同的效果,但在深入了解答案和文档之前,我想问一下这个解决方案在现代浏览器上是否仍然有效。感谢任何意见! - Photon
@Photon 这在 Edge 和工作场所两个月前的 Chrome 上仍然有效。 - Maya
1
@Maya:感谢您的回复!是否正在使用Adobe Reader浏览器插件?我想使用一个开放式阅读器,因此尝试在pdf.js中使事情正常工作,但是来自pdf.js开发团队的人告诉我那里不支持JS并且不会支持(由于某些ISO标准禁止在PDF中使用JS:https://en.wikipedia.org/wiki/PDF/A#Description)。 - Photon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接