清泛网Demo地址:https://www.tsingfun.com/statics/pdf.js/web/viewer.html
前言
英文是github上的原文,找不到中文资料,我根据自己理解翻译的,有些词意思拿不准就直接把单词留在原地了,看这个文档应该可以凑合着用了。
PDF.js是什么
PDF.js is a Portable Document Format(PDF) viewer that is built with HTML5.PDF.js is community-driven and supportedby Mozilla Labs. Our goal is to create a general-purpose, web standards-basedplatform for parsing and rendering PDFs.
PDF.js是一个由HTML5建立的PDF阅读器。依托开源社区驱动和Mozilla实验室的技术支持。目标是建立一个通用的,基于web的解析和渲染PDF文件的平台。https://github.com/ChineseDron/pdf.js# 是从Mozilla原版中fork出来的一个版本,原版的链接在这里https://github.com/mozilla/pdf.js 原版的版次新一些,我们用原版。
PDF.js怎么用
这个viewer我觉得就是PDF.js的最终UI。根据以往经验,网上能下载的demo,从来就没有见过能正常运行的,不过我还是抱着侥幸试了一下,PDF.js果然也不例外。从github上面我们可以下载PDF.js项目源代码,examples里有几个demo示例,helloworld运行就报错,此处省略研究过程1W字,大家只用看结论就可以了:IE9报错就升级的IE10,我也是试出来的,这个时候还不知道原因。其他的demo示例运行不是页面全黑就是全白,可以直接删了。
Mozilla有一个比较简单的Pre-built版demo程序,改造一下就可以用了。
2.1 demo程序的结构翻译
build/ |
|
pdf.js |
display layer 显示层采用核心层并且暴露了一个更容易使用的API来渲染PDF文件,并获得其他的资料出文件。该API基于不同的版本号而不同。 |
pdf.worker.js |
core layer core层是PDF解析和解释核心功能,是所有其它层的基础 |
web/ |
|
cmaps/ |
character maps(required by core) 字符映射(core层需要的资源) |
compatibility.js |
polyfills for missing features Polyfilling 是由 RemySharp提出的一个术语,它是用来描述复制缺少的 API和API功能的行为。 |
09.pdf |
test pdf 测试用的pdf文件 |
debugger.js |
helpful pdf debugging features |
images/ |
images for the viewer and annotation icons viewer界面的图标 |
l10n.js |
localization |
locale/ |
translation files 翻译文件,包含所有支持语言的翻译资源 |
viewer.css |
viewer style sheet viewer界面的css |
viewer.html |
viewer html viewer主界面 |
viewer.js |
viewer layer viewer界面的js,页面参数包括加载的PDF文件路径都在这里设置 |
2.2 我想只要满足下面两个要求就算大家可以用了
1.打开任意想打开的pdf文件(这就是github上的FAQ的第一个问题)
2.能够通过.net后台动态的控制与打开pdf有关的参数
第一个问题:
我们只用修改viewer.js文件中的pdf路径参数即可:
var DEFAULT_URL = '09.pdf';
如果pdf文件与viewer.html不在一层目录中,改成相对路径即可:
var DEFAULT_URL = ' ../doc/ 09.pdf';
第二个问题:
viewer.html可以通过页面参数传值的方式加载pdf文件,比如我们想打开09.pdf文件的话,只需要这样:
先把viewer.js中的参数修改为空:
var DEFAULT_URL = '';
然后把url改写为参数传值:
http://localhost:54175/PDFJSInNet/web/viewer.html?file=09.pdf
如果pdf文件与viewer.html不在一层目录中,改成相对路径即可:
http://localhost:54175/PDFJSInNet/web/viewer.html?file=../doc/09.pdf
非常容易通过Visual Studio控制后台代码动态拼出这样一个url字符串。
2.3 补充
viewer的demo程序示例的toolbar工具比较全,第二个是打印第三个是下载,如果我们只想做在线阅读,不许用户打印或者下载文档的话,把这两个按钮隐藏掉或者删掉即可,在viewer.html源码第180行186行
2.4 再补充
viewer在解析和渲染pdf的时候有点耗费系统资源,尤其是cpu资源,不知道是不是因为我的本子配置较低的缘故,在页面加载等待的过程中,IE进程消耗掉了CPU资源的50-60%。点击翻页操作,或者改变IE的窗口大小会触发viewer对pdf进行重新解析和渲染。有时把IE前端的某个挡住他的程序窗口(比如一个txt)移开也会导致重新渲染,但是并不是每次都会触发,原因不详。
如果在viewer解析和渲染的过程中尝试用adobe reader之类的工具打开那个pdf文件,系统会出现第二个iexplore.exe *32的进程,有时是AcroRd32.exe *32进程,两个进程加一起几乎耗去了100%的CPU资源,此时机器已经显得比较卡了。多点两下就会出现页面未响应,但是一般情况下是假死,等几秒就会活过来,我试了很多次还没有遇到真死的情况。
我用一个7M大的PDF测试了一下速度,能感觉出解析和渲染的时间变长了,但是时间还没有长到不能忍受(FAQ里的最后一个问题有提到)
官方上的FAQ
我只选取了我认为可以用得到的问题。
Can Ispecify a different PDF in the default viewer?可以指定一个不同的PDF文件给viewer打开吗?
You canmodify the DEFAULT_URL
variable in the web/viewer.js
file or you can append the ?file=
query string to the viewer URL, e.g.http://mozilla.github.com/pdf.js/web/viewer.html?file=compressed.tracemonkey-pldi-09.pdf
.
在2.2章节已经回答了。
Can I load a PDF fromanother server (cross domain request)?能否从其它服务器读取pdf文件(跨域访问)?
Notby default, but it is possible. PDF.js runs with the same permissions as anyother JavaScript code, which means it cannot do cross origin requests (see Same origin policy and an example).There are some possible ways to get around this such as using CORS (seealso unsafeheaders issue and Access-Control-Expose-Headersissue) or setting up a proxy on your server thatwill feed PDF.js the PDF file. Both workarounds are out of the scope of thePDF.js project and we will not provide code to do either.
不默认,但它是可能的。 PDF.js运行具有相同权限的任何其他JavaScript代码,这意味着它不能跨出自身请求(见同根同源的政策和示例) 。有一些可能的方法来解决这个问题,如使用CORS (seealso unsafe headers issue and Access-Control-Expose-Headersissue),或者设置你的服务器上的代理,将PDF文件提供给PDF.js。这两种解决方法都出了PDF.js项目的范围,我们将不提供代码,请执行。
What browsers are supported?支持哪些浏览器?
The goal is to support all HTML5 compliant browsers, but sincefeature support varies per browser/version our support for all PDF featuresvaries as well. If you want to support more browsers than Firefox you'll needto include compatibility.jswhich has polyfills for missing features. Find the list offeatures needed for PDF.js to properly work and browser tests for thosefeatures at RequiredBrowser Features. In general, the support is below:
我们的目标是支持所有HTML5兼容的浏览器,但是每个浏览器/版本对PDF的所有特性的支持是不同的。如果你想支持除了Firefox以外的更多种浏览器,你需要有compatibility.js文件,它有polyfills丢失的功能。想查找PDF.js正常工作所需的浏览器的测试要求,请参考如下浏览器特性的列表:
Browser |
Supported |
Automated Testing |
Notes |
Firefox Stable |
yes |
Windows and Linux |
|
Chrome Stable |
yes |
Windows and Linux |
|
Opera Stable |
yes |
none |
|
Android |
limited |
none |
Android's Web Browser version 4.0 or below lacks a number of features or has defects, e.g. in typed arrays or HTTP range requests |
Safari |
limited |
none |
Safari (desktop and mobile) lacks a number of features or has defects, e.g. in typed arrays or HTTP range requests |
IE9 |
limited |
none |
IE9 lacks a number of features and most notably typed arrays which causes subpar performance. IE9缺少了一些功能和最显着的类型化数组,支持性表现欠佳,我想到了之前运行出错的helloworld.... |
<=IE8 |
NO |
none |
IE8 and below are missing too many features to be supported. IE8及以下缺失太多的功能特性以至于无法得到支持。 |
Is it possible to add annotations to aPDF?是否可以向pdf文件添加注解?
PDF.js is mainly written for reading PDF files, not editing them. Becauseof that we don't yet support adding any kind of annotations. We do howeversupport rendering a number of annotation types for viewing.
PDF.js主要是写阅读PDF文件,而不是编辑它们。正因为如此,我们还不支持添加任何注释。然而,我们也支持渲染一些注释类型以供查看。
The PDF.js files are too big. Can you provide minified versions ofJS files?PDF.js文件太大,可以提供缩小版的js文件吗files?
仅为google编译器(GoogleClosure Compiler)提供
I know that my PDFs arecorrupted.Will PDF.js attempt to display it?
Yes. PDF.js will attempt to recover usable PDF data (pages,content or fonts) and display the document. Please report the issue (see above)and we will take a look.
是。PDF.js将尝试恢复可用的PDF数据(页,内容或字体),并显示文档。
What types of PDF files are slow in PDF.js? Can I optimize a PDFfile to make PDF.js faster?什么样的pdf文件会导致PDF.js运行速度减慢,是否可以优化pdf文件使PDF.js速度变快?
Typically, PDFs with a smaller filesize will be rendered faster and it depends on how big a single page is. Theamount of pages does not affect the performance. It's essential that youoptimize your documents for the web. See Optimize a PDFfromAdobe's website for more information. There are more improvement techniquesthat we can suggest:
- Avoid using high resolution images -- 150 dpi resolution for scanned images shall be enough for screens, especially for low powered devices;
- Try to use JPEG encoding for color images/photos inRGB colorspacewhen possible;
- Avoid using expensive compositions/effects such as transitions/masking --flatten transparency;
- Avoid using PDF generators (or don't create content) that produce ineffective PDF output (e.g. LibreOffice creates a lots of tiny images for vector elements/pictures it does not understand);
- If there is such a setting, use web-optimized PDF output / linearization;
- Fix or don't produce corrupted PDFs that do not conform to the PDF32000 specification.
通常情况下, PDF文件以更小的文件大小将变得更快,这取决于单页(数据量?)有多大。还有更多的改进技术,我们可以建议:
1.避免使用高清晰度的图像- 建议不超过150dpi的分辨率的扫描图像,尤其是对于低功率设备;
2.如果可能的话,尝试使用JPEG编码的彩色图像或者是RGB色彩的照片;
3.避免使用华丽的成分/效果,如转换/屏蔽- 拼合透明度;
4.避免使用PDF生成器(或者不创造内容)产生无效的PDF输出(如LibreOffice中创建大量的微小的图像,矢量元素/图片);
5.使用的网络优化格式的PDF;
6.修复或不产生不符合PDF32000规范的PDF文件。
回答网友提问 2015-1-19
chrome是可以通过参数传值方式打开PDF的,我用的版本是39.0.2171.95 m
回答网友提问 2015-7-28
因为好多人问能不能显示中文的问题,我总结大致分为两类问题:
1.能否显示中文?2.能否读取远程服务器上的PDF(包括中文文件名)
第一个问题:能否显示中文?
首先,显示中文肯定是可以的,不论是文件名还是文件的正文,见下图:
如果你说显示不出中文,我想是不是下面这种情况:
这属于js中文乱码问题,你看中文文件名完全没有识别出来,看一下你的viewer.html文件在<head>标记是不是有这句:<meta charset="utf-8">
换成:<meta http-equiv="Content-Type" content="text/html" charset="gb2312" > 就可以啦!说白了就是charset换成gb2312
第一个问题over。
第二个问题:能否读取远程服务器上的PDF(包括中文文件名)
我们哆嗦一点,从头说起,首先用mozilla的example证明读取远程服务器上的pdf绝对没有问题,见下图
读取http://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf
然后我换成公司服务器上的pdf文件地址,运行,如下图所示,我想大多数人遇到的都是这个问题。
这个问题简单说就是跨域访问,其实mozilla的example里有一段声明提到了这个问题,只是这个声明不那么显眼,在helloworld.html中,见下图
(CORS) - most servers don't support cross-origin browser requests.
CORS就是跨域访问,大多数服务器都不支持跨域访问。
要解决跨域访问问题,有很多解决方案,由于能力有限,那些好复杂的处理办法我还完全不懂,不过我百度的水平还是一流的,下面这个链接就是处理这个问题的简单方法,无奈中文资料太少。http://www.webdavsystem.com/ajax/programming/cross_origin_requests
如果看不懂英文,我翻译过来就是一张图
设置完毕后再运行:成功,跨域访问问题顺利解决,见下图。第二个问题OVER。
关于7.28第二个问题的延伸,同事帮助解决了一个小细节 2015-11-17
同事使用的时候发现一个小问题,跨域访问按照我所说的问题2设置了还是不行(IE浏览器),但是用搜狗浏览器极速模式就可以,于是采取了如下办法问题解决:在页面添加 <meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-8" />
demo程序点此下载
清泛网注:一般在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题,详细请参考《Access-Control-Allow-Origin与跨域》。