H5移动端文件预览pdf

news2024/11/18 8:39:23

H5移动端文件预览pdf

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

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

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

成功案例 pdf.js + iframe

步骤一: 下载 pdf.js , pdfjs 下载地址:https://pan.baidu.com/s/1Meh_hSlwCPvN6wPKzYNfyQ

提取码:pdfj

步骤二: 把下载下来的文件夹,放到项目中。注意:放在不会被打包压缩的地方,比如 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内嵌常见问题:https://blog.csdn.net/qq_35408366/article/details/128447408

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 代码举例: https://blog.csdn.net/u014212540/article/details/129408653

遇到的问题:

  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可以显示。

网上解决方法:https://blog.csdn.net/PokoMobula/article/details/103164795,未解决问题;https://blog.csdn.net/weixin_44612172/article/details/127783210, 未解决问题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 代理,应该也能实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1462369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++从入门到精通 第十三章(认识STL)

写在前面&#xff1a; 本系列专栏主要介绍C的相关知识&#xff0c;思路以下面的参考链接教程为主&#xff0c;大部分笔记也出自该教程&#xff0c;笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外&#xff0c;笔者还参考了其它的一些C教材&#xff08;比…

做过的卷子如何转换成空白卷子?3种还原方法分享

做过的卷子如何转换成空白卷子&#xff1f;在日常学习中&#xff0c;将做过的卷子转换成空白卷子具有极大的实用性。通过使用扫描工具&#xff0c;可以迅速将已完成的卷子恢复成空白状态&#xff0c;为后续的复习或练习提供便利。这种转换不仅省去了重新寻找或制作新卷子的麻烦…

Javascript中var和let之间的区别

文章目录 一.变量提升(声)二.let和var的区别 区别&#xff1a; 1、var有变量提升&#xff0c;而let没有&#xff1b; 2、let不允许在相同的作用域下重复声明&#xff0c;而var允许&#xff1b; 3、let没有暂时性死区问题&#xff1b; 4、let创建的全局变量没有给window设置对应…

腾讯云宝塔Linux安装Mysql5.7

一、下载官方mysql包 wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm二、安装mysql包 rpm -ivh mysql-community-release-el7-5.noarch.rpm三、安装mysql yum install mysql-community-server -y四、启动数据库 systemctl start mysqld.service…

2023 re:Invent 用 PartyRock 10 分钟构建你的 AI 应用

前言 一年一度的亚马逊云科技的 re:Invent 可谓是全球云计算、科技圈的狂欢&#xff0c;每次都能带来一些最前沿的方向标&#xff0c;这次也不例外。在看完一些 keynote 和介绍之后&#xff0c;我也去亲自体验了一些最近发布的内容。其中让我感受最深刻的无疑是 PartyRock 了。…

无人机的视频图传技术

在操控无人机时&#xff0c;视频图传技术显得尤为关键。通过这项技术&#xff0c;无人机的摄像头所捕捉的画面能实时回传至遥控器&#xff0c;使操作者全面掌握无人机的拍摄情况。同时&#xff0c;无人机图传技术也是衡量无人机性能的重要标准&#xff0c;它关乎飞行距离与时间…

Python format函数

在Python编程中&#xff0c;format()函数是一个非常重要且常用的字符串格式化方法&#xff0c;用于将各种数据类型插入到字符串中&#xff0c;并指定其格式。这个函数可以动态地生成各种格式的字符串&#xff0c;包括文本、数字、日期等。本文将深入探讨Python中的format()函数…

openAI:人工智能领域的领军者

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、openAI创始人二、openAI的发展历程三、openAI的股权架构四、Sam Altman的离开 一、openAI创始人 openAI由埃隆马斯克、Sam Altman、Greg Brockman三位创始人于…

【智能车入门:pcb版】(蓝牙遥控、超声波避障、红外循迹)

