vue使用iframe引入pdf文件

在网上找的很多文章都显示需要添加pdf.js来引入vue文件,但是还有一个很简单的办法就是使用iframe框架引入pdf

效果

在这里插入图片描述
使用iframe框架引入的话代码会变得非常简洁

<template>
<div class="app">
          <div class="agreement_picture">
            <div class="pdf">
              <iframe :src="src" frameborder="0" style="width: 50vw; height:50vh"></iframe>
            </div>
          </div>
          </div>
</template>

<script>
    export default {
        name: 'page-one',
         data () {
    return {
      src: 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf', //pdf地址,这里我用的是我本地的文件,你也可以使用后台的文件
      dialogVisible: true
    }
  }
   }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

vue引入pdf.js来引入pdf文件

首先下载文件放在static里面并且命名为pdf
在这里插入图片描述
之后可以自己写组件,我是在pages里面添加了pdf文件夹,再添加两个文件,需要注意路劲,其他也没什么需要更改的地方
在这里插入图片描述
pdf.vue

<style>
    .contract-modal {
        position: absolute;
        right: 15%;
        width: 1000px;
        height: 500px;
        overflow: scroll;
        background: rgba(139, 148, 171, 0.7);
        padding: 20px 0 0;
        z-index: 900;
    }
    .contract-modal .contract-detail {
        margin: 0 auto;
        max-width: 96%;
        height: auto;
    }
    .contract-btns{
        height: 50px;
        background-color:  #fff;
        text-align: center;
        padding-bottom:44px;
        padding-top:10px;
    }
    #mycanvas {
        min-height: 50vh;
        background: #fff;
    }
    canvas{
        margin: 0 auto;
        display: block;
        border-bottom:2px solid #aaa;
    }
    .close-btn{
        position: absolute;
        right: 15%;
        width: 26px;
        height: 26px;
        z-index: 999;
        background-color: #666;
        border-radius: 50%;
        cursor: pointer;
    }
</style>

<template>
    <div v-if='visible'>
        <div class="contract-modal">
            <div class="contract-detail"
                 id="contractDetail">
                <div id="mycanvas" ref="mycanvas"></div>
                <!--合同内容-->
                <div class="contract-btns contract-operate" v-if="showBtns">
                    <button @click="commit" >合同内容有误</button>
                    <button @click="confirm">我已确认合同内容</button>
                </div>
            </div>
        </div>
        <div class="close-btn" @click="closeModal">
            <span style="font-weight: bold; margin-top: 2px;display: inline-block;">X</span>
        </div>
    </div>
</template>

<script>
// ../../../static/pdf/build/pdf
    import pdf from '../../../static/pdf/build/pdf'
    export default {
        name: 'md-contract',
        props: {
            visible: Boolean,
            showBtns: {
                type: Boolean,
                default: false
            }
        },
        data () {
            return {}
        },
        watch: {
            visible (val) {
                if (val) {
                    this.contractError = false
                    this.$nextTick(()=>{
                        this.getPdf()
                    })
                }
            }
        },
        methods: {
            handleError (status) { //  合同有误
                this.contractError = status
            },
            closeModal () {
                this.$emit('handleModal')
            },
            confirm () { //  我已确认合同内容
                alert('success')
            },
            commit () { //  提交错误消息
                alert('error')
            },
            getPage (pdf,pageNumber,container,numPages) { //获取pdf
                let _this = this
                pdf.getPage(pageNumber).then((page) => {
                    let scale = (container.offsetWidth/page.view[2])
                    let viewport = page.getViewport(scale)
                    let canvas = document.createElement("canvas")
                    canvas.width= viewport.width
                    canvas.height= viewport.height
                    container.appendChild(canvas)
                    let ctx = canvas.getContext('2d');
                    var renderContext = {
                        canvasContext: ctx,
                        transform: [1, 0, 0, 1, 0, 0],
                        viewport: viewport,
                        intent: 'print'
                    };
                    page.render(renderContext).then(() => {
                        pageNumber +=1
                        if(pageNumber<=numPages) {
                            _this.getPage(pdf,pageNumber,container,numPages)
                        }
                    })
                })
            },
            getPdf () {
                // 此中方式接受流形式返回
                this.$refs.mycanvas.scrollTop =0
//                let accessToken = cache.get('TOKEN').Authorization
//                let url = `${config.baseUrls}/api/fund/v1/contractReports/previewContractContent?access_token=${accessToken}&id=${contractData.id}&contractUrl=${contractData.contractUrl}&.pdf`
                let url = 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf'
				let pdfjsLib = pdf
				// /static/pdf/build/pdf.worker.js
                pdfjsLib.PDFJS.workerSrc = '../../../static/pdf/build/pdf.worker.js'
                let loadingTask = pdfjsLib.getDocument(url)
                loadingTask.promise.then((pdf) =>{
                    let numPages = pdf.numPages
                    let container = document.getElementById('mycanvas')
                    let pageNumber = 1
                    this.getPage(pdf,pageNumber,container,numPages)
                }, function (reason) {
                    alert(reason)
                });
            }
        },
        created () {
        }
    }
