pdf预览相对word、excel、ppt等文件的预览比较容易,因为常见的浏览器都是支持pdf文件直接预览,所以最简单的实现方法就是在浏览器中直接输入pdf文件存放在服务器上的路径地址就可以直接预览;
1、使用浏览器默认支持访问pdf文件的功能
1.1、当后端返回的是pdf文件在服务器上的路径时,直接访问该路径即可
1.2、当后端返回的是pdf文件流时,直接访问文件流接口时,浏览器会默认下载该pdf文件,此时需要对该接口的响应头进行设置,具体如下:
Content-Disposition: inline;filename=<pdf的文件名>
Content-Type: application/pdf;charset=UTF-8
Content-Disposition有两个值:attachment和inline,attachment表示下载文件,inline表示内嵌显示;
上面设置的目的就是告诉浏览器,当前接口返回的文件流是pdf格式,且需要内嵌显示,也就是告诉浏览器不要下载文件,应该预览。
这样当我们调用后端接口,后端返回pdf文件流时就可以直接在浏览器上访问;
2、使用PDF.js进行预览
PDF.js是mozilla开源的一个可以解析、预览pdf文件的插件,它本身提供了预览页面方便我们直接传入pdf文件地址进行预览,具体使用如下:
- 1、到PDF.js官网下载PDF.js插件
2、解压下载好的PDF.js插件
3、在vue项目根目录下创建static文件夹用于存放静态资源(已存在则不需要重复创建),在static下新建名称pdf文件夹并将解压后的pdf.js文件放在该目录中
4、webpack配置将static文件夹下的静态资源复制到dist目录下,这样开启本地服务或上线后可以访问到静态资源
4.1、安装
copy-webpack-plugin
插件
npm install -D copy-webpack-plugin
- 4.2、在webpack配置文件中引入:
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
...
plugins: [
new CopyPlugin([
{
from: path.resolve(__dirname, './static'),
to: path.resolve(__dirname, './dist/static'),
ignore: ['.*']
}
]),
],
...
};
- 5、在vue文件中使用pdf.js提供的预览页面来预览pdf文件
我们就是利用viewier.html文件来进行pdf文件的预览。
window.open(`/static/pdf/web/viewer.html?file=${pdfFileUrl}`);
使用上面代码就可以新开页预览pdf文件,就是使用viewer.html通过传入文件地址来进行预览,pdfFileUrl
为pdf文件存放服务器的地址
Q&A:
1、PDF.js是一个开源的插件,为什么不使用npm install方式安装?
因为需求比较简单,只要预览就可以,对预览页面涨什么样没有要求,所以采用PDF.js提供的预览页面也就是viewer.html来实现预览是最省事的。npm上关于PDF.js的包有两个分别是pdfjs和pdfjs-dist,其中pdfjs-dist的下载量比pdfjs的多,通过npm install安装pdfjs和pdfjs-dist后可以发现其文件中均没有viewer.html(如下图所示),所以无法使用PDF.js提供的预览页面来预览。那使用pdfjs和pdfjs-dist的是如何预览的?它们负责提供解析pdf文件,并将解析内容输出来,预览的话需要自己来写一个预览页面,对于对pdf预览页面有特殊定制需求的话可以使用该方法;
2、为什么要使用copy-webpack-plugin插件将静态资源复制一份到dist目录下?
我们在本地启动项目后,通过localhost:8080访问时,其实就是访问webpack-dev-server上的静态资源,webpack会自动打包项目代码并将打包后代码放在webpack-dev-server上,也就是使用dist下的资源作为静态资源,因此,无论是开启本地服务还是上线之后,我们都需要将PDF.js的文件作为静态资源放在服务器上;而copy-webpack-plugin插件可以很方便的帮助我们将静态资源放在dist目录下。
可能会遇到的问题:
2.1、在使用copy-webpack-plugin插件时,需要注意由于copy-webpack-plugin插件版本与webpack版本不兼容带来的问题。
我们项目使用的webpack版本是3.x版本的,如果安装最新的copy-webpack-plugin插件也就是5.x版本的,会出现如下报错:
TypeError: Cannot read property 'emit' of undefined at CopyPlugin.apply
解决办法:
对于webpack 3.x版本的,推荐安装copy-webpack-plugin 4.x版本的,这样就不会出现版本兼容问题,亲测有效。
3、在使用viewer.html预览时,当传入pdf文件地址时报如下错误:
这是由于pdf.js不支持跨域请求,才报的错:file origin does not match viewer’s
解决办法:
简单粗暴的方法就是把viewer.js的判断远程地址的代码注释掉即可
在viewer.js文件中找到如下判断,注释即可:
// if (origin !== viewerOrigin && protocol !== 'blob:') {
// throw new Error('file origin does not match viewer\'s');
// }