项目场景:后台接口请求数据,返回PDF文档的链接(即pdf文件在服务器上的存放路径),在vue3页面可预览和打印该PDF。
在之前的Vue2项目中,预览并打印PDF用的是vue-pdf这个插件,但在vue3中是不支持的,只能换个插件了,于是经过测试,也踩了一些坑,总结了以下两种方法:
pnpm install vue-pdf-embedpnpm install pdfjs-dist2.0.943
当时我在安装pdfjs-dist时遇到了问题 ,我没有指定版本号,控制台报错,翻了一些文章,有博主建议安装2.0.943版本,于是又重新输入命令,安装了这个版本,就一切正常了
// 引入插件import VuePdfEmbed from 'vue-pdf-embed'import * as pdfjsLib from 'pdfjs-dist'//定义const state = reactive({ source: '', // pdf文件地址 pageNum: 0, // 当前页面 scale: 1, // 缩放比例 numPages: 0 // 总页数})const scale = computed(() => `transform:scale(${state.scale})`)
<div> // 操作按钮 <div class="page-tool"> <div class="page-tool-item" @click="lastPage">上一页</div> <div class="page-tool-item" @click="nextPage">下一页</div> <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div> <div class="page-tool-item" @click="pageZoomOut">放大</div> <div class="page-tool-item" @click="pageZoomIn">缩小</div> </div> //pdf预览 <vue-pdf-embed ref='pdf' :source="state.source" :style="scale" :page="state.pageNum" class="vue-pdf-embed" /> </div>
<script setup> onMounted(()=>{ // 首先请求接口,获取pdf存放地址,赋值给pdfUrl(此处省略请求代码) // 拿到pdf路径后,执行下面的函数 getPdfUrl(pdfUrl) }) function getPdfUrl(data){ state.source = data pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js' const loadingTask = pdfjsLib.getDocument(data) loadingTask.promise.then(pdf => { state.numPages = pdf.numPages }) } // 上一页 function lastPage() { if (state.pageNum > 1) { state.pageNum -= 1 } } // 下一页 function nextPage() { if (state.pageNum < state.numPages) { state.pageNum += 1 } } // 放大 function pageZoomOut() { if (state.scale < 2) { state.scale += 0.1 } } // 缩小 function pageZoomIn() { if (state.scale > 1) { state.scale -= 0.1 } }</script>
为了好看一些,我给操作按钮写了样式
<style lang="scss" scoped> .page-tool { display: flex; position: absolute; top: 5px; left: 50%; z-index: 100; transform: translateX(-50%); align-items: center; background: rgb(66 66 66); color: white; border-radius: 19px; cursor: pointer; justify-content: center; font-size: 15px; } .page-tool-item { padding: 4px 10px; cursor: pointer; }</style>
最终的实现效果:
const { proxy } = getCurrentInstance() <div @click='print'>打印</div><script setup> function print(){ proxy.$refs['pdf'].print() }</script>
说明:pdf.js可以打印canvas数据,所以选择这个插件
pnpm install pdfjs-dist
安装之后,在项目的node_modules文件夹里,找到pdfjs-dist ->build->pdf.worker.js文件,拷贝出来放到public根目录下,接着找到pdfjs-dist ->cmaps文件夹,拷贝一下放到public->static文件夹里,如下图所示:
具体我是参考的这篇博文:前端使用print.js实现打印_printjs_@我不认识你的博客-CSDN博客
// 打印按钮<div @click="print">打印</div> //pdf预览显示<div> <div id="printDom" ref="printDom"> <div v-for="item in state.numPages" :key="item"> <canvas :id="`pdfCanvas-${item}`" :ref="`pdfCanvas-${item}`" /> </div> </div></div> <script setup> import * as pdfjsLib from 'pdfjs-dist' //引入pdfjs-dist import Print from '@/assets/js/print' //引入print.js const { proxy } = getCurrentInstance() const state = reactive({ pageNum: 0, // 当前页面 scale: 1, // 缩放比例 numPages: 0, // 总页数 pdfCtx: null // pdf对象 }) onMounted(()=>{ // 请求服务接口,获取pdf存放地址,赋值给pdfUrl变量(此处省略请求代码) // pdfUrl获取到之后,接着执行以下代码 pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js' const loadingTask = pdfjsLib.getDocument({ url: pdfUrl, //这里的pdfUrl即pdf的链接地址 cMapUrl: '../../../../static/cmaps/', cMapPacked: true }) loadingTask.promise.then(pdf => { // console.log('页数', pdf.numPages) state.numPages = pdf.numPages state.pdfCtx = pdf nextTick(() => { renderPdf() }) }) }) const renderPdf = (num = 1) => { state.pdfCtx.getPage(num).then(page => { const canvas = document.getElementById(`pdfCanvas-${num}`) const ctx = canvas.getContext('2d') const viewport = page.getViewport(1.6) canvas.height = viewport.height canvas.width = viewport.width page.render({ canvasContext: ctx, viewport: viewport }) if (num < state.numPages) { renderPdf(num + 1) } }) } //打印 function print(){ Print(proxy.$refs['printDom']) }</script>
原网址: 访问
创建于: 2023-08-18 14:57:40
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论