【问题标题】:Can a PDF file's print dialog be opened with Javascript?可以使用 Javascript 打开 PDF 文件的打印对话框吗?
【发布时间】:2010-10-15 19:39:10
【问题描述】:

我知道如何在新窗口中打开网页并添加 javascript,以便弹出打印对话框。有没有办法对 PDF 文件做类似的事情?

【问题讨论】:

  • 没有必要为此使用javascript。改用命名操作,即使禁用了 javascript 也可以使用。
  • 我有 cors 问题,不能在其他选项卡上打印,或者弹出任何想法?

标签: javascript pdf printing


【解决方案1】:

是的,你可以...

PDF 支持 Javascript。在创建 PHP 生成的 PDF 时,我需要具有自动打印功能,并且我能够使用 FPDF 让它工作:

http://www.fpdf.org/en/script/script36.php

【讨论】:

  • 至少,只需将<script type="text/javascript">print();</script> 添加到您的PDF。 (我正在使用 dompdf)
  • 派对迟到了,但是如何使用 3rd 方库来实现呢?
【解决方案2】:

我通常使用iframe 做类似于How to Use JavaScript to Print a PDF (eHow.com) 给出的方法。

  1. 一个容纳打印触发器的函数...

    function printTrigger(elementId) {
        var getMyFrame = document.getElementById(elementId);
        getMyFrame.focus();
        getMyFrame.contentWindow.print();
    }
    
  2. 一个授予用户访问权限的按钮...

    abuttoninput 上的 onClick 或任何你想要的)

    <input type="button" value="Print" onclick="printTrigger('iFramePdf');" />
    
  3. 指向您的 PDF 的 iframe...

    <iframe id="iFramePdf" src="myPdfUrl.pdf" style="display:none;"></iframe>
    

Bonus Idea #1 - 创建 iframe 并将其添加到 printTrigger(); 内的页面中,以便在用户单击“打印”按钮之前不会加载 PDF,然后javascript可以攻击! iframe 并触发打印对话框。


Bonus Idea #2 - 如果您禁用“打印”按钮并在用户点击后给他们一点加载微调器或其他东西,那么他们就会知道某些东西正在进行中而不是点击它反复!

【讨论】:

  • 在 Google Chrome 中加载 PDF 时似乎没有定义 contentWindow
  • @jtietema 我相信,如果您将 PDF 作为整个且唯一的文档(即,不在 iframe 中)直接加载到浏览器中,那么 contentWindow 是未定义的。但只要您在 iframe 中加载 PDF 并且从与父 DOM 相同的域加载,那么这应该可以正常工作。
  • 这个答案不再适用于 Firefox(当前为 v25)stackoverflow.com/questions/15011799/… 查看错误报告:bugzilla.mozilla.org/show_bug.cgi?id=911444
  • 这给出了一个错误Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
【解决方案3】:

刚刚弄清楚如何在 PDF 本身中执行此操作 - 如果您有 acrobat pro,请转到您的页面选项卡,右键单击第一页的缩略图,然后单击页面属性。单击窗口顶部的操作选项卡,然后在选择触发器下选择打开页面。在选择操作下选择“运行 javascript”。然后在 javascript 窗口中输入:

this.print({bUI: false, bSilent: true, bShrinkToFit: true});

这将打印您的文档,而无需与您机器上的默认打印机对话。如果您想要打印对话框,只需将 bUI 更改为 true,将 bSilent 更改为 false,并且可以选择删除缩小以适应参数。

自动打印 PDF!

【讨论】:

  • 这对我有帮助,但应该注意的是,根据documentation,这也可以通过使用 printParams 对象来实现,这可能会派上用场,因为我在其他地方读到 print 方法忽略了所有其他如果传递了 printParams 参数(我需要它作为 NumCopies 参数)
  • 如果您使用 printParams 对象,Chrome PDF 插件不会显示打印对话框,但它会使用此答案中显示的 javascript。如果 Acrobat 正在执行 PDF 显示,则两者都可以。两者都不适用于 FireFox 20 和 21 的 PDFJS 显示代码。
  • 只是为了记录,因为它把我逼疯了;打印参数(bUI、bSilent、bShrinkToFit)记录在“使用 JavaScript 开发 Acrobat 应用程序”-“打印 PDF 文档”中:adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/…
【解决方案4】:

我使用 named action 而不是 javascript,因为 javascript 经常被禁用,如果不是,它会发出警告。

我的 Web 应用程序创建了一个 postscript 文件,然后使用 ghostscript 将其转换为 pdf。我希望它自动打印,因为用户已经在我的应用程序中单击了打印。通过上面@DSimon 中有关命名操作的信息,我研究了如何解决这个问题。这一切都归结为在 pdf 的正确位置插入字符串 /Type /Action /S /Named /N /Print

我正在考虑编写一个小实用程序,但它必须解析 pdf 以找到根节点,插入带有引用的 /OpenAction 带有操作的对象,并重新计算外部参照中的字节偏移量。

但后来我发现 pdfmark 是 postscript 的一个扩展,用于以 postscript 语法表达由 Adob​​e 蒸馏器或 ghostscript 转换为 pdf 的习语。

