推荐的将PDF嵌入HTML的方式是什么?

1370

如何在HTML中嵌入PDF文件?

  • 使用iFrame标签?
  • 使用Object标签?
  • 使用Embed标签?

Adobe官方对此有何建议?

在我的情况下,PDF文件是实时生成的,因此在刷新之前无法将其上传到第三方解决方案。


9
尝试使用pdf2htmlEX:https://github.com/coolwanglu/pdf2htmlEX/ - Lu Wang
1
在pdf2htmlEX存储库的wiki上,不仅有特定解决方案的比较,还有一般策略的很好的比较。此外,虽然我没有尝试过,但是这个似乎是一个维护的分支。 - ShreevatsaR
请尝试按照https://www.sitelint.com/blog/how-to-embed-a-pdf-in-html-without-downloading-it/中描述的方法进行操作。 - undefined
30个回答

669

这是快速、简单、直接且不需要任何第三方脚本的方法:

<embed src="http://example.com/the.pdf" width="500" height="375" 
 type="application/pdf">

更新(2021年2月3日)

Adobe现在提供了自己的PDF嵌入API。
(这需要在Adobe注册并获取clientID以在js中使用)

https://www.adobe.io/apis/documentcloud/dcsdk/pdf-embed.html

更新(1/2018):

Android 上的 Chrome 浏览器不再支持 PDF 嵌入。您可以通过使用 Google Drive PDF 查看器来解决此问题。

<embed src="https://drive.google.com/viewerng/
viewer?embedded=true&url=http://example.com/the.pdf" width="500" height="375">

37
最好使用<object>标签,这样您就可以包含备用内容。 - Jonathon Hill
72
如果您想确保它被显示而不是自动下载PDF(就像我遇到的那样),请在嵌入标签中添加“type ='application / pdf'”。 - Hassek
36
最好使用<object>标签,因为它可以在不能显示PDF的浏览器中显示备用内容。如果需要,甚至可以在<object>标签中放置一个<embed>标签。参考:https://dev59.com/p3M_5IYBdhLWcg3wvV9w - Raphael
@batfan,如果我认为这里提供的几乎所有解决方案都是针对在移动设备屏幕上完美显示PDF文档的挑战,那么这是否正确?我有一个网页,在计算机屏幕上嵌入了PDF,这在计算机屏幕上运行良好,但在使用Chrome的Android手机上却无法正常工作。请给出一些解决此问题的建议/解决方案。 - CodeForGood
2
@PKTG 我刚刚测试了一下,对我来说是可以工作的。请参见以下链接:https://jsfiddle.net/196fv04s/ - Batfan
显示剩余2条评论

604

16
如另一个回答所提到的,scribd实际上使用pdf2swf来转换pdf文件。 - Peter Craig
11
我强烈不建议使用Scribd - 我刚刚对一份特定的文档进行了实验,在Firefox 4中只显示了前3页,而在IE9中它渲染了错误的文字 - 它偏移了页面的某些部分。因此从技术上讲,它是有缺陷的。此外,他们希望你订阅才能打印或下载文档!实质上,他们正在围绕以前免费的文件设置付费墙。 - frankster
12
PDF.js 库实际上看起来是一个非常好的解决方案,尽管链接的演示没有将其嵌入页面中(它占据了整个页面)。但它使用了 HMTL5 画布,所以应该很容易嵌入,并且速度很快。不过缺点是需要一些 JS 来使用,不像 <object>。https://github.com/mozilla/pdf.js/blob/master/examples/helloworld/hello.js - LarsH
45
PDF.js在平板浏览器(如Chrome)上效果不佳。我也发现它在处理大型PDF文档时非常缓慢。 - Rocco The Taco
2
@RoccoTheTaco 有没有高性能的替代方案? - Kiquenet
值得一提的是,许多浏览器内置的PDF阅读器无法与主机系统的辅助功能API进行通信。但是pdf.js生成了一个语义化的DOM树,可以使文档对屏幕阅读器和其他辅助技术可访问。我认为Chromium浏览器中的默认PDF阅读器也会做类似的事情,但存在各种不完美之处。这对于公共部门的内容来说是一个重要的考虑因素。 - brennanyoung

