vue-pdf 票据字体不显示的问题

本文详细介绍了在Vue.js项目中如何使用vue-pdf-signature组件来实现PDF预览和下载功能。在父组件中传递PDF地址给子组件,通过处理跨域问题和字体缺失问题,成功实现预览并提供了分页和下载功能。遇到的问题主要是PDF预加载时的错误,通过在父组件中添加条件渲染解决了这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PDF 预览与下载

功能描述:
  • 在项目中点击PDF文件然后跳转到一个对话框,展示PDF的内容,然后还有分页和下载的功能。
使用的框架和具体的插件:
  • vue@2.5.16,vue-pdf-signature
使用方法:
  • 描述:

    在父组件中调用封装好的组件pdf(实现预览PDF的功能),然后当点击PDF时给子组件一个后端返回的PDF的地址,就可以实现效果。
  • 问题:

    因为vue-pdf出现的各种问题,这里使用vue-pdf-signature,替换vue-pdf。字体有时候会出现缺失的情况,所以需要找到下面路径(node_modules/vue-pdf/build/pdf-dist/cmaps)下的文件夹复制然后放到static下面。然后再组件里面直接引用,这样在解析的时候就不会出现字体丢失了。

    cmaps

  • 代码如下:

    PdfPriview页面的代码

	
<template>
    <div class="pdfPreview">
        <el-dialog
            :close-on-click-modal="false"
            :visible.sync="dialogVisible"
            :fullscreen="true"
            :before-close="handleClose"
            title="合同预览">
            <div class="agreement_picture">
                <div class="tools">
                    <el-button @click="prePage" class="mr10"> 上一页</el-button>
                    <el-button @click="nextPage" class="mr10"> 下一页</el-button>
                    <span class="page">{{pageNum}}/{{pageTotalNum}} </span>
                    <el-button @click="handleClose" class="mr10 fl-r btn-cancel"> 取消</el-button>
                    <el-button @click="downPDF" class="mr10 dowmBtn"> 下载</el-button>
                </div>
                <pdf ref="pdf"
                     :src="src"
                     :page="pageNum"
                     @page-loaded="pageLoaded($event)"
                     @num-pages="pageTotalNum=$event"
                     @error="pdfError($event)"
                     @link-clicked="page = $event">
                </pdf>
            </div>
        </el-dialog>
    </div>

</template>

<script>
import pdf from 'vue-pdf-signature';

export default {
    name: 'PdfPreview',
    components: {
        pdf
    },
    props:{
        dialog: {
            type: Boolean,
            default: false
        },
        urlPdf:{
            type:String,
            default:''
        }
    },
    data() {
        return {
            dialogVisible:this.dialog,
            url:this.urlPdf,
            src: '', // 预览地址
            pageNum: 1, // 当前页码
            pageTotalNum: 1, // 总页数
        };
    },
    mounted () {
        // 有时PDF文件地址会出现跨域的情况,这里最好处理一下
        var url = this.url
        this.src = pdf.createLoadingTask({
        	url,
            cMapUrl: '../../../../static/cmaps/',
            cMapPacked: true,
        });
    },

    methods: {
        // 上一页函数,
        prePage() {
            var page = this.pageNum
            page = page > 1 ? page - 1 : this.pageTotalNum
            this.pageNum = page
        },
        // 下一页函数
        nextPage() {
            var page = this.pageNum
            page = page < this.pageTotalNum ? page + 1 : 1
            this.pageNum = page
        },
        // 页面加载回调函数,其中e为当前页数
        pageLoaded(e) {
            this.curPageNum = e
        },
        // 抛出错误的回调函数。
        pdfError(error) {
            console.error(error)
        },
        downPDF() { // 下载 pdf
            var url = this.url
            var tempLink = document.createElement("a");
            tempLink.style.display = "none";
            tempLink.href = url;
            tempLink.setAttribute("download", 'XXX.pdf');
            if (typeof tempLink.download === "undefined") {
                tempLink.setAttribute("target", "_blank");
            }
            document.body.appendChild(tempLink);
            tempLink.click();
            document.body.removeChild(tempLink);
            this.handleClose();
        },
        handleClose() {
            // this.$emit('update:dialogVisible', false);
            // this.$emit('updata:url','');
            this.$emit('update',false);
        }
    }
};


</script>

<style scoped>
.wrap{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    bottom: 0;
}
</style>


父组件的代码

<template>
    <div>
     <el-dialog :title="dialogTitle" :visible.sync="editDialog" width="770px"
                   :close-on-click-modal="false" :close-on-press-escape="false" @close="dialogClose">
            <div class="dialog-div">
                <el-form label-width="110px">
                    <div class="inline-div">
                        <el-form-item label="企业名称:">
                            <div class="handle-input">{{detailForm.companyName}}</div>
                        </el-form-item>
                        <el-form-item label="位置:">
                            <div class="handle-input">{{detailForm.location}}</div>
                        </el-form-item>
                    </div>
                    <div class="inline-div">
                        <el-form-item label="联系人:">
                            <div class="handle-input">{{detailForm.contact}}</div>
                        </el-form-item>
                        <el-form-item label="联系方式:">
                            <div class="handle-input">{{detailForm.contactInformation}}</div>
                        </el-form-item>
                    </div>
                    <el-form-item label="备注:">
                        <div class="handle-row-input">{{detailForm.remark}}</div>
                    </el-form-item>
                    <el-form-item label="附件:">
                        <div style="display: flex;flex-direction: column;">
                            <el-upload ref="uploadImg"
                                       action=""
                                       :disabled="true"
                                       accept=".pdf,.jpg,.jpeg,.png,.PNG,.bmp,.JPG,.JPEG"
                                       :on-preview="handlePreview"
                                       :file-list="fileList">
                            </el-upload>
                        </div>
                    </el-form-item>
                </el-form>
            </div>
<!--            <div class="btn-div">-->
<!--                <el-button type="primary" @click="cancleSubmit">关闭</el-button>-->
<!--            </div>-->
        </el-dialog>
        <pdf-preview :dialog='pdfBoo' :urlPdf='pdfUrl' v-if="pdfBoo" @update="closeUpdate"></pdf-preview>
    </div>
</template>
<script>
	export default {
		data(){
	return {
	pdfBoo:false,
    pdfUrl:''
}
},
methods: {
            closeUpdate(val){
              this.pdfBoo = val;
            },
            handlePreview(file) {
                if (file.name.endsWith(".pdf")) {
                    this.pdfBoo= true;
                    this.pdfUrl = file.response.data;
                } else {
                    this.dialogImageUrl = file.response.data;
                    this.dialogVisible = true;
                }
            },
}
</script>
遇到的问题:
  • 主要在父组件一加载就会报错,然后解决一直出问题,最后在父组件中给子组件加上判断 v-if 当需要的时候给她true让在在渲染,问题解决。
效果演示:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值