微信小程序实现PDF预览功能——pdf.js(含源码解析)

news2024/11/17 19:35:49

文章目录

      • 前言
      • 一、pdf.js 是什么?
      • 二、使用步骤
        • 1.下载库文件
        • 2.使用方式
          • 微信小程序端——使用 web-view 标签
          • H5 端——使用 iframe 标签(使用vue框架)
        • 3.更改源码
          • 如何隐藏顶部工具栏
          • 如何让用户强制阅读一定时间
          • 如何获取pdf总页数
          • 如何获取pdf当前页数
          • 将总页数和当前页数发送给小程序
      • 总结


前言

前一段时间遇到了一个需求,关于 pdf 文件的预览,客户要求如下:

  • 只能在微信小程序内预览,不能调起本地浏览器预览;
  • 需要让用户强制阅读 10s 后才算阅读完成,进而进行下一步操作;
  • 用户不能下载预览的 pdf 文件;

因为一些原因(此处省略一万字🐎),这个项目具有 H5 端和原生微信小程序端,并且他们有着相同的业务逻辑😊,所以最好的办法就是设计出一套方案适用两端,前期做了一些尝试,可以看这篇文章,最后决定使用 pdf.js 来实现业务要求。


一、pdf.js 是什么?

PDF.js 由 Mozilla 提供支持。目标是创建一个通用的、基于 Web 标准的平台,用于解析和呈现 PDF。

二、使用步骤

1.下载库文件

前往 pdf.js 的 官网 下载库文件,我们下载哪个版本都是可以的,后者适用于旧版浏览器,我这里下载的后者。

在这里插入图片描述

下载完成后,因为微信小程序打包的限制,我将库文件放到腾讯云服务器上,如果想测试可以联系我提供测试资源。
H5 可以放到本地,目录如下:

在这里插入图片描述

2.使用方式

通过web目录下 viewer.html 查看器 + pdf文件路径预览pdf文件

yourPath/web/viewer.html?file=pdfPath 
微信小程序端——使用 web-view 标签

代码示例:

//.wxml
<web-view src="{{pdfView+pdfUrl}}" ></web-view>

//.js
data: {
		// viewer.html 查看器的路径
        pdfView:"yourPath/web/viewer.html?file=",
        // 要预览的 pdf 文件的路径
        pdfUrl:"http://play.li-stack.top:88/pdf/sjisr-3-2-36-42.pdf"
    },

运行效果:
在这里插入图片描述

H5 端——使用 iframe 标签(使用vue框架)

代码示例:

<template>
    <div>
        <iframe :src="src" style="width: 100%;height: 100vh" ></iframe>
    </div>

</template>

<script>
    export default {
        name: "myTestTwo",
        data(){
            return {
                url:'http://play.li-stack.top:88/pdf/sjisr-3-2-36-42.pdf',
                src:''
            }
        },
        mounted() {
            this.getUrl();
        },
        methods :{
            getUrl:function () {
                this.src = '/pdfplugin/web/viewer.html?file=' + this.url
            }
        }
    }
</script>

<style scoped>

</style>

运行效果:
在这里插入图片描述

注意事项:

  • web-view 标签默认铺满全屏,会覆盖其他组件;
  • H5项目使用 pdf.js 注意跨域问题;

3.更改源码

如何隐藏顶部工具栏

在业务要求中,不能让用户下载 pdf ,我这里处理的办法就是将顶部工具栏隐藏
处理方法:

  • 在 web 文件夹下的 viewer.html 文件,搜到 <div class="toolbar">
  • 将其改为 <div class="toolbar" style="display:none">这样就可以隐藏了。
如何让用户强制阅读一定时间

在让用户强制阅读时,一定是 pdf 文件先加载完成,才开始倒计时。
处理方法:

  • 在 viewer.js 中找到 load 函数(可直接搜索load: function load(pdfDocument定位)) ,部分代码如下
load: function load(pdfDocument) {
    var _this11 = this;

    this.pdfDocument = pdfDocument;
    pdfDocument.getDownloadInfo().then(function (_ref4) {
      var length = _ref4.length;
      _this11._contentLength = length;
      _this11.downloadComplete = true;

      _this11.loadingBar.hide();

      firstPagePromise.then(function () {
        _this11.eventBus.dispatch("documentloaded", {
          source: _this11
        });
      });
    });
	
	//添加以下代码
	let mytime = 10
    let timeout = setInterval(()=>{
        console.log("倒计时:",mytime)
        if(mytime == 0){
            clearTimeout(timeout)
        }else{
            --mytime
        }
    },1000)

    ……
  }
  • 当pdf加载成功后运行效果,页面渲染效果大家可以自行实现
    在这里插入图片描述
如何获取pdf总页数

同样在上述 load 函数中,当pdf加载完成后,pdfDocument 属性中就包含了当前 pdf 的总页数
处理方法:可通过 pdfDocument.numPages 获取

