要在网页上显示PDF文件,首先< object >、< embed >、< iframe >这几个标签就能实现PDF文件的预览(无需JavaScript支持),我还在网上看了下发现挺多第三方js库可以实现PDF预览,如jQuery Document Viewer、jquery.media.js、PDFObject、PDF.js等等。我大概看了下PDFObject、PDF.js这两个库,前者并不是一个PDF的渲染工具,而是通过使用< embed >标签来显示PDF;后者则会解析PDF文件内容,还能将PDF渲染成Canvas。

< iframe >

所有浏览器都支持 < iframe > 标签,直接将src设置为指定的PDF文件就可以预览了。此外可以把需要的文本放置在 < iframe > 和 之间,这样就可以应对无法理解 iframe 的浏览器,比如下面的代码可以提供一个PDF的下载链接:

<iframe src="/index.pdf" width="100%" height="100%">
     
    This browser does not support PDFs. Please download the PDF to view it: <a href="/index.pdf">Download PDF</a>
     
    </iframe>

< embed >

< embed > 标签定义嵌入的内容,比如插件。在HTML5中这个标签有4个属性:
属性     值     描述
height     pixels     设置嵌入内容的高度。
width     pixels     设置嵌入内容的宽度。
type     type     定义嵌入内容的类型。
src     url     嵌入内容的 URL。

但是需要注意的是这个标签不能提供回退方案,与< iframe > < / iframe >
不同,这个标签是自闭合的的,也就是说如果浏览器不支持PDF的嵌入,那么这个标签的内容什么都看不到。用法如下:

<embed src="/index.pdf" type="application/pdf" width="100%" height="100%">

< object >

< object >定义一个嵌入的对象,请使用此元素向页面添加多媒体。此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码。用于包含对象,比如图像、音频、视频、Java applets、ActiveX、PDF 以及 Flash。几乎所有主流浏览器都拥有部分对 < object > 标签的支持。这个标签在这里的用法和< iframe >很小,也支持回退:

<object data="/index.php" type="application/pdf" width="100%" height="100%">
     
    This browser does not support PDFs. Please download the PDF to view it: <a href="/index.pdf">Download PDF</a>
     
    </object>

当然,结合< object >和< iframe >能提供一个更强大的回退方案:

<object data="/index.pdf" type="application/pdf" width="100%" height="100%">
     
    <iframe src="/index.pdf" width="100%" height="100%" style="border: none;">
     
    This browser does not support PDFs. Please download the PDF to view it: <a href="/index.pdf">Download PDF</a>
     
    </iframe>
     
    </object>

以上三个标签是一种无需JavaScript支持的PDF预览方案。下面提到的PDFObject和PDF.js都是js库。

PDFObject

看官网上的介绍,PDFObject并不是一个PDF渲染工具,它也是通过< embed >标签实现PDF预览:

PDFObject is not a rendering engine. PDFObject just writes an < embed > element to the page, and relies on the browser or browser plugins to render the PDF. If the browser does not support embedded PDFs, PDFObject is not capable of forcing the browser to render the PDF.

PDFObject提供了一个PDFObject.supportsPDFs用于判断该浏览器能否使用PDFObject:

if(PDFObject.supportsPDFs){
       console.log("Yay, this browser supports inline PDFs.");
    } else {
       console.log("Boo, inline PDFs are not supported by this browser");
    }

整个PDFObject使用起来非常简单,完整代码:

<!DOCTYPE html>
    <html>
    <head>
        <title>Show PDF</title>
        <meta charset="utf-8" />
        <script type="text/javascript" src='pdfobject.min.js'></script>
        <style type="text/css">
            html,body,#pdf_viewer{
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }
        </style>
    </head>
    <body>
        <div id="pdf_viewer"></div>
    </body>
    <script type="text/javascript">
        if(PDFObject.supportsPDFs){
            // PDF嵌入到网页
            PDFObject.embed("index.pdf", "#pdf_viewer" );
        } else {
            location.href = "/canvas";
        }
    </script>
    </html>

PDF.js

PDF.js可以实现在html下直接浏览pdf文档,是一款开源的pdf文档读取解析插件,非常强大,能将PDF文件渲染成Canvas。PDF.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,一个负责API解析,一个负责核心解析。
首先引入pdf.js文件<script type="text/javascript" src='pdf.js'></script>
PDF.js大部分用法都是基于Promise的,PDFJS.getDocument(url)方法返回的就是一个Promise:

PDFJS.getDocument('../index.pdf').then(pdf=>{
            var numPages = pdf.numPages;
            var start = 1;
            renderPageAsync(pdf, numPages, start);
        });

