vue3实现pdf预览
- 游戏开发
- 2025-08-12 11:27:03

需要下载pdfjs-dist
<template> <a-modal class="fill-modal" v-model:open="state.visible" :title="state.modalTitle" width="50%" @cancel="handleCancel"> <div class="preview-btns-posi"> <a-button type="primary" @click="exportBtn" :loading="state.downLoading">下载</a-button> <a-button @click="handleCancel" type="primary">返回</a-button> </div> <div class="interviewVideo_main" id="videoContainer"> <!--此处根据pdf的页数动态生成相应数量的canvas画布--> <canvas v-show="state.show" v-for="pageIndex in pdfPages" :id="`pdf-canvas-` + pageIndex" :key="pageIndex" style="display: block;width:100%;" class="canvas"></canvas> </div> <template #footer></template> </a-modal> </template> <script lang="ts" setup> import { ref, reactive, nextTick } from "vue"; import * as pdfjsLib from "pdfjs-dist/build/pdf.js"; import * as workerSrc from 'pdfjs-dist/build/pdf.worker.min.js' import { message } from "ant-design-vue"; import { downloadBlobAsync } from "@/lib/tool"; let pdfPages = ref(0); // pdf文件的页数 let pdfDoc: any = reactive({}) let pdfScale = ref(1.0); // 缩放比例 const state: any = reactive({ visible: false, downLoading: false, modalTitle: '预览文件', show: false }) const props = defineProps<{ file: { previewPath: string, originalFileName: string, path: string, } }>() //调用loadFile方法 //获取pdf文档流与pdf文件的页数 const loadFile = async (url: string) => { try { pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc; const loadingTask = pdfjsLib.getDocument(url); loadingTask.promise.then((pdf: any) => { state.show = true; pdfDoc = pdf; pdfPages.value = pdf.numPages; nextTick(() => { renderPage(1); }); }).catch((err: any) => { console.error(err); pdfDoc = null state.show = false }); } catch (error) { console.error(error) } }; //渲染pdf文件 const renderPage = (num: number) => { pdfDoc?.getPage(num).then((page: any) => { const canvasId = "pdf-canvas-" + num; const canvas = <any>document.getElementById(canvasId); const ctx = canvas.getContext("2d"); const dpr = window.devicePixelRatio || 1; const bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; const ratio = dpr / bsr; const viewport = page.getViewport({ scale: pdfScale.value }); canvas.width = viewport.width * ratio; canvas.height = viewport.height * ratio; canvas.style.width = viewport.width + "px"; canvas.style.height = viewport.height + "px"; ctx.setTransform(ratio, 0, 0, ratio, 0, 0); const renderContext = { canvasContext: ctx, viewport: viewport, }; page.render(renderContext); if (num < pdfPages.value) { renderPage(num + 1); } }); }; function openModal() { state.visible = true; nextTick(() => { loadFile(props.file.previewPath); }) } function handleCancel() { state.visible = false; } async function exportBtn() { try { state.downLoading = true if (!props.file?.path) { message.warning(`无地址,可供下载`) return; } await downloadBlobAsync(props.file?.path, props.file?.originalFileName, true) } catch (error: any) { message.error(error) } finally { state.downLoading = false } } defineExpose({ openModal }) </script> <style> #videoContainer { height: 500px; width: 100%; overflow: auto; .canvas { width: 80% !important; margin: 0 auto; } } .preview-btns-posi { position: absolute; top: 10px; right: 50px; } </style> /**下载文件 */ export const downloadBlobAsync = (blob: Blob | string, fileName: string, isUrl = false) => { return new Promise<void>((resolve, reject) => { try { //对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性 //IE10以上支持blob但是依然不支持download if ('download' in document.createElement('a')) { //支持a标签download的浏览器 const link = document.createElement('a'); //创建a标签 link.download = fileName; //a标签添加属性 link.style.display = 'none'; link.href = isUrl ? blob as string : URL.createObjectURL(blob as Blob); document.body.appendChild(link); link.click(); //执行下载 URL.revokeObjectURL(link.href); //释放url document.body.removeChild(link); //释放标签 } else { //其他浏览器 (navigator as any)?.msSaveBlob(blob, fileName); } } catch (error) { console.log(error) reject(error); } finally { setTimeout(() => { resolve() }, 500) } }) };vue3实现pdf预览由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“vue3实现pdf预览”