最近弄的项目中需要在线展示PDF文件,以前用的是Adobe PDF阅读器直接在浏览器端打开的,这要求客户端必须安装这个软件,若是没有安装就不能在线预览了。为了解决这个问题,最终决定用pdf.js来实现预览功能。

1、PDF.js下载

下载链接:http://mozilla.github.io/pdf.js/

下载下来的压缩包包含两个文件夹:build和web,打开web文件夹下的viewer.html,就能看到PDF的预览效果了。

预览的PDF文件是位于viewer.html同目录下的compressed.tracemonkey-pldi-09.pdf,

而设置加载这个文件的地方是:与viewer.html同目录下的viewer.js的DEFAULT_URL属性,修改这个属性的值就能够预览不同的文件,中英文的pdf文件都能成功预览

2、功能使用

使用pdf.js在web页展示pdf文件的关键是打开viewer.html,也就是在web页打开一个html,可以用的方法至少有两三种:

a、a标签:<a href="PDFJS\web\viewer.html">使用pdf.js展示pdf文件</>

b、window.open:window.open("PDFJS\web\viewer.html");

c、iframe:<iframe  src="PDFJS\web\viewer.html" />

3、在客户端预览服务器端的文件:使用文件流进行解决

以我此次使用的情况为例,我使用的iframe进行展示:

第一步:设置iframe的请求路径

var src="pdfjs/web/viewer.html?file=/testWeb/fileRouter!openDocInPdf.action";

说明:

a、pdfjs/web/viewer.html这个必须带,没什么可说的

b、若是从服务器端请求文件,必须使用file这个关键字,用来告知pdf.js你这个是文件流。我是怎么知道的?百度+源码。看网上的demo时说要用这个关键字,我也纳闷你怎么知道要用这个关键字,就去看源码了,跟踪的过程中,发现viewer.js的webViewerInitialized()的方法中有这么一句

file = 'file' in params ? params.file : appConfig.defaultUrl;

这就很明显了,你要是没有file我就使用默认值。所以必须用file关键字。

c、testWeb是我的项目名称,在此处请求action时必须加上:/项目名称。不这么处理会报404(至少我这块儿是这样子)。

怎么个404??假设我的项目访问路径为:http://127.0.0.1:8080/testWeb,

若写成 file=/testWeb/fileRouter!openDocInPdf.action,(上面说的写法)

那么请求路径就是:http://127.0.0.1:8080/testWeb/fileRouter!openDocInPdf.action,正确

若写成 file=fileRouter!openDocInPdf.action (不加上/testWeb)

那么请求路径:http://127.0.0.1:8080/fileRouter!openDocInPdf.action (404)

或者写成:file=/fileRouter!openDocInPdf.action(不加上testWeb,只加了/)

请求路径:http://127.0.0.1:8080/fileRouter!openDocInPdf.action (404)

第二步: 使用iframe进行请求

$("body").append("<iframe  width=\"100%\" height=\"100%\" src='"+src+"' />");

第三步:action请求

HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("application/pdf");
FileInputStream in = new FileInputStream(pdfFile);
OutputStream out = response.getOutputStream();byte[] b = new byte[1024];
while ((in.read(b)) != -1) {out.write(b);
}
out.flush();
in.close();
out.close();

当然在实际应用中,经常牵涉到带参数的问题,这就是后面要说的第四个点了。

4、带参数进行文件请求

带参数的URL通常都这么写: fileRouter!openDocInPdf.action?id=123,

按照一般情况处理,此处应该是:var src="pdfjs/web/viewer.html?file=/testWeb/fileRouter!openDocInPdf.action?id=123";

按照这个路径去请求最后的请求链接会变成:http://127.0.0.1:8080/testWeb/fileRouter!openDocInPdf.action?id,这样子的请求路径必然会报错,那么为什么会这样子呢?还是viewer.js的webViewerInitialized(),里面处理链接的代码是这样子的:

