H5移动端文件预览pdf

H5移动端文件预览pdf本文介绍了使用 pdf js 和 iframe 在 H5 移动端实现 PDF 预览的详细步骤 包括下载 pdf js 放置文件 创建组件和使用方法

大家好,欢迎来到IT知识分享网。

H5移动端文件预览pdf

需求:H5页面嵌入浙政钉,需要文件预览Pdf。

试用了多个插件,踩了很多坑,如果小伙伴有类似填坑经历,并成功解决,感谢留言指点!!!

先讲最终方案,兼容ios,安卓,鸿蒙多种系统手机,移动端和pc端的pdf预览方式 — pdf.js + iframe。

成功案例 pdf.js + iframe

步骤一: 下载 pdf.js , pdfjs 下载地址:https://pan.baidu.com/s/1Meh_hSlwCPvN6wPKzYNfyQ
步骤二: 把下载下来的文件夹,放到项目根目录文件夹下。注意:放在不会被打包压缩的地方,比如 public 或 static 文件夹中,因为后面会用到web 文件中的 view.html 对文件地址进行代理,对于该路径相当于读取静态资源。【注:viewer.html 是pdf 的查看器】
步骤三:新建一个组件,pdfjs.vue
    <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标签也可以展示,应该是内置了预览组件。安卓和鸿蒙就不行,自带浏览器也都是直接跳下载,谷歌浏览器可以预览。

1. 简单的前端处理方式:

url: 文件地址(一般为文件流形式) a 标签, <a :href="url"></a> window.open(url) //新建窗口打开链接预览 window.location.href = 文档地址; //本页面内跳转链接实现预览 iframe 预览:<iframe :src="url" width="100%" height="100vh"></iframe> 以上方式,部分浏览器 或 手机app不能直接打开,会自动回退成下载链接,比如鸿蒙,比如IE 

iframe内嵌常见问题:H5移动端文件预览pdf

2. pdfh5 预览(移动端,h5)

  1. npm install pdfh5 , (会报错,需要其他依赖,不能直接用提示的语句直接npm下载,依旧会报错,npm报错:These dependencies were not found:* canvas in ./node_modules/pdfh5/js/pdf.js* dommatrix/dist/d )
  2. npm install canvas@2.8.0 –ignore-scripts
  3. npm install –save dommatrix
  4. npm install –save web-streams-polyfill
  5. 运行就成功了,亲测可行,但是pc端运行打不开 pdf的文件【vue-pdf 和 pdfh5 不可同时引用】,而且需要点两次才能获取到 pdfh5 这个对象。
  6. 引用 pdfh5 和 css【关于css的引入方式,网上也有踩了很多坑的,下面这种是最佳方式,亲测可行】
 import Pdfh5 from 'pdfh5' import 'pdfh5/css/pdfh5.css' 
  1. 定义容器【id】
     <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 代码举例: H5移动端文件预览pdf

遇到的问题:

  1. 下载依赖,一直报错,无法正常运行,切换 node 和 npm 版本都无果。解决方式:参考上文1234,按次序下载依赖。
  2. pc端运行打不开 pdf 的文件【vue-pdf 和 pdfh5 冲突,不可同时引用,原因未细究】,而且需要点两次才能获取到 pdfh5 这个对象【未解决】
  3. 安卓直接打不开项目,ios可以正常打开且能预览

3.vue-pdf 预览

遇到问题:

  1. vue-pdf 默认只能显示第一页,通过获取总页数遍历解决。
  2. vue-pdf 默认不可手机端两指放大缩小,加 页面放大缩小:
 <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> 
  1. vue-pdf 不太友好,网上有说用 vue-pdf-signature 替代,依旧一样的问题。
  2. 安卓显示不全,鸿蒙白屏,ios可以显示。

网上解决方法:H5移动端文件预览pdf,未解决问题;H5移动端文件预览pdf, 未解决问题imagepng

  1. 引入上面的字体后,安卓直接白屏,iOS依然可以显示。问题依旧。

4.pfile 代理

 let url = 'https://xxxx?key=xxx.pdf' let pfileUrl = 'http://www.pfile.com.cn/api/profile/onlinePreview?url='+encodeURIComponent(url) window.open(pfileUrl); 

遇到问题:

  1. 三种手机系统都打不开,需要手动转跳到浏览器中打开,浏览器都能正常预览。

预测方案:按成功方案预测,iframe + pfile 代理,应该也能实现。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/110188.html

(0)
上一篇 2026-02-02 10:20
下一篇 2026-02-02 10:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信