【问题标题】:Recommended way to embed PDF in HTML?将 PDF 嵌入 HTML 的推荐方法?
【发布时间】:2010-09-22 10:50:54
【问题描述】:

在 HTML 中嵌入 PDF 的推荐方法是什么?

  • iFrame?
  • 对象?
  • 嵌入?

Adobe 是怎么说的?

就我而言,PDF 是动态生成的,因此在刷新之前无法将其上传到第三方解决方案。

【问题讨论】:

标签: html pdf


【解决方案1】:

更新 - Adob​​e PDF Embed API

Adobe 发布了完全免费的Adobe PDF Embed API。因为他们自己创建了 PDF 格式,所以他们的 API 可能是最适合这个的。

  • 它提供了最高质量的 PDF 渲染。
  • 您可以完全自定义用户体验并选择如何显示 PDF。
  • 您还将获得有关 PDF 使用情况的分析,以便了解用户如何与 PDF 交互,包括在页面上花费的时间和搜索时间。

您所要做的就是创建一个api_key 并在代码 sn-p 中使用它。

通过file_url显示PDF

这里是代码 sn-p 的示例,您可以将其添加到 HTML 并利用 file_url 的 API 显示 PDF。您必须添加 { location: { url: "url_of_the_pdf" } } 配置。

<div id="adobe-dc-view"></div>

<script src="https://documentcloud.adobe.com/view-sdk/main.js"></script>

<script type="text/javascript">
  document.addEventListener("adobe_dc_view_sdk.ready", function(){
    var adobeDCView = new AdobeDC.View({clientId: "api_key", divId: "adobe-dc-view"});
    adobeDCView.previewFile({
      content: { location: { url: "url_of_the_pdf" } },
      metaData: { fileName: "file_name_to_display" }
    }, {});
  });
</script>

将 PDF 显示为缓冲区

这是代码 sn-p 的示例,您可以将其添加到 HTML 中,如果您有缓冲区(例如本地文件),则可以利用它们的 API 来显示 PDF。您必须添加 { promise: &lt;FILE_PROMISE&gt; } 配置。

<div id="adobe-dc-view"></div>

<script src="https://documentcloud.adobe.com/view-sdk/main.js"></script>

<script type="text/javascript">
  document.addEventListener("adobe_dc_view_sdk.ready", function(){
    var adobeDCView = new AdobeDC.View({clientId: "api_key", divId: "adobe-dc-view"});
    adobeDCView.previewFile({
      content: { promise: <FILE_PROMISE> }
      metaData: { fileName: "file_name_to_display" }
    }, {});
  });
</script>