381

您也可以使用Google PDF查看器来实现此目的。据我所知,这不是Google的官方功能(如果我错了请指正),但是它对我来说非常好用和流畅。您需要先将PDF上传到某个地方,然后只需使用其URL即可:

<iframe src="https://docs.google.com/gview?url=http://example.com/mypdf.pdf&embedded=true" style="width:718px; height:700px;" frameborder="0"></iframe>
重要的是它不需要Flash播放器,而是使用JavaScript。

35
需要提到的一件事是,PDF 文件的大小有一个上限,不能超过10MB/100页。顺便说一句,我认为这个浏览器并不是“非官方”的,他们甚至有一个如何页面来构建嵌入式URL:https://docs.google.com/viewer - SuperElectric
33
这个选项非常好用,但你必须使你的PDF公开可访问,而这对我来说并不总是可选的。 - KoviNET
5
@riot_starter,这个解决方案已经不再适用。如果你完全退出 Google 登录,它会正常加载;如果你完全登录,则也能正常加载;然而,如果你处于中间状态(具体是指什么不清楚),它会要求输入密码。对于 iframe,则根本无法加载。 - dwenaus
5
您可以将任何Google Docs的隐私设置为“公开”,“需要登录”和“私人”。鉴于在Google Docs上的任何文档都有“嵌入”选项,因此这绝对是一项官方功能。 - arkon
7
还有一件需要提到的事情是“您最近发送过多请求”的警告,这是一种限制。 - kommradHomer

140

