可以使用 Javascript 打开 PDF 文件的打印对话框吗?
Posted
技术标签:
【中文标题】可以使用 Javascript 打开 PDF 文件的打印对话框吗?【英文标题】:Can a PDF file's print dialog be opened with Javascript? 【发布时间】:2010-10-15 19:39:10 【问题描述】:我知道如何在新窗口中打开网页并添加 javascript,以便弹出打印对话框。有没有办法对 PDF 文件做类似的事情?
【问题讨论】:
没有必要为此使用javascript。改用命名操作,即使禁用了 javascript 也可以使用。 我有 cors 问题,不能在其他选项卡上打印,或者弹出任何想法? 【参考方案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) 给出的方法。
一个容纳打印触发器的函数...
function printTrigger(elementId)
var getMyFrame = document.getElementById(elementId);
getMyFrame.focus();
getMyFrame.contentWindow.print();
一个授予用户访问权限的按钮...
(a
或 button
或 input
上的 onClick
或任何你想要的)
<input type="button" value="Print" onclick="printTrigger('iFramePdf');" />
指向您的 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)***.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 语法表达由 Adobe 蒸馏器或 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" 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 操作。将内容配置设置为“内联”,这样当用户点击打印链接时:
-
它会在同一选项卡中打开 Adobe Reader 并加载文件
立即显示打印对话框
“打印”对话框一关闭(无论是点击“确定”还是“取消”),浏览器选项卡都会返回网页
仅使用文件和 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" >
在你的 javascript 中:
<script>
var pdf = document.getElementById("examplePDF");
pdf.print();
</script>
希望对你有帮助。
【讨论】:
你测试过这段代码吗?我收到一条错误消息,提示“对象不支持方法的此属性”。以上是关于可以使用 Javascript 打开 PDF 文件的打印对话框吗?的主要内容,如果未能解决你的问题,请参考以下文章