</script>

main.vue

<template>
<div class="innerPdf">
    <div class="page-one">
        <p>pdf.js demo</p>
        <!--本地-->
        <div style="margin-top: 10px">
            <p>本地</p>
            <button @click="check">点击</button>
            <button @click="checkLocal">点击一下</button>
        </div>
        <!--服务器-->
        <div style="margin-top: 30px">
            <p>服务器</p>
            <button @click="checkError">查看错误</button>
            <button @click="checkNormal">查看有效</button>
            <button @click="checkSuccess">查看服务器跨域返回流</button>
        </div>
        <!--上传文件-->
        <div style="margin-top: 40px">
            <input type="file" name="myfile" id="myfile" @change="preview($event)"/>
            <!--<button @click="changeLocal">点击预览本地pdf</button>-->
            <iframe v-if="showPdf" id='previewPdf' :src="src" height="560"
                    width="100%">
            </iframe>
        </div>
        <!--canvas-->
        <div style="margin-top: 30px;color: #70DB55">
            <span style="font-weight: 600" @click="checkContract">点我试试</span>
        </div>
        <md-contract :visible="contractVisable"
                     :showBtns="true"
                     @handleModal="close">
        </md-contract>
    </div>
    </div>
</template>

<script>
    import mdContract from './Pdf'

    export default {
        name: 'page-one',
        components: {
            mdContract
        },
        data() {
            return {
                src: 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf',
                showPdf: false,
                contractVisable: false,
            }
        },
        methods: {
            check() {
                window.open('https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003237411.pdf')
            },
            checkLocal() {
//          let url = '/static/pdf/web/demo.pdf'
                let url = 'demo.pdf'
                window.open('../../../static/pdf/web/viewer.html?file=' + url)
            },
            checkError() {
                let url = 'http://somedomain/doc/manuals/R-intro.pdf' // 报错跨域
                window.open('../../../static/pdf/web/viewer.html?file=' + url)
            },
            checkNormal() {
                let url = 'http://image.cache.timepack.cn/nodejs.pdf'  // 有效 服务器配置跨域处理
                window.open('../../../static/pdf/web/viewer.html?file=' + url)
            },
            checkSuccess() {
                // 后台返回流的形式,也是我本人项目的使用
                let url = 'https://dluat.hscf.com/api/esm/v1/contractTemplates/load/c08def54aa40412b8b511406fc0271d2/0?access_token=ea19dc0de8801b389ed5099a2297161d&name=cehsi.pdf'
                // 当然上面的是可以的,但是此access_token 是有时效性的,只是放在这边当作个例子,至于最后我为什么加了个测试.pdf 是可以在浏览器标签叶上显示
                window.open('../../../static/pdf/web/viewer.html?file=' + encodeURIComponent(url))
            },
            // 这是打开本地文件进行预览
            preview(event) {
                let files = document.getElementById('myfile').files[0]
                if (files.type !== 'application/pdf') {
                    alert('只能上传一份pdf文件哦~')
                    return
                }
                this.showPdf = true
                this.fileUrl = this.getObjectURL(files)

            },
            getObjectURL(file) {
                let url = null;
                if (window.createObjectURL != undefined) { // basic
                    url = window.createObjectURL(file);
                } else if (window.webkitURL != undefined) { // webkit or chrome
                    url = window.webkitURL.createObjectURL(file);
                } else if (window.URL != undefined) { // mozilla(firefox)
                    url = window.URL.createObjectURL(file);
                }
                return url;
            },
            checkContract() {
                this.contractVisable = !this.contractVisable
            },
            close () {
                this.contractVisable = false
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .page-one button {
        margin-left: 10px;
    }
    .innerPdf{
        height: 80vh;
        width: 60vw;
    }
</style>

效果

在这里插入图片描述
使用这个的话就功能比较多,还能上传之类的

Logo

前往低代码交流专区

更多推荐