【讨论】:

    【解决方案2】:

    查看此代码 - 将 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>
    

    【讨论】:

    • 这似乎不起作用。我总是以空白的灰色屏幕而不是pdf结束。但是将src 切换为data,就像@Gayle 的回答一样,确实有效。
    • 我使用的是 Chrome 44,但它不起作用。我也尝试将数据切换到 src。
    • type="application/pdf" 解决了这个问题。在 chrome 中运行良好。
    • 包含 type="application/x-pdf" 现在实际上会阻止在 Chrome 和 FireFox 上呈现。它应该被删除。
    【解决方案3】:

    可能最好的方法是使用PDF.JS 库。这是一个纯粹的HTML5/JavaScript 渲染器,用于 PDF 文档,没有任何第三方插件。

    在线演示: https://mozilla.github.io/pdf.js/web/viewer.html

    GitHub: https://github.com/mozilla/pdf.js

    【讨论】:

    • 在另一个答案中提到,scribd 实际上使用 pdf2swf 来转换 pdf 文件
    • 我强烈建议不要使用 scribd - 我刚刚对特定文档进行了实验,在 Firefox 4 中它只显示前 3 页,而在 IE9 中它的呈现文本错误 - 它偏移了这页纸。所以从技术上讲,它是错误的。此外,他们希望您订阅打印或下载文档!从本质上讲,他们正在获取以前免费的文件并在它们周围建立付费墙。
    • PDF.js 库实际上看起来是一个非常好的解决方案,尽管链接的演示没有显示它嵌入到页面中(它占据了整个页面)。但是它使用 HMTL5 画布,所以应该很容易嵌入,而且它。不利的一面是,它需要一些js才能使用,不像&lt;object&gt;github.com/mozilla/pdf.js/blob/master/examples/helloworld/…
    • pdf.js 在 Chrome 等平板电脑浏览器上效果不佳。我还发现它对于较大的 pdf 文档非常非常慢。
    • @RoccoTheTaco 有没有高性能的替代品?
    【解决方案4】:

    如果您不想自己托管 PDF,或者不想使用其他安全功能(例如阻止用户下载 PDF 文件)自定义 PDF 查看器。我推荐使用 CloudPDF。 https://cloudpdf.io

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>CloudPDF Viewer</title>
      <style>
        body, html {
          height: 100%;
          margin: 0px;
        }
      </style>
    </head>
    <body style="height: 100%">
      <div id="viewer" style="width: 800px; height: 500px; margin: 80px auto;"></div>
      <script type="text/javascript" src="https://cloudpdf.io/viewer.min.js?version=0.1.0-beta.11"></script>
      <script>
        document.addEventListener('DOMContentLoaded', function(){
          const config = { 
            documentId: 'eee2079d-b0b6-4267-9812-b6b9eadb9c60',
            darkMode: true,
          };
          CloudPDF(config, document.getElementById('viewer')).then((instance) => {
    
          });
        });
      </script>
     </body>
    </html>
    

    【讨论】:

      【解决方案5】:
      <embed src="data:application/pdf;base64,..."/>
      

      【讨论】:

      • 这不是链接
      【解决方案6】:

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

      首先我们尝试了 PDF.jS。它在 Firefox 和 Chrome 的查看器中与 Base64 配合使用。但是,对于我们的 PDF,它的速度慢得令人无法接受。 IE/Edge 根本不工作。

      因此,我们尝试在 HTML 对象标签中使用 Base64 字符串。这同样不适用于 IE/Edge(可能与 PDF.js 的问题相同)。在 Chrome/Firefox/Safari 中再次没有问题。 这就是我们选择混合解决方案的原因。 IE/Edge 我们使用 IFrame,而对于所有其他浏览器,我们使用 object-tag。

      IFrame 解决方案当然也适用于 Chrome 和 co。我们没有为 Chrome 使用此解决方案的原因是,虽然 PDF 显示正确,但 Chrome 会在您单击预览中的“下载”时立即向服务器发出新请求。不再设置所需的隐藏字段 pdfHelperTransferData(用于发送生成 PDF 所需的表单数据),因为 PDF 显示在 IFrame 中。有关此功能/错误,请参阅 Chrome sends two requests when downloading a PDF (and cancels one of them)

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

      我们的 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 的浏览器类型,请参见此处:How can I detect Internet Explorer (IE) and Microsoft Edge using JavaScript? 我希望这些发现可以节省其他人的时间。

      【讨论】:

      • 对不起,我不明白,变量“transferData”有什么值?
      • 嗨@Kate,在我们的例子中,我们根据用户在Web 表单中的输入生成PDF。 “transferData”包含以 JSON 格式发送到 Web API 中的 PDF 生成函数的数据。我添加了一行更多代码以进行澄清。
      【解决方案7】:

      这既快速又简单,并且不需要任何第三方脚本:

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

      更新(2021 年 2 月 3 日)

      Adobe 现在提供自己的 PDF 嵌入 API。

      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">
      

      【讨论】:

      • 最好使用 标签,这样您就可以包含一个后备。
      • 如果你想确保它会被显示而不是自动下载 pdf(因为它发生在我身上)添加 type='application/pdf' 到嵌入标签
      • 最好使用&lt;object&gt; 标签,因为它可以在无法显示 pdf 的浏览器中显示替代内容。如果需要,甚至可以将 &lt;embed&gt; 标签放入 &lt;object&gt; 标签中。参考:stackoverflow.com/questions/1244788/embed-vs-object
      • @PKTG 我刚刚测试了这个,它对我有用。见下文jsfiddle.net/196fv04s
      • 是的。问题实际上是 src 在我的代码中格式错误。谢谢你的时间。
      【解决方案8】:

      您可以像这样使用保存的 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>
      

      【讨论】:

      • Chrome 理解嵌入就像 Flash,它会自动阻止它。带引导程序的 iFrame 是一个不错的选择。
      【解决方案9】:

      在我遇到嵌入用 PDF 编码的 base64 的问题之前,因为 URI 限制,所以任何超过 2MB 的文件都无法在 Chrome 上正确呈现。

      我的解决办法是:

      1. Convert uri encoded to Blob:

      2. 基于 Blob 生成临时 DOM 字符串。

        const blob = dataURItoBlob(this.dataUrl);

        var temp_url = window.URL.createObjectURL(blob);

      3. 确定要将 iframe 附加到 DOM 的位置:

        const target = document.querySelector(targetID);

        target.innerHTML = `&lt;iframe src='${temp_url}' type="application/pdf"&gt;&lt;/iframe&gt;

      【讨论】:

        【解决方案10】:

        我发现为我的案例嵌入 pdf 的最佳方法是使用 bootstrap,因为它不仅显示 pdf,而且还填充可用空间,您可以根据需要指定比率。这是我用它制作的一个例子:

        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
        
        <div class="embed-responsive embed-responsive-1by1">
          <iframe class="embed-responsive-item" src="http://example.com/the.pdf" type="application/pdf" allowfullscreen></iframe>
        </div>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

        【讨论】:

          【解决方案11】:

          只需将 iFrame 用于 PDF。

          我的 React.js 应用程序有特定需求,尝试了数百万种解决方案,但最终得到了一个 iFrame :) 祝你好运!

          【讨论】:

            【解决方案12】:

            我必须使用 React 预览 PDF,所以在尝试了几个库之后,我的最佳解决方案是获取数据并 ebmed。

            const pdfBase64 = //fetched from url or generated with jspdf or other library
            
              <embed
                src={pdfBase64}
                width="500"
                height="375"
                type="application/pdf"
              ></embed>
            

            【讨论】:

              【解决方案13】:
              1. 创建一个容器来保存您的 PDF

                <div id="example1"></div>
                
              2. 告诉PDFObject要嵌入哪个PDF,以及在哪里嵌入

                <script src="/js/pdfobject.js"></script>
                <script>PDFObject.embed("/pdf/sample-3pp.pdf", "#example1");</script>
                
              3. 您可以选择使用 CSS 来指定视觉样式,包括尺寸、边框、边距等。

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

              来源:https://pdfobject.com/

              【讨论】:

              • 这是一个非常好的解决方案,并且与引导程序样式结合使用效果很好。这一切都建立在其他引导元素之上。
              • 您是否尝试过使用 blob 文件?我将它与来自 lib jspdf 的 pdf.output('bloburl') 一起使用,但它似乎不适用于 IE11。
              • 这是一个很好的解决方案,但即使是最新的 iPhone safari 浏览器也无法使用 :(
              【解决方案14】:

              您可以通过在查询字符串中传递一些选项来控制 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>
              

              【讨论】:

              • 这是最好的解决方案,因为它使用的是浏览器功能,而不是复杂的第三方解决方案。在所有现代浏览器(IE9、FF 或 Chrome)中,PDF 都应该很好地嵌入。对不起 IE 6/7 用户。他们必须升级。我们很久以前就停止支持这些浏览器了。 :(
              【解决方案15】:
              1. 构造一个输入 PDF 字节的 blob
              2. 使用 iframePDF.js 修补了this cross browser workaround

              iframe 的 URI 应如下所示:

              /viewer.html?file=blob:19B579EA-5217-41C6-96E4-5D8DF5A5C70B
              

              现在 FF、Chrome、IE 11 和 Edge 都在通过 URL 中的标准 blob URI 传递的 iframe 中的查看器中显示 PDF。

              【讨论】:

                【解决方案16】:

                这就是我使用 AXIOS 和 Vue.js 的方式:

                        axios({
                            url: `urltoPDFfile.pdf`,
                            method: 'GET',
                            headers: headers,
                            responseType: 'blob'
                        })
                        .then((response) => {
                            this.urlPdf = URL.createObjectURL(response.data)
                        })
                        .catch((error) => {
                            console.log('ERROR   ', error)
                        })
                

                将 urlPDF 动态添加到 HTML:

                <object width='100%' height='600px' :data='urlPdf' type='application/pdf'></object>
                

                【讨论】:

                  【解决方案17】:

                  我发现这很好用,浏览器在 Firefox 中处理它。我还没查IE...

                  <script>window.location='url'</script>
                  

                  【讨论】:

                  • 这应该达到什么目的?我看不出它是如何回答这个问题的。
                  • 当我在我的 HTML 中嵌入 PDF 时,我发现最好的方法是有一个指向该文档的链接。例如 server1.network/trifold_JonesChiro.pdf" target='_blank'>Client Portal Trifold (sample) 有时打开页面并显示 pdf vs 字符串以将其放置在 html 中是一个干净的答案。它还允许 pdf 在选项卡中保持打开状态。
                  • 所以您的建议是链接,而不是嵌入?没关系,但作为答案,这还不清楚。
                  【解决方案18】:

                  如果您不想自己托管 PDF.JS,可以尝试DocDroid。它类似于 Google Drive PDF 查看器,但允许自定义品牌。

                  【讨论】:

                    【解决方案19】:

                    同时使用&lt;object&gt;&lt;embed&gt; 将为您提供更广泛的浏览器兼容性。

                    <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>
                    

                    【讨论】:

                    • 如果 pdf 插件未安装或过期,这将在浏览器中不起作用
                    • 另外,这不会对那些关注代码验证的人进行验证。
                    • 这对我很有效,而单独使用 embed 标签被 Chrome 和 Firefox 视为 unsafe
                    • 出于某种原因,在 Android (chrome) 上它不嵌入 PDF,而是提供下载它。在 iPhone (safari) 上,它只显示 PDF 的第一页。
                    【解决方案20】:

                    PdfToImageServlet 使用 ImageMagick 的 convert 命令。

                    使用示例: &lt;img src='/webAppDirectory/PdfToImageServlet?pdfFile=/usr/share/cups/data/default-testpage.pdf'&gt;

                    【讨论】:

                      【解决方案21】:
                      <object width="400" height="400" data="helloworld.pdf"></object>
                      

                      【讨论】:

                        【解决方案22】:

                        您应该考虑的选项之一是值得注意的 PDF
                        它有一个免费计划,除非您打算在 pdf 上进行实时在线协作

                        将以下 iframe 嵌入任何 html 并享受结果:

                        <iframe width='1000' height='800' src='http://bit.ly/1JxrtjR' frameborder='0' allowfullscreen></iframe>
                        

                        【讨论】:

                          【解决方案23】:

                          通过 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 只有一两页,这是一个不错的选择。当然,您需要在您的网络服务器上安装 ImageMagick(这又需要 Ghostscript),该选项在共享主机环境中可能不可用。还有一个 PHP 插件(称为 imagick)可以工作 like this,但它有自己的特殊要求。

                          【讨论】:

                          • 或使用应用程序将图像转换为 PNG,例如 Mac 上的 Preview。
                          • 但你能以编程方式做到这一点吗?
                          • 如果文档超过 1 页怎么办?我猜你只会显示第一页
                          • @seb 已经有一段时间了,但我能够在 2 或 3 页长的 PDF 上使用它。比这大得多是不明智的,我认为移动浏览器很难显示这样的图像。这就是为什么我称它为“快速而肮脏”的方法,但我认为这是一个很好的方法,只要 PDF 不超过几页。
                          • 如果您使用 zend 库打开 PDF,那么您可以执行 foreach($pdf-&gt;pages as $page) 并为每个页面创建一个图像
                          【解决方案24】:

                          Scribd 不再要求您将文档托管在他们的服务器上。如果您与他们创建一个帐户,那么您将获得一个发布者 ID。只需几行 JavaScript 代码即可加载存储在您自己的服务器上的 PDF 文件。

                          更多详情,请查看Developer Tools

                          【讨论】:

                          • 你能发布另一个链接来说明这是如何完成的吗?从您发布的链接中不清楚。
                          • 好像他们已经更新了他们的网站并改变了这个页面。我认为此页面包含我在原始帖子中所指的内容:scribd.com/developers/api?method_name=Javascript+API
                          • 我希望我能不止一次喜欢这个,它工作得很好。滚动到网站底部并单击 API 以查看示例。
                          • scribd 的注册现已关闭。
                          【解决方案25】:

                          要将文件流式传输到浏览器,请参阅 Stack Overflow 问题 How to stream a PDF file as binary to the browser using .NET 2.0 - 请注意,有细微的变化,无论您是从文件系统提供文件还是动态提供文件,这都应该有效生成。

                          话虽如此,参考的 MSDN 文章对世界的看法相当简单,因此您可能还需要阅读 Successfully Stream a PDF to browser through HTTPS 以了解您可能需要提供的一些标头。

                          使用这种方法,iframe 可能是最好的方法。有一个流式传输文件的网络表单,然后将 iframe 放在另一个页面上,并将其 src 属性设置为第一个表单。

                          【讨论】:

                          • @downvoter 想解释一下为什么你匿名否决了一个 10 年前的答案?
                          【解决方案26】:

                          xpdf 不是一个完美的 PDF 转换器。如果您需要更好的结果,那么Ghostview 可以将 PDF 文档转换为其他格式,您可以更轻松地为其构建 Flash 查看器。

                          但对于简单的 PDF 文档,FDView 应该可以正常工作。

                          【讨论】:

                          • FDView 在其他任何地方都可用吗? code4net.com 似乎消失了。
                          • @Michael 不是我能轻易找到的。如果有人在其他地方重新托管 fdview,我会留下这个答案。
                          【解决方案27】:

                          您也可以为此目的使用 Google PDF 查看器。据我所知,这不是谷歌的官方功能(我错了吗?),但它对我来说非常顺利和顺利。您需要先在某处上传您的 PDF,然后使用它的 URL:

                          <iframe src="http://docs.google.com/gview?url=http://example.com/mypdf.pdf&embedded=true" style="width:718px; height:700px;" frameborder="0"></iframe>
                          

                          重要的是它不需要 Flash 播放器,它使用 JavaScript。

                          【讨论】:

                          • 有一点需要说明的是,可以显示的PDF大小是有上限的。我认为目前是 10MB/100 页。 PS:我不认为观众是“非官方的”;他们甚至有一个为您构建嵌入 URL 的操作指南页面:docs.google.com/viewer
                          • 这个选项效果很好,但你必须让你的 PDF 公开访问,这对我来说并不总是一个选项。
                          • @riot_starter 这个解决方案不再有效,如果你完全退出谷歌它加载正常,如果你完全登录它加载正常,但是如果你介于两者之间(无论这意味着什么)它询问您的密码。在 iframe 的情况下,它只是不加载。
                          • 您可以在publicsign-in requiredprivate 之间设置任何Google 文档的隐私。考虑到 Google Docs 上的任何文档都有 embed 选项,这绝对是一项官方功能。
                          • 另外需要提一下的是“你最近发出了太多请求”的警告,这是一个限制。
                          猜你喜欢
                          • 1970-01-01
                          • 2019-10-25
                          • 2014-01-13
                          • 1970-01-01
                          • 2023-02-21
                          • 2011-06-02
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多