Promise返回的pdf是一个PDFDocumentProxy对象官网API介绍是:

Proxy to a PDFDocument in the worker thread. Also, contains commonly used properties that can be read synchronously.

PDF的解析工作需要通过pdf.getPage(page)去执行,这个方法返回的也是一个Promise,因此可以通过async/await函数去逐页解析PDF:

async function renderPageAsync(pdf, numPages, current){
            for(let i=1; i<=numPages; i++){
                // 解析page
                let page = await pdf.getPage(i);
                // 渲染
                // ...
            }
        }

得到的page是一个PDFPageProxy对象,即Proxy to a PDFPage in the worker thread 。这个对象得到了这一页的PDF解析结果,我们可以看下这个对象提供的方法:
方法     返回
getAnnotations     A promise that is resolved with an {Array} of the annotation objects.
getTextContent     That is resolved a TextContent object that represent the page text content.
getViewport     Contains ‘width’ and ‘height’ properties along with transforms required for rendering.
render     An object that contains the promise, which is resolved when the page finishes rendering.

我们可以试试调用getTextContent方法,并将其结果打印出来:

page.getTextContent().then(v=>console.log('page', v));

第一页部分结果如下:

{
        "items": [
            {
                "str": "小册子标题",
                "dir": "ltr",
                "width": 240,
                "height": 2304,
                "transform": [
                    48,
                    0,
                    0,
                    48,
                    45.32495,
                    679.04
                ],
                "fontName": "g_d0_f1"
            },
            {
                "str": " ",
                "dir": "ltr",
                "width": 9.600000000000001,
                "height": 2304,
                "transform": [
                    48,
                    0,
                    0,
                    48,
                    285.325,
                    679.04
                ],
                "fontName": "g_d0_f2"
            }
          ],
        "styles": {
            "g_d0_f1": {
                "fontFamily": "monospace",
                "ascent": 1.05810546875,
                "descent": -0.26171875,
                "vertical": false
            },
            "g_d0_f2": {
                "fontFamily": "sans-serif",
                "ascent": 0.74365234375,
                "descent": -0.25634765625
            }
        }
     }

我们可以发现,PDF.js将每页文本的字符串、位置、字体都解析出来,感觉还是挺厉害的。

官网有个demo,还用到了官网提到的viewer.js(我认为它的作用是对PDF.js渲染结果再次处理):http://mozilla.github.io/pdf.js/web/viewer.html,我看了一下它的HTML机构,首先底图是一个Canvas,内容和PDF一样(通过下面介绍的page.render方法可以得到),底图之上是一个textLayer,我猜想这一层就是通过page.getTextContent()得到了字体的位置和样式,再覆盖在Canvas上:

通过这种方式就能实现再预览文件上选中文字(刚开始我还在纳闷为什么渲染成Canvas还能选择文字)

将page渲染成Canvas是通过render方法实现的,代码如下:

async function renderPageAsync(pdf, numPages, current){
            console.log("renderPage async");
            for(let i=1; i<=numPages; i++){
                // page
                let page = await pdf.getPage(i);
     
                let scale = 1.5;
                let viewport = page.getViewport(scale);
                // Prepare canvas using PDF page dimensions.
                let canvas = document.createElement("canvas");
                let context = canvas.getContext('2d');
                document.body.appendChild(canvas);
     
                canvas.height = viewport.height;
                canvas.width = viewport.width;
     
                // Render PDF page into canvas context.
                let renderContext = {
                        canvasContext: context,
                        viewport: viewport
                };
                page.render(renderContext);
            }
        }

PDF.js是Mozilla实验室的作品,感觉真的很强大!
我在码云上有个demo,结合了PDFObject和PDF.js。因为PDFObject使用的< embed >标签可以直接显示PDF文件,速度很快;但是手机上很多浏览器不支持,比如微信的浏览器、小米浏览器,所以我就使用了PDF.js将其渲染成Canvas,速度与PDFObject相比慢多了,但至少能看。-_-||
demo地址:https://git.oschina.net/liuyaqi/PDFViewer.git

参考:
PDFObject:https://pdfobject.com
PDF.js: http://mozilla.github.io/pdf.js/

---------------------
作者:ruanhongbiao
来源:CSDN
原文:https://blog.csdn.net/qappleh/article/details/80250492