如何获取pdf当前页数

如果能获取当前页数,也获取了总页数,这就可以实现阅读进度了,当然阅读进度的细节还有很多,比如用户很快地往下滑,这种肯定不能算是真正阅读了,在这里我就不细分了,下面来获取一下当前页数
处理方法:

  • 可以在本地储存中获取,键名:pdfjs.history
  • 找到函数 function webViewerPageChanging(_ref15) ,当每次滑动屏幕时,每经过一个页面就会得到当前页数,代码如下:
function webViewerPageChanging(_ref15) {
  var pageNumber = _ref15.pageNumber,
      pageLabel = _ref15.pageLabel;
  //这里打印出来
  console.log(pageNumber)
  PDFViewerApplication.toolbar.setPageNumber(pageNumber, pageLabel);
  PDFViewerApplication.secondaryToolbar.setPageNumber(pageNumber);

  if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) {
    PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(pageNumber);
  }
}
将总页数和当前页数发送给小程序

有时候会需要H5和小程序通讯,可以参考 这篇文章


总结

本文主要是针对微信小程序的 web-view 标签,在H5中使用 ifream 获取页数会有更简单的的方法,
例如可以尝试:

var iFrame = document.getElementById('iframe_id');
if( iFrame.contentDocument){
	let currentPageNum = iFrame.contentDocument.getElementById('pageNumber').value;
}
//或者
document.querySelector('iframe id').contentWindow.PDFViewerApplication.page;

//或者
window.PDFViewerApplication.pdfViewer.currentPageNumber

欢迎大家积极交流……

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

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

相关文章

【折腾电脑】Edge浏览器看B站视频卡顿最全解决办法合集

开头碎碎念&#xff1a;更新频率明显和疫情呈正相关&#xff0c;祝大家健健康康吃好喝好&#xff01; 使用Microsoft Edge浏览器观看B站视频&#xff0c;卡得无法忍受。 在网络上搜索相关问题&#xff0c;最早的一条是2016/04/17微软问题反馈的记录。任何原因的卡顿都是正常的&…

Vue样式穿透

Vue样式穿透 vue文件的style标签的scoped属性作用&#xff1a;PostCSS在元素标签上添加特殊属性值&#xff0c;在样式的选择器后面添加属性选择器&#xff0c;实现了组件样式的私有化&#xff0c;防止组件之间的样式污染&#xff08;比如相同类名的元素&#xff09;。 但在使…

【CSS】盒子模型内边距 ② ( 内边距复合写法 | 代码示例 )

文章目录一、内边距复合写法1、语法2、代码示例 - 设置 1 个值3、代码示例 - 设置 2 个值4、代码示例 - 设置 3 个值5、代码示例 - 设置 4 个值一、内边距复合写法 1、语法 盒子模型内边距 可以通过 padding-left 左内边距padding-right 右内边距padding-top 上内边距padding-…

前端开发服务器中的 Proxy 代理跨域实现原理解读

各位朋友你们好&#xff0c;我是桃小瑞&#xff0c;微信公众 桃小瑞。在这给大家拜个晚年&#xff0c;祝各位朋友新年快乐。 前言 在前端的开发过程中&#xff0c;尤其是在浏览器环境下&#xff0c;跨域是个绕不开的话题&#xff0c;相信每个前端都会涉及到这个问题&#xf…

“write javaBean error, fastjson version 1.2.83, class org.apache.shiro.web.servlet.ShiroHttpServletR

1. 相关技术 springboot 2.6.3mybatis-spring-boot-starter 2.2.2mybatis 3.5.10fastjson 1.2.83hutool-all 5.7.22shiro-spring 1.8.0 2. 报错信息 "write javaBean error, fastjson version 1.2.83, class org.apache.shiro.web.servlet.ShiroHttpServletRequest, meth…

<router-view> can no longer be used directly inside <transition> or <keep-alive>.

百度翻译&#xff1a; &#xff1c;router view&#xff1e;不能直接在&#xff1c;transition&#xff1e;或&#xff1c;keep alive&#xff1e;中使用。 改用插槽道具&#xff1a; 运行环境&#xff1a; "vue": "^3.2.8", "vue-router": &quo…

idea的vue文件中使用ElementUi组件

作为计算机专业的学生&#xff0c;在做实训项目时很惆怅前端页面的搭建&#xff0c;这个时候就突出到了组件的好处&#xff1b; 这篇就是给大家展示使用ElementUi组件&#xff01;&#xff01;&#xff01; 内容上分为vue3和之前的版本&#xff0c;自行选择&#xff01;&#x…

33.JavaScript映射与集合(Map、Set)数据类型基础知识介绍与使用

文章目录映射与集合&#xff08;Map、Set&#xff09;映射&#xff08;Map&#xff09;Map常用的方法不要使用map[key]访问属性对象作为Map的键Map的遍历与迭代默认的迭代方式forEach()从数组、对象创建Map从数组、Map创建对象集合&#xff08;Set&#xff09;集合迭代总结映射…