由于我已经在使用 ghostscript,我所要做的就是将以下内容附加到我的 postscript 文件的末尾:

%AUTOPRINT
[ /_objdef {PrintAction} /type /dict /OBJ pdfmark
[ {PrintAction} << /Type /Action /S /Named /N /Print >> /PUT pdfmark
[ {Catalog} << /OpenAction {PrintAction} >> /PUT pdfmark

ghostscript 将创建动作、链接它并计算外部参照偏移。 (在后记中% 是评论,PrintAction 是我的对象名称)

通过查看 PDF,我发现它创建了这个:

1 0 obj
<</Type /Catalog /Pages 3 0 R
/OpenAction  9 0 R
/Metadata 10 0 R
>>
endobj

9 0 obj
<</S/Named
/Type/Action
/N/Print>>endobj

1 0 是对象 1,修订版 0,9 0 是对象 9,修订版 0。在 pdf-trailer 中说对象 1 是根节点。如您所见,对象 1 有一个引用 /OpenAction 来运行对象 9 修订版 0。

使用 ghostscript,可以将 pdf 转换为 postscript (pdf2ps),附加上面的文本,然后使用 ps2pdf 将其转换回 pdf。应该注意的是,有关 pdf 的元信息在此转换中丢失了。我没有对此进行更多搜索。

【讨论】:

    【解决方案5】:

    嵌入代码示例:

    <object type="application/pdf" data="example.pdf" width="100%" height="100%" id="examplePDF" name="examplePDF"><param name='src' value='example.pdf'/></object>
    
    <script>
       examplePDF.printWithDialog();
    </script>
    

    可能不得不用 ids/names 胡闹。 使用 adobe 阅读器...

    【讨论】:

    • TypeError: 对象没有方法'printWithDialog'
    • 对于阅读本文的人:正确的函数名称是“Print()”,带有大写 P。在本例中,正确的调用是 examplePDF.Print()
    【解决方案6】:

    如果您知道 PDF 文件的结构(或者愿意花一点时间阅读规范),您可以这样做。

    在 Catalog 对象的 OpenAction 字段中使用命名操作“Print”; “打印”操作未记录在案,但 Acrobat Reader 和大多数其他主要读者都理解它。这种方法的一个很好的好处是您不会收到任何 JavaScript 警告。详情见这里:http://www.gnostice.com/nl_article.asp?id=157

    为了让它更加闪亮,我添加了第二个动作,URI,引导读者返回发起请求的页面。然后我使用它的 Next 字段将此 Action 附加到第一个 Named 操作。将内容配置设置为“内联”,这样当用户点击打印链接时:

    1. 它会在同一选项卡中打开 Adob​​e Reader 并加载文件
    2. 立即显示打印对话框
    3. “打印”对话框一关闭(无论是点击“确定”还是“取消”),浏览器选项卡都会返回网页

    仅使用文件和 IO 模块,我就能在 Ruby 中轻松完成所有这些更改;我打开了使用外部工具生成的 PDF,将外部参照跟随到现有目录部分,然后在 PDF 上附加了一个新部分,其中包含更新的目录对象,其中包含我的特殊 OpenAction 行以及新的操作对象。

    由于 PDF 的增量修订功能,您无需对现有数据进行任何更改,只需在末尾附加一个附加部分即可。

    【讨论】:

    • 感谢您的帖子,这使我走向了正确的方向。效果很好!
    【解决方案7】:

    为什么不使用“操作”菜单选项来设置它?

    执行以下操作:如果您有 Acrobat Pro,请转到您的页面选项卡,右键单击第一页的缩略图,然后单击页面属性。单击窗口顶部的操作选项卡,然后在选择触发器下选择打开页面。在选择操作下选择'执行菜单项'。单击“添加”按钮,然后选择“文件 > 打印”,然后选择“确定”。再次单击“确定”并保存 PDF。

    【讨论】:

      【解决方案8】:

      如果您使用 Ruby on Rails 的 prawn gem 来生成 PDF,则可以使用以下附加 gem 来激活打印对话框:

      prawn-print

      【讨论】:

        【解决方案9】:

        另一种解决方案:

        <input type="button" value="Print" onclick="document.getElementById('PDFtoPrint').focus(); document.getElementById('PDFtoPrint').contentWindow.print();">
        

        【讨论】:

          【解决方案10】:

          如果您在网页中嵌入 pdf 并引用对象 id,您应该可以做到。

          例如。 在您的 HTML 中:

          <object ID="examplePDF" type="application/pdf" data="example.pdf" width="500" height="500">
          

          在你的 javascript 中:

          <script>
          
          var pdf = document.getElementById("examplePDF");
          
          pdf.print();
          
          </script>
          

          希望对你有帮助。

          【讨论】:

          • 你测试过这段代码吗?我收到一条错误消息,提示“对象不支持方法的此属性”。
          猜你喜欢
          • 1970-01-01
          • 2012-11-24
          • 2015-05-17
          • 2012-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-14
          相关资源
          最近更新 更多