当前位置:   article > 正文

vue实现预览pdf_vue预览pdf

vue预览pdf

PC端

直接使用iframe嵌套即可

<iframe
    class="course-file-iframe"
    :src="url"
></iframe>
  • 1
  • 2
  • 3
  • 4

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);
 });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

H5端

h5端 用iframe 展示pdf的话 会提示 no enabled plugin supports this MIME type在这里插入图片描述

因此 h5端只能引入第三方插件实现

方案一:vue-pdf

优点:代码少 写的快
缺点:
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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
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总页数
                });
            });
        },
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
<style lang="less" scoped>
.course-file-iframe {
    width: 100%;
    height: calc(100% - 45px);
    border: none;
    overflow: auto;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

方案二:pdfjs-dist

缺点:
1. 也是以canvas画出来的图片实现的 因此文件中的链接无法点击 (目前我没能解决)
2. 好像也说是还有什么付费字体无法展示之类的,我没有遇到,可能需要各位自己遇到的时候自己找了

<div class="course-file-iframe">
    <canvas
        v-for="page in pages"
        :id="'the-canvas' + page"
        :key="page"
    ></canvas>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
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);
            });
        },
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

遇到的坑

pdfjs-dist 我getViewport 一直拿不到宽高 NaN (我的版本号就是2.0.943)

网上说改版本号啥的 都不对
最后我看了看node_module里的源码才发现传参错了

在这里插入图片描述他只有一个形参 scale。 并不是github里 issue里说的 那样有三个参数或者是个对象
在这里插入图片描述
高版本的可能需要自己看一下源码,2.0.943 版本的只用穿一个scale就行了 ,像我之前传的是一个对象的话 就会导致 pdf倒置 且拿不到宽高 ,改成一个值之后 就正常展示了
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/172663
推荐阅读
相关标签
  

闽ICP备14008679号