var appConfig = PDFViewerApplication.appConfig;
var file = void 0;
var queryString = document.location.search.substring(1);
//alert(queryString);//结果:file=/testWeb/fileRouter!openDocInPdf.action?id=123,
var params = (0, _ui_utils.parseQueryString)(queryString);
//alert(params.file);//结果:testWeb/fileRouter!openDocInPdf.action?id
file = 'file' in params ? params.file : appConfig.defaultUrl;
validateFileURL(file);

看结果就知道问题出在第四行,第四行的parseQueryString方法如下:

function parseQueryString(query) {var parts = query.split('&');var params = Object.create(null);for (var i = 0, ii = parts.length; i < ii; ++i) {var param = parts[i].split('=');var key = param[0].toLowerCase();var value = param.length > 1 ? param[1] : null;params[decodeURIComponent(key)] = decodeURIComponent(value);}return params;
}

这下应该知道请求链接为什么会变成那个样子了。

其实上面的例子存在一个问题,细心的可能已经发现了,那就是请求链接的问题:var src="pdfjs/web/viewer.html?file=/testWeb/fileRouter!openDocInPdf.action?id=123",一个url中不可能存在多个?,只有第一个参数用?其他的都用&,如果这个请求换成&号会怎么样,会不会就没有问题了呢??

假设请求是这个样子的:var src="pdfjs/web/viewer.html?file=/testWeb/fileRouter!openDocInPdf.action&id=123",viewer.js的webViewerInitialized()的执行结果就是:

var appConfig = PDFViewerApplication.appConfig;
var file = void 0;
var queryString = document.location.search.substring(1);
//alert(queryString);//结果:file=/testWeb/fileRouter!openDocInPdf.action&id=123
var params = (0, _ui_utils.parseQueryString)(queryString);
//alert(params.file);//结果:testWeb/fileRouter!openDocInPdf.action
file = 'file' in params ? params.file : appConfig.defaultUrl;
validateFileURL(file);

最后就变成了没有参数。

接下来说解决办法,我觉得至少有两种

第一种: parseQueryString()方法中起关键作用的是split("="),带参数的时候因为有多个等号除第一个之外的其他都没干掉了,那么我若是保证这个url中只有file=这儿的一个等号呢,于是就可以改成:

var src = "pdfjs/web/viewer.html?file="+encodeURIComponent("/testWeb/fileRouter!openDocInPdf.action?id=123");

如此就会变成:file=%2FtestWeb%2FfileRouter!openDocInPdf.action%3Fid%3D123

最后的请求链接就是:http://127.0.0.1:8080/testWeb/fileRouter!openDocInPdf.action?id=123,这样子的请求是正确的。

第二种:改处理方法,人为的定义file中的值

将webViewerInitialized()中处理参数的代码改成:

  var appConfig = PDFViewerApplication.appConfig;var file = void 0;var queryString = document.location.search.substring(1);/*注释掉原来的参数处理方法var params = (0, _ui_utils.parseQueryString)(queryString);file = 'file' in params ? params.file : appConfig.defaultUrl;*///使用一下的代码进行处理if(queryString.split("file2=").length>0){file = queryString.split("file2=")[1];}else{file = appConfig.defaultUrl;}validateFileURL(file);

然后iframe的src改成: var src="pdfjs/web/viewer.html?file2=/testWeb/fileRouter!openDocInPdf.action?id=123";

如此请求就会变成:http://127.0.0.1:8080/testWeb/fileRouter!openDocInPdf.action?id=123

至此,带参数的问题解决。