实现最简单的蓝牙遥控、超声波避障、红外循迹&#xff09; 总览项目获取 本篇是对 上一篇博客的改进&#xff0c;上一篇博客使用面包板&#xff0c;看起来很乱&#xff0c;春节结束之后嘉立创免费打板恢复&#xff0c;板子到了之后进行焊接测试&#xff0c;相较于使用面包板&a…

数据结构-拓扑排序

介绍 介绍拓扑排序之前&#xff0c;首先要先引入一个名词&#xff0c;即AOV网&#xff1a; 如果有一项工程&#xff0c;它的完成需要多个活动组成&#xff0c;将活动看做结点&#xff0c;活动间的联系看做图的边&#xff0c;那么这样一个表示工程活动的有向图&#xff08;活动…

【软考高项】【教材知识梳理】- 15 - 第15章 - 项目风险管理

一、基本问题 1&#xff1a;按照可预测性&#xff0c;风险分哪三类&#xff1f; &#xff08;1&#xff09;已知风险&#xff1a;如项目目标不明确&#xff0c; 过分乐观的进度计划&#xff0c; 设计或施工变更和材料价格波动等。&#xff08;2&#xff09;可预测风险&#xff…

电脑黑屏什么都不显示怎么办 电脑开机黑屏不显示任何东西的4种解决办法

相信有很多网友都有经历电脑开机黑屏不显示任何东西&#xff0c;找了很多方法都没处理好&#xff0c;其实关于这个的问题&#xff0c;首先还是要了解清楚开机黑屏的原因&#xff0c;才能够对症下药&#xff0c;下面大家可以跟小编一起来看看怎么解决吧 电脑开机黑屏不显示任何…

【设计模式】使用适配器模式做补偿设计

文章目录 1.概述2.两种适配器模式2.1.类适配器2.2.对象适配器 3.总结 1.概述 适配器模式是一种结构型设计模式&#xff0c;它提供了一个中间层&#xff0c;通过这个中间层&#xff0c;客户端可以使用统一的接口与具有不同接口的类进行交互&#xff0c;也就是说&#xff0c;将一…

Chromium的下载地址

Chromium的下载地址&#xff1a; Download Chromiumhttps://www.chromium.org/getting-involved/download-chromium/ https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefixWin_x64/https://commondatastorage.googleapis.com/chromium-br…

[设计模式Java实现附plantuml源码~行为型]协调多个对象之间的交互——中介者模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

linux CentOs 安装docker 推荐生产环境使用

目录 1. 在CentOs上安装docker所需的系统环境 2. 卸载旧版本 2.1 查看是否已安装docker 2.2 卸载已安装的docker 3. 安装方式 3.1 使用rpm存储库安装(推荐使用该方法) 3.2 从包中安装 4. 开始docker 1. 在CentOs上安装docker所需的系统环境 需要以下CentOS版本之一的维…

基于JAVA的人事管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员功能模块2.2 普通员工功能模块2.3 答辩文案 三、系统展示四、核心代码4.1 查询职称4.2 新增留言回复4.3 工资申请4.4 工资审核4.5 员工请假 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的人…

STM32-开发板介绍

市面的开发板有很多&#xff0c;博主有幸了解到一款集成度较高的开发板&#xff0c;朗峰STM32F103RCT6&#xff0c;知名度不高&#xff0c;性价比很高&#xff0c;这是目前唯一一款集成了大量传感器和功能模块的高集成度开发板。 巨大的优势在于&#xff0c;传感器和功能模块的…

高效社区:数字孪生在智慧社区中的应用与实践

随着科技的快速发展&#xff0c;数字孪生技术在智慧社区建设中扮演着越来越重要的角色。数字孪生技术通过建立物理空间与数字空间的交互映射关系&#xff0c;实现对社区设施、环境、服务等智能化管理和服务&#xff0c;为未来社区的发展提供了新的动力。本文将探讨数字孪生在智…

【AI大语言模型】ChatGPT在地学、GIS、气象、农业、生态、环境等领域中的应用

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…