赞
踩
需求:H5页面嵌入浙政钉,需要文件预览Pdf。
试用了多个插件,踩了很多坑,如果小伙伴有类似填坑经历,并成功解决,感谢留言指点!!!
先讲最终方案,兼容ios,安卓,鸿蒙多种系统手机,移动端和pc端的pdf预览方式 — pdf.js + iframe。
提取码:pdfj
或官网地址下载: https://mozilla.github.io/pdf.js/
<template> <div> <iframe width="100%" style="height: 100vh;border:none;" :src="pdfSrc"></iframe> <van-button class="close" @click="closePdf"> 关闭 </van-button> </div> </template> <script> export default { name: 'pdf', props: { pdfurl: { type: String, }, }, data(){ return { pdfSrc: '' } }, mounted() { console.log('pdfurl', this.pdfurl) // 此处,我是把文件夹放到public中,pdf文件夹就在打包完的根目录下,pdf/web/viewer.html this.pdfSrc = `${window.location.origin + window.location.pathname}pdf/web/viewer.html?file=${encodeURIComponent(this.pdfurl)}` console.log('pdfSrc', this.pdfSrc) }, methods: { closePdf() { this.$emit('closePdf') } } } </script> <style scoped> .close { position: absolute; left: 0; bottom: 0; height: 80px; width: 100%; line-height: 40px; text-align: center; color:#367CFD; font-size: 36px; background: #fff; } </style>
<template> <div> <!-- ... --> <van-popup v-model="previewFile" position="bottom"> <pdf :pdfurl="preFileUrl" @closePdf="closePdfFn"></pdf> </van-popup> </div> </template> <script> // 引入pdfjs组件 import pdf from '../../components/pdfjs.vue' export default { components: { pdf }, data() { return { previewFile: false, preFileUrl: '', // 'https://xxxx?key=xxx.pdf' } }, mounted() { }, methods: { oprenPdfFn() { this.previewFile = true }, closePdfFn() { this.previewFile = false } } } </script>
经过下面几个插件的试用,发现ios都能展示,而且用a标签也可以展示,应该是内置了预览组件。安卓和鸿蒙就不行,自带浏览器也都是直接跳下载,谷歌浏览器可以预览。
url: 文件地址(一般为文件流形式)
a 标签, <a :href="url"></a>
window.open(url) //新建窗口打开链接预览
window.location.href = 文档地址; //本页面内跳转链接实现预览
iframe 预览:<iframe :src="url" width="100%" height="100vh"></iframe>
以上方式,部分浏览器 或 手机app不能直接打开,会自动回退成下载链接,比如鸿蒙,比如IE
iframe内嵌常见问题:https://blog.csdn.net/qq_35408366/article/details/128447408
npm install pdfh5 , (会报错,需要其他依赖,不能直接用提示的语句直接npm下载,依旧会报错,npm报错:These dependencies were not found:* canvas in ./node_modules/pdfh5/js/pdf.js* dommatrix/dist/d )
npm install canvas@2.8.0 --ignore-scripts
npm install --save dommatrix
npm install --save web-streams-polyfill
运行就成功了,亲测可行,但是pc端运行打不开 pdf的文件【vue-pdf 和 pdfh5 不可同时引用】,而且需要点两次才能获取到 pdfh5 这个对象。
引用 pdfh5 和 css【关于css的引入方式,网上也有踩了很多坑的,下面这种是最佳方式,亲测可行】
import Pdfh5 from 'pdfh5'
import 'pdfh5/css/pdfh5.css'
<div id="pdf-content" style="height: 100%;width: 100%"></div> openPdf(url) { // pdfh5实例化时传两个参数:selector选择器,options配置项参数,会返回一个pdfh5实例对象, // 可以用来操作pdf,监听相关事件 this.pdfh5 = new Pdfh5('#pdf-content', { pdfurl: url || this.preFileUrl, lazy: false, // 是否懒加载,默认false renderType: 'canvas', // canvas、svg,默认canvas maxZoom: 3, // 手势缩放最大倍数,默认3 scrollEnable: true, // 是否允许pdf滚动,默认true zoomEnable: true,// 是否允许pdf手势缩放,默认true limit: 0, // 限制pdf加载最大页数,默认0不限制 goto: 1, // 设置每一页pdf上的水印 // logo: { src: require("@/assets/images/icon27.png"), x: 20, y: 70, width: 60, height: 60 }, }); console.log('pdfh5', this.pdfh5) // 监听pdf准备开始渲染,此时可以拿到pdf总页数 this.pdfh5.on('ready', function(totalNum) { console.log('总页数:' + totalNum); }); // 监听pdf加载完成事件,加载失败、渲染成功都会触发 this.pdfh5.on('complete', (status, msg, time) => { console.log('状态:' + status + ',信息:' + msg + ',耗时:' + time + '毫秒'); }) },
vue2 和 vue3 代码举例: https://blog.csdn.net/u014212540/article/details/129408653
遇到的问题:
遇到问题:
<template> <div class="pdf_wrap"> <div class="pdf_btn"> <van-button @click="scaleD()">放大</van-button> <van-button @click="scaleX()">缩小</van-button> <van-button @click="clock()">顺时针</van-button> <van-button @click="counterClock()">逆时针</van-button> </div> <div class="pdf_list"> <!-- src:pdf地址,page: 当前显示页 --> <pdf ref="pdf" v-for="i in numPages" :key="i" :src="src" :page="i" :rotate="pageRotate" style="width: 100%"></pdf> </div> <van-button class="close" @click="closePdf"> 关闭 </van-button> </div> </template> <script> import pdf from 'vue-pdf'; import CMapReaderFactory from 'vue-pdf/src/CMapReaderFactory.js' // import pdf from 'vue-pdf/src/vuePdfNoSssNoWorker.vue'; export default { components: { pdf, }, props: { pdfurl: { type: String, }, }, data() { return { src: '', numPages: undefined, scale: 100, pageRotate: 0 } }, mounted() { console.log('pdf', pdf) this.loadPdf(this.pdfurl) }, methods: { loadPdf(url) { console.log(url, 'url') this.src = pdf.createLoadingTask({ url, // pdf内容文字丢失 cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/',//引入pdf.js字体 cMapPacked: true, // 动态文字不展示问题 CMapReaderFactory }) console.log(this.src, 'src') this.src.promise.then(pdf => { console.log(pdf, 'pdf') this.numPages = pdf.numPages // 这里拿到当前pdf总页数 }).catch(err => { console.log('err', err) }) console.log(this.src, 'src11111') }, closePdf() { this.$emit('closePdf') }, //放大 scaleD() { this.scale += 20; console.log('refs.pdf', this.$refs.pdf) if (this.$refs.pdf && this.$refs.pdf.length > 0) { this.$refs.pdf.forEach(pdfPage=>{ pdfPage.$el.style.width = parseInt(this.scale) + '%'; }) } else { this.$refs.pdf.$el.style.width = parseInt(this.scale) + '%'; } }, //缩小 scaleX() { if (this.scale === 100) { return; } this.scale += -20; if (this.$refs.pdf && this.$refs.pdf.length > 0) { this.$refs.pdf.forEach(pdfPage=>{ pdfPage.$el.style.width = parseInt(this.scale) + '%'; }) } else { this.$refs.pdf.$el.style.width = parseInt(this.scale) + '%'; } }, // 顺时针 clock() { this.pageRotate += 90; }, // 逆时针 counterClock() { this.pageRotate -= 90; } } } </script> <style scoped> .pdf_btn button { color:#367CFD; } .pdf_wrap { background: #fff; height: 100vh; position: relative; } .pdf_list { height: 100vh; overflow: scroll; } .close { position: absolute; left: 0; bottom: 0; height: 60px; width: 100%; line-height: 40px; text-align: center; color:#367CFD; font-size:30px; background: #fff; } </style>
vue-pdf 不太友好,网上有说用 vue-pdf-signature 替代,依旧一样的问题。
安卓显示不全,鸿蒙白屏,ios可以显示。
网上解决方法:https://blog.csdn.net/PokoMobula/article/details/103164795,未解决问题;https://blog.csdn.net/weixin_44612172/article/details/127783210, 未解决问题
let url = 'https://xxxx?key=xxx.pdf'
let pfileUrl = 'http://www.pfile.com.cn/api/profile/onlinePreview?url='+encodeURIComponent(url)
window.open(pfileUrl);
遇到问题:
预测方案:按成功方案预测,iframe + pfile 代理,应该也能实现。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。