📝 使用背景
在前端开发中,有时候我们需要进行pdf文件的预览操作,通过在网上查询,基本都是一下几种常见的预览pdf文件的方法:
实现方案 | 效果 | |
HTML 标签 | iframe 标签 | iOS:只能展示第一页,多页不能展示 Android: 弹出下载弹窗 PC:正常展示 |
embed 标签 | iOS:只能展示第一页, Android: 弹出下载弹窗, PC:显示不出来 | |
object 标签 | iOS:只能展示第一页, Android: 弹出下载弹窗, PC:正常展示 | |
第三方插件 | react-pdf | 在React中使用,各端都能正常展示,且可以根据需要展示PDF的全部页数,设定翻页操作,但是部署到生产环境时存在bug |
vue-pdf | 基于pdfjs封装,在Vue中使用,各端都能正常展示,且可以根据需要展示PDF的全部页数,设定翻页操作,但是部署到生产环境时存在bug | |
PDF.js | 各个项目均可使用,各端均能正常展示 |
标签的方式简单,支持大部分 PC 浏览器(IE 不支持),跨域资源同样可以,但是不支持移动端浏览器,不支持 IE 等低版本浏览器,样式无法自定义。因为本次项目需要在移动端展示,最后使用了pdf.js。
🛠 安装
直接使用官方封装好的 viewer.html 来展示自己的 PDF 文档,该方法比较简单,不用去操作 API;而且功能比较齐全,还可复制 pdf 中的文本。
- 官网地址: https://mozilla.github.io/pdf.js/,下载打包好的 Prebuilt 版本压缩包,下载后解压。
- 把pdf.js放在Vue/React项目根目录的public文件目录下,注意:要是没有这个文件可以放在static里效果都一样
⚙️ 使用配置
页面中,添加iframe标签
可以直接打开本地的pdf(compressed.tracemonkey-pldi-09.pdf),能打开说明pdf正常使用。
注:此处主要说明React中使用方法,Vue中使用场景下文常见问题中可以参考。
// React 项目
return (
<iframe
width="100%"
height="100%"
src={`/pdfjs/web/viewer.html?file=http://localhost:3003/pdfjs/web/compressed.tracemonkey-pldi-09.pdf`} // 打开本地的pdf
// src={`/pdfjs/web/viewer.html?file=${'https://mzy.lhzzs.top/pdfjs/web/compressed.tracemonkey-pldi-09.pdf'}`} // pdfUrl 接口返回的 pdf 文件
></iframe>
)
🚨 常见问题
- 跨域问题
不同域下会报下面这个错误
默认只能查看同域名下的 pdf 文件的,解决方法是 修改 viewer.js 文件的源码,将这个地方注释掉。
- 后端返回文件流
// Vue 项目
<template>
<div>
<div> <button @click="showPdf">点击显示pdf</button> </div>
<iframe v-if="pdfUrl" :src="'/pdfjs/web/viewer.html?file='+ pdfUrl" width="500" height="500"></iframe>
</div>
</template>
<script>
import axios from 'axios';
export default {
data(){
return {
pdfUrl: ""
}
},
methods: {
showPdf(){
axios({
method: "get",
responseType: "blob",
url: "xxx" // 接口路径
}).then(res => {
console.log(res)
let blob = new Blob([res.data], {
type: 'application/pdf;chartset=UTF-8'
})
this.pdfUrl = URL.createObjectURL(blob) // 这个方法会创建一个临时的路径用于访问文件
})
}
}
}
</script>