赞
踩
直接使用iframe嵌套即可
<iframe
class="course-file-iframe"
:src="url"
></iframe>
url就是pdf的线上文档地址
不过我们项目后端并不给返回地址,只返回一个key 然后让前端用这个key去走下载链接来下载这个文件,因此我这里是请求blob二进制流文件,相当于存储到当前浏览器中,然后展示
request.get(apis.url.fileDownload, {
params: {key: fileKey},
// 请求类型为blob格式的二进制文件流
responseType: 'blob',
}).then(res => {
// 获取到的blob类型文件地址 pdf文件对应的MIME类型为'application/pdf'
let type = 'application/pdf';
const blob = new Blob([res], {type});
// 这就是blob类型文件地址 赋值给src即可展示(仅限PC端)
this.url = window.URL.createObjectURL(blob);
}).catch(err => {
console.error('文件获取失败', err);
});
h5端 用iframe 展示pdf的话 会提示 no enabled plugin supports this MIME type
优点:代码少 写的快
缺点:
1. 是以canvas画出来的图片实现的 因此文件中的链接无法点击 (目前我没能解决)
2. 页面能渲染出来,就是控制台报错 没有catch这个属性 (切换版本解决 npm i vue-pdf@4.2.0)
3. 好像说是还有什么付费字体无法展示之类的,我没有遇到,可能需要各位自己遇到的时候自己找了
<div
v-else-if="isLocalFile"
class="course-file-iframe"
>
<pdf
v-for="index in numPages"
:key="index"
:src="pdfUrl"
:page="index"
/>
</div>
import Pdf from 'vue-pdf'; export default { components: { Pdf }, data() { return { numPages: null, pdfUrl: '', } }, methods: { // 请求pdf文件地址的方法,每个人每个项目都不一样, 按自己的来 getUrl() { request.get(api.fileGeneralDownload, { params: {key: fileKey}, responseType: 'blob', }).then(res => { let type = 'application/pdf'; const blob = new Blob([res], {type}); this.videoUrl = window.URL.createObjectURL(blob); this.loadPdf(); }).catch(err => { console.error('文件获取失败', err); }); }, // 上下滚动pdf加载 loadPdf() { this.pdfUrl = Pdf.createLoadingTask(this.videoUrl); this.pdfUrl.promise.then(pdf => { this.$nextTick(() => { this.numPages = pdf.numPages; // pdf总页数 }); }); }, } }
<style lang="less" scoped>
.course-file-iframe {
width: 100%;
height: calc(100% - 45px);
border: none;
overflow: auto;
}
</style>
缺点:
1. 也是以canvas画出来的图片实现的 因此文件中的链接无法点击 (目前我没能解决)
2. 好像也说是还有什么付费字体无法展示之类的,我没有遇到,可能需要各位自己遇到的时候自己找了
<div class="course-file-iframe">
<canvas
v-for="page in pages"
:id="'the-canvas' + page"
:key="page"
></canvas>
</div>
const PDFJS = require('pdfjs-dist'); PDFJS.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.min'); export default { data() { return { pdfDoc: null, pages: 0, pdfUrl: '', src: '', loadding: true, file: true, isDestory: true } }, methods: { // 请求pdf文件地址的方法,每个人每个项目都不一样, 按自己的来 getUrl() { request.get(api.fileGeneralDownload, { params: {key: fileKey}, responseType: 'blob', }).then(res => { let type = 'application/pdf'; const blob = new Blob([res], {type}); this.videoUrl = window.URL.createObjectURL(blob); this.loadFile(this.videoUrl); }).catch(err => { console.error('文件获取失败', err); }); }, renderPage(num) { // getPage 处理每个页面 // 返回单页内容实例(页面引索) pdf.getPage(index) this.pdfDoc.getPage(num).then(page => { // canvas 绘制 PDF let canvas = document.getElementById('the-canvas' + num) let ctx = canvas.getContext('2d'); ctx.mozImageSmoothingEnabled = false; ctx.webkitImageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false; ctx.imageSmoothingEnabled = false; let dpr = window.devicePixelRatio || 1; let bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; let ratio = dpr / bsr; // 这里我一直没有获取到宽高 百度了很多都不对 最后才发现是传参的问题 具体分析看下面的遇到的坑 let viewport = page.getViewport(1); canvas.width = viewport.width * ratio; canvas.height = viewport.height * ratio; canvas.style.width = '100%'; canvas.style.height = 'calc(100% - 50px)'; let renderContext = { canvasContext: ctx, viewport: viewport, transform: [ratio, 0, 0, ratio, 0, 0] }; const that = this; page.render(renderContext).promise.then(() => { if (that.isDestory) { if (that.pages > num) { that.renderPage(num + 1); } } }); }); }, loadFile(url) { PDFJS.getDocument(url).promise.then(pdf => { this.pdfDoc = pdf; this.pages = this.pdfDoc.numPages; this.loadding = false; const that = this; if (that.isDestory) { this.$nextTick(() => { this.renderPage(1); }); } }).catch(err => { console.log('err', err); }); }, } }
pdfjs-dist 我getViewport 一直拿不到宽高 NaN (我的版本号就是2.0.943)
网上说改版本号啥的 都不对
最后我看了看node_module里的源码才发现传参错了
他只有一个形参 scale。 并不是github里 issue里说的 那样有三个参数或者是个对象
高版本的可能需要自己看一下源码,2.0.943 版本的只用穿一个scale就行了 ,像我之前传的是一个对象的话 就会导致 pdf倒置 且拿不到宽高 ,改成一个值之后 就正常展示了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。