使用pdf.js在web页面展示pdf文件相关推荐

  1. PDF.js实现html页面读取pdf文件内容

    项目中遇到要在HTML页面上读取PDF文档的内容,并显示在网页上. pdf.js官网:pdf.js官网 本地附件:pdf.js 一.下载 1.下载至本地 2.创建PDF.js文件夹 并将刚解压的文件放 ...

  2. [置顶] 读取pdf并且在web页面中显示

    读取pdf并且在web页面中显示 if (System.IO.File.Exists(f)) { Response.ContentType = "applicationpdf"; ...

  3. pdf.js 利用HTML5技术显示pdf内容

    Mozilla实验室最近在github上开源了一款js库pdf.js,用来读取PDF文件. http://mozilla.github.io/pdf.js/ Using base64 encoded  ...

  4. html 打印预览 兼容,vue下使用 pdf.js 预览 和 打印 PDF文档 兼容React

    我使用前端开发框架是vue,有一个打印PDF文档的需求. 这个需求最开始是交给后台,但是明显不切实际, 因为后台服务器,根本就无法连接打印机. 所以这个预览加打印文档的需求就交到了前端, 开始我有想过 ...

  5. vue下使用 pdf.js 预览 和 打印 PDF文档 兼容React

    我使用前端开发框架是vue,有一个打印PDF文档的需求. 这个需求最开始是交给后台,但是明显不切实际, 因为后台服务器,根本就无法连接打印机. 所以这个预览加打印文档的需求就交到了前端, 开始我有想过 ...

  6. JavaScript前端:与PDF.js结合,实现网页PDF内容批量下载

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 JavaScript前端:与PDF.js结合,实现网页PDF内容批量下载 前言 一.PDF.js是什么? 二.PDF.js单个PDF文 ...

  7. 利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能)

    利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能) 参考文章: (1)利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功 ...

  8. html展示markdown文件,在前端页面展示Markdown文件

    常我们都会在GitHub上浏览很多的readme文件,这些都是Markdown语法写成的Markdown文件,HTML中并没有用于展示Markdown文件的元素,那么为什么可以在前端展示呢? 有别于G ...

  9. pdf.js使用方法整理,web页面中pdf在线查看,web页面显示pdf文档

    pdf.js 使用步骤: 一.到官网下载 pdf.js 插件并解压  (地址: http://mozilla.github.io/pdf.js/ ) 若官网无法下载,通过下面链接下载,注:作者有测试方 ...

最新文章

  1. MySQL主从复制原理图
  2. Freebsd10上部署open*** 服务器
  3. RabbitMQ中的消息不可达returnlistener和mandatory的使用
  4. SAP ABAP ALV构建动态输出列与构建动态内表
  5. .Net开发的两个小技巧
  6. 中两个数做减法_人生下半场,学会做减法
  7. 华为美国研发中心将迁至加拿大;高通CEO否认中国5G超美国:技术上还没有,顶多算并驾齐驱;亚马逊宣布进军量子界……...
  8. java 度量_Java度量方法调用率
  9. 我的 WinClock 项目系列之一 (概述)
  10. 高富帅与大公司 续三 自我认知
  11. P2P-JXTA学习(1)-入门
  12. 大漠插件注册使用方法教程
  13. Clearcase, SVN, Git之我见
  14. 系统架构师论文-论新技术的引进
  15. Java - 两个对象值相同(x.equals(y) == true),但却可以有不同的hash code,这句话对不对?
  16. RS-485位移传感器集线器的功能大家了解吗?
  17. 老旗舰华为能用上鸿蒙吗,千元机也能用鸿蒙!曝荣耀 9X 手机年内全部升级鸿蒙系统...
  18. Python中的arg,*args,**kwargs用法
  19. 总结非结构化数据分析「十步走」
  20. java实现809*两位数=800*两位数+9*两位数,求出两位数的值。其中8*两位数的结果为两位数,9*两位数的结果为三位数

热门文章

  1. 中华石杉讲解mysql_中华石杉老师课程汇总
  2. My A710, wait me
  3. 【架构师之路 四】需要掌握的技能点---架构性能优化
  4. fabric 启动peer_Hyperledger fabric peer数据膨胀解决方案探讨
  5. 可逆电子计算机,基于可逆逻辑的计算机系统原型(Recom-II)
  6. Unity体感设备KinectV2虚拟换装解决方案
  7. 五十音三天快速记忆方法汇总
  8. websocket粘包处理
  9. 拧瓶盖螺丝,高度灵活的柔性机器人为你开可口可乐
  10. 七巧板复原算法——摆放和贴合算法的改进