前端预览PDF总结:iframe、embed、PDFObject、PDF.js相关推荐

  1. 前端预览 PDF 文件几种方式汇总(使用PDFJS)

    哈喽大家好啊.前半年还挺忙的,一直也没有发文章,有老哥想我了嘛.这两天发现老有人私信问我 PDF 相关的内容. 那么好,为了我能安心摸鱼,我准备出一篇文章来介绍一下如何使用 PDFJS . PDF.j ...

  2. 不使用前端的pdf.js,通过pdfbox转换pdf为图片,拼接成html实现pdf前端预览

    一般情况,pdf类型的文件在前端预览,都是通过前端插件,或者获取源文件浏览器自带的工具预览,由于项目中,是前后端分离,前端不想使用pdf.js类的插件,预览的要求又是只能看不能下载,所以只能另外想别的 ...

  3. 前端技术实现文件预览(word、excel、pdf、ppt、mp4、图片、文本)

    前言 因为业务需要,很多文件需要在前端实现预览,今天就来了解一下吧. Demo地址[1]:https://zhuye1993.github.io/file-view/dist/index.html 实 ...

  4. 实现PPT的在线预览(动态,及转PDF)

    实现PPT的在线预览(动态,及转PDF) 公司的新需求,需要在网页上动态预览PPT,此处记录下,防止忘记. 之前在网上找了很多资料,比如:用POI 实现等,这里写下自己的实现方法 1.PPT 转PDF ...

  5. 前端预览-Word(.docx)

    目前前端预览有以下几个方案: 1.使用微软.永中等第三方提供的服务进行预览. 2.前端使用docx-preview.mammoth两个插件进行预览. 3.后端提供服务或者转为pdf进行预览. 以下逐条 ...

  6. vue中将base64的pdf文件流转换成pdf并预览(二)——base64转PDF工具的使用

    vue中将base64的pdf文件流转换成pdf并预览(二)--base64转PDF工具的使用 Base64 to PDF官网 1.官网 官网--https://www.ipvoid.com/base ...

  7. 实现文件预览的多种方式(office, image, pdf)

    实现文件预览的多种方式(office, image, pdf) 使用 xdoc 文档预览云服务, 直达链接 使用方式 http://view.xdocin.com/xdoc?_xdoc=文件全路径 使 ...

  8. 前端预览word文档实现

    记录前端预览word文档的需求实现 方案一:XDOC文档预览 可以使用XDOC文档预览云服务来进行word文件的在线预览,直接去网站体验就知道怎么用了. https://view.xdocin.com ...

  9. React:后端返回pdf数据流,前端打开页面预览,使用fetch,PDFObject

    预览页面: import React, { useEffect } from 'react'; import { connect } from 'react-redux'; import PropTy ...

  10. vue项目实现前端预览word和pdf格式文件

    最近做vue项目遇到一个需求,就是前端实现上传word或pdf文件后,后端返回文件对应的文件流,前端需要在页面上展示出来.word预览简单一些,pdf预览我试过pdfjs,vue-pdf总是报各种奇奇 ...

最新文章

  1. COMP 0137 Machine Vision
  2. 九、OLTP 性能调整与优化--结语
  3. 047_Unicode对照表十三
  4. PCL环境配置失败和运行PCL自带例子
  5. 面试总结-百度(2)
  6. 【maven】dependency的systemPath属性:引入本地系统中的jar
  7. var类型推断关键字
  8. javascript DOM事件总结
  9. 一个简简单单检测http服务状态的脚本
  10. 深度学习模型的可视化技术总结
  11. 盘点那些没用的上网小技巧-主流直播平台直播源的获取(适用potplayer)
  12. 记一次SQLServer2019安装和卸载问题的解决过程
  13. Python入门学习—列表(FishC)
  14. 蔡为东:行之有效的IT技术团队管理实践
  15. python中function是什么意思_Python中的Function定义方法
  16. 转:为什么你不是真正的快乐
  17. SPJ数据库-初识sql语句(05)(注释版)
  18. java处理保留小数点后几位
  19. 运行python程序的两种方式交互式和文件式_Python基础知识2
  20. Java枚举和C枚举的转换——JNI笔记

热门文章

  1. java对称矩阵_对称矩阵与压缩存储算法(java实现)
  2. 【ADMM】ADMM Gap
  3. 网易云服务器怎么上传文件,怎么把本地歌曲上传到网易云上
  4. 在plc中用c语言实现电梯控制程序,基于PLC的电梯控制系统的设计与实现[论文+答辩ppt+完整程序代码]...
  5. 华为HCIE云计算培训笔记第二天
  6. ARINC429硬件层初探
  7. 【A星算法】--第四篇(A星算法)
  8. qq远程卡主,只能看到桌面,鼠标、键盘操作不了的解决方法
  9. 服务器内存有很多不显示,这里大神多,帮忙看看这个服务器内存是不是真的
  10. 华中数控系统与高创驱动器EtherCat通讯设置及控制参数