Vuex 之一:3种拿到 state 中数据的方式与实例剖析

Ⅰ、Vuex 简介&#xff1a; 1、Vuex 是什么&#xff1f; 答&#xff1a;Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式&#xff1b; 而所谓状态就是指&#xff1a;组件中所维护的数据); (简而言之&#xff1a;就是状态管理&#xff0c;解决复杂组件数据通信&#xff0c…

React中实现keepalive组件缓存效果

背景&#xff1a;由于react官方并没有提供缓存组件相关的api&#xff08;类似vue中的keepalive&#xff09;&#xff0c;在某些场景&#xff0c;会使得页面交互性变的很差&#xff0c;比如在有搜索条件的表格页面&#xff0c;点击某一条数据跳转到详情页面&#xff0c;再返回表…

处理vue中的长按事件、点击事件、默认事件冲突

写在前面 示例是h5项目。技术栈&#xff1a;vue vant nuxt。 知识点简介&#xff1a; touchstart: // 手指放到屏幕上时触发 touchend: // 手指离开屏幕时触发 touchmove: // 手指在屏幕上滑动式触发 touchcancel: // 系统取消touch事件的时候触发 页面及需求&#xff1a; …

一文教会你何为重绘、回流?

文章目录css图层图层创建的条件重绘(Repaint)回流触发重绘的属性触发回流的属性常见的触发回流的操作优化方案requestAnimationFrame----请求动画帧写在最后学习目标&#xff1a; 了解前端Dom代码、css样式、js逻辑代码到浏览器展现过程了解什么是图层了解重绘与回流了解前端层…

【已失效】免翻在Chrome上使用新必应(New Bing)聊天机器人

已失效&#xff0c;暂时没时间去摸索&#xff0c;大家可以在评论区讨论&#xff0c;其实大家评论的我也尝试过了&#xff0c;并没有找到一个很完美的方式&#xff0c;有时间折腾再更新吧&#xff01;&#xff01; 这里不讲如何加入New Bing内测 文章目录【更新】免翻使用New B…

如何理解虚拟DOM

一、js 操作DOM 假如现在你需要写一个像下面一样的表格的应用程序&#xff0c;这个表格可以根据不同的字段进行升序或者降序的展示。 这个应用程序看起来很简单&#xff0c;你可以想出好几种不同的方式来写。最容易想到的可能是&#xff0c;在你的 JavaScript 代码里面存储这样…

【CSS重点知识】属性计算的过程

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 标题什么是计算机属性确定声明值层叠冲突继承使用默认值总结什么是计算机属性 CSS属性值的计算…

Vue实例生命周期

Vue实例的生命周期就是Vue实例从创建到销毁的全过程。在这个过程中&#xff0c;经历了创建、初始化数据、编译模板、挂载Dom(beforeCreate(){}、created(){}、beforeMount(){}、mounted(){})、渲染→更新→渲染(beforeUpdate(){}、updated(){})、卸载(beforeDestroy(){}、destr…

SVG+CSS动画实现动效(流光、呼吸等效果)

流光效果 绘制流光线条 创建SVG&#xff0c;根据UI给的背景图&#xff0c;定位到图上每条管道&#xff08;即流光线条的路径&#xff09;的起始点以及拐点&#xff0c;绘制折线。绘制折线的时候按照下图方框通过class分组&#xff0c;这几组的光线流动是同时出发的。 svg相关知…

【大学生期末大作业】HTML+CSS+JavaScript — 模仿博客网站设计(Web)

你为什么不亲自下船&#xff0c; 就一次也好啊&#xff0c; 亲眼去看看这个世界。 目录 你为什么不亲自下船&#xff0c; 就一次也好啊&#xff0c; 亲眼去看看这个世界。 关于HTML5&#xff1a; 关于CSS&#xff1a; 关于JavaScript&#xff1a; 一、&#x1f30e;前言…

牛客前端刷题(四)——微信小程序篇

还在担心面试不通过吗?给大家推荐一个超级好用的刷面试题神器:牛客网,里面涵盖了各个领域的面试题库,还有大厂真题哦! 赶快悄悄的努力起来吧,不苒在这里衷心祝愿各位大佬都能顺利通过面试。 面试专栏分享,感觉有用的小伙伴可以点个订阅,不定时更新相关面试题:面试专栏…

Vue 使用 Vue-socket.io 实现即时聊天应用(Vue3连接原理分析)

目录 前言&#xff1a; 一、新建 Vue3 项目 二、下载相关依赖 2.1 后台服务 2.2 前端连接 2.3 启动项目 2.4 触发与接收事件 2.5 原因分析 三、vue3 使用socket的原理 3.1 socket对象实例 3.2 socket 触发事件 3.3 socket对象监听原生事件 3.4 vue-socket.io 源码解析 …