通过在查询字符串中传递一些选项,您可以在浏览器中控制PDF的显示方式。我很高兴看到它能够工作,但是我发现它在IE8中无法正常使用 :(

它可以在Chrome 9和Firefox 3.6中运行,但在IE8中会显示消息“如果无法显示PDF,请插入您的错误消息。”

我尚未测试过上述任何浏览器的早期版本。但这是我的代码,以防对任何人有帮助。它将缩放设置为85%,删除滚动条、工具栏和导航窗格。如果我找到在IE中也有效的解决方法,我会更新我的帖子。

<object width="400" height="500" type="application/pdf" data="/my_pdf.pdf?#zoom=85&scrollbar=0&toolbar=0&navpanes=0">
    <p>Insert your error message here, if the PDF cannot be displayed.</p>
</object>

12
这是最佳的解决方案,因为它利用了浏览器的功能而不是复杂的第三方解决方案。在所有现代浏览器(IE9、FF或Chrome)中,PDF文件应该可以很好地嵌入。对于使用IE 6/7的用户我们很抱歉,他们需要升级浏览器。我们很久以前就停止支持这些浏览器了。 :( - Adrian P.
这个解决方案最好。我尝试了stackoverflow上的其他解决方案,但无法显示pdf。这是最好的解决方案。 - gojiraki
我正在尝试通过S3预签名URL显示PDF文件表单。我的文件类型在S3中设置为PDF。不幸的是,嵌入、对象和iframe都会触发下载而不显示PDF文件。 - avijit
我正在尝试使用S3预签名URL显示PDF文件表单。我的文件类型在S3中设置为PDF。不幸的是,嵌入、对象和iframe都会触发下载而不显示PDF文件。 - undefined

74

同时使用<object><embed>将使您在浏览器兼容性方面拥有更广泛的覆盖。

<object data="http://yoursite.com/the.pdf" type="application/pdf" width="750px" height="750px">
    <embed src="http://yoursite.com/the.pdf" type="application/pdf">
        <p>This browser does not support PDFs. Please download the PDF to view it: <a href="http://yoursite.com/the.pdf">Download PDF</a>.</p>
    </embed>
</object>

6
如果浏览器没有安装或者插件过期了,这将无法在浏览器中工作。 - Umair Hamid
1
此外,这不会为那些关心代码验证的人进行验证。 - NotJay
1
这对我非常有效,而仅使用“embed”标签被Chrome和Firefox视为“不安全”。 - Richie Thomas
3
在 Android(Chrome)上出现问题,无法嵌入 PDF 文件,仅提供下载选项。在 iPhone(Safari)上,仅显示 PDF 文件的第一页。 - Ivan Rubinson
@IvanRubinson 安卓手机和部分平板电脑无法显示嵌入式PDF文件。对于某些iOS移动设备(iPhone、iPad),也存在同样的问题。而其他iOS设备(iPad Pro等)只能显示PDF的第一页。这是iOS上已知的长期存在的问题。 - Prabhu Thomas

26

看看这段代码- 将PDF嵌入HTML

<!-- Embed PDF File -->
<object src="YourFile.pdf" type="application/pdf" title="SamplePdf" width="500" height="720">
    <a href="YourFile.pdf">shree</a> 
</object>

8
这似乎不起作用,我总是得到一个空灰色屏幕而不是PDF文件。但是像@Gayle的答案一样使用data替换src确实有效。 - Mottie
1
我正在使用Chrome 44,但它无法工作。我还尝试将数据切换到src。 - NotJay
2
type="application/pdf" 可以解决这个问题。在 Chrome 中运行良好。 - Gavin Simpson
2
包括 type="application/x-pdf" 将会阻止 Chrome 和 FireFox 渲染 PDF 文件。应该将其移除。 - Jared Wilber

22

通过ImageMagick将其转换为PNG格式,然后显示PNG文件(简单粗暴)。

<?php
  $dir = '/absolute/path/to/my/directory/';
  $name = 'myPDF.pdf';
  exec("/bin/convert $dir$name $dir$name.png");
  print '<img src="$dir$name.png" />';
?>

如果您需要快速解决方案,想要避免跨浏览器的PDF查看问题,并且PDF只有一页或两页,则这是一个不错的选择。当然,您需要在Web服务器上安装ImageMagick(它又需要Ghostscript),这可能在共享托管环境中不可用。还有一个PHP插件(称为Imagick),可以像这样使用,但需要满足其特定要求。


或者使用应用程序(例如Mac上的预览)将图像转换为PNG格式。 - Garrett
2
但是你能通过编程实现吗? - Dan Mantyla
如果文档有多页呢?我猜你只会显示第一页。 - seb
@seb 好久不见了,但我能够在两到三页长的PDF上使用它。我认为最好不要使用比这更大的文件,因为移动浏览器很难显示这样的图片。这就是为什么我称之为“快速而简单”的方法,但我认为只要PDF不超过几页,这是一个好方法。 - Dan Mantyla
2
如果您使用Zend库打开PDF,则可以使用foreach($pdf->pages as $page)循环遍历每个页面并为每个页面创建一个图像。 - 99 Problems - Syntax ain't one
显示剩余4条评论

15
您可以像这样使用保存的PDF文件的相对位置:
示例1
<embed src="example.pdf" width="1000" height="800" frameborder="0" allowfullscreen>

例子2

<iframe src="example.pdf" style="width:1000px; height:800px;" frameborder="0" allowfullscreen></iframe>

1
Chrome 理解 embed 就像 Flash 一样,会自动阻止它。使用带有 Bootstrap 的 iFrame 是一个不错的选择。 - Mehmet Taha Meral

13
  1. 创建一个容器来存放你的PDF

<div id="example1"></div>
告诉PDFObject要嵌入哪个PDF文件,以及在哪里嵌入它。
<script src="/js/pdfobject.js"></script>
<script>PDFObject.embed("/pdf/sample-3pp.pdf", "#example1");</script>
  • 您可以选择使用 CSS 来指定视觉样式,包括尺寸、边框、边距等。

  • <style>
    .pdfobject-container { height: 500px;}
    .pdfobject { border: 1px solid #666; }
    </style>
    

    来源: https://pdfobject.com/


    这是一个非常好的解决方案,并且与Bootstrap样式很好地配合使用。它可以放置在其他Bootstrap元素之上。 - netfed
    你试过使用blob文件吗?我在jspdf库中使用了pdf.output('bloburl'),但在IE11上似乎无法正常工作。 - Tran Son Hoang
    这是一个不错的解决方案,但它甚至在最新的iPhone Safari浏览器上也无法工作 :( - Mehmet Taha Meral

    13

    我们的问题是出于法律原因,我们不允许将PDF临时存储在硬盘上。此外,在浏览器中显示预览时,不应重新加载整个页面来显示PDF。

    首先,我们尝试了PDF.js。它在Firefox和Chrome的查看器中使用Base64可以正常工作。然而,对于我们的PDF来说,速度太慢了。IE/Edge根本无法工作。

    因此,我们尝试在HTML对象标记中使用Base64字符串。这在IE / Edge上仍然无法工作(可能与PDF.js相同的问题)。但在Chrome / Firefox / Safari上没有问题,所以我们选择了一种混合解决方案。Edge使用IFrame,对于所有其他浏览器使用对象标记。

    当然,IFrame解决方案也适用于Chrome等浏览器。之所以我们没有在Chrome中使用此解决方案,是因为虽然PDF正确显示了,但是一旦您在预览中单击“下载”,Chrome就会向服务器发出新请求。所需的隐藏字段pdfHelperTransferData(用于发送PDF生成所需的表单数据)不再设置,因为PDF显示在IFrame中。关于此功能/错误,请参见Chrome发送两个请求以下载PDF(并取消其中一个)

    现在问题儿童IE9和IE10仍然存在。对于这些,我们放弃了预览解决方案,而是通过单击预览按钮将文档作为下载发送给用户(而不是预览)。我们已经尝试了很多,但即使我们找到了解决方案,为此微小的用户部分付出额外的努力也不值得。您可以在此处找到我们的下载解决方案:使用IFrame无需刷新下载PDF

    我们的Javascript:

    var transferData = getFormAsJson()
    if (isMicrosoftBrowser()) {
            // Case IE / Edge (because doesn't recoginzie Pdf-Base64 use Iframe)
            var form = document.getElementById('pdf-helper-form');
            $("#pdfHelperTransferData").val(transferData);
            form.target = "iframe-pdf-shower";
            form.action = "serverSideFunctonWhichWritesPdfinResponse";
            form.submit();
     } else {
            // Case non IE use Object tag instead of iframe
            $.ajax({
                url: "serverSideFunctonWhichRetrivesPdfAsBase64",
                type: "post",
                data: { downloadHelperTransferData: transferData },
                success: function (result) {
                    $("#object-pdf-shower").attr("data", result);
                }
            })
     }
    
    

    我们的HTML:

    <div id="pdf-helper-hidden-container" style="display:none">
       <form id="pdf-helper-form" method="post">
            <input type="hidden" name="pdfHelperTransferData" id="pdfHelperTransferData" />
       </form>
    </div>
    
    <div id="pdf-wrapper" class="modal-content">
        <iframe id="iframe-pdf-shower" name="iframe-pdf-shower"></iframe>
        <object id="object-pdf-shower" type="application/pdf"></object>
    </div>
    

    如果想检查 IE/Edge 浏览器的类型,请参见此处:如何使用 JavaScript 检测 Internet Explorer (IE) 和 Microsoft Edge? 希望这些发现可以为其他人节省时间。


    对不起,我不明白变量“transferData”有什么值。 - Kate
    1
    嗨@Kate,我们的情况是基于用户在我们的Web表单中输入生成PDF。 "transferData"包含作为JSON发送到Web API中的PDF生成函数的数据。我添加了一行更多的代码以进行澄清。 - Astrophage

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