引言:最近在做微信小程序和手机端app开发(基于vue),实现一个pdf预览功能。

  • 需求:点击pdf列表,跳转到预览pdf页面,页面上强制阅读10s后,显示一个按钮返回,更新阅读状态;
  • 要求:不能调用本地浏览器预览,不能让用户下载pdf,强制阅读10s后才可返回;
  • 准备:pdf在线文档:“http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf”

1.微信小程序端

  1. 方式一:webview
<web-view src="http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf" ></web-view>

运行结果
分析

  • 上述结果是在ios系统上运行的,pdf可以正常显示;
  • 在android系统上,解析失败,一直显示空白界面;
  • 原因:ios可以自动解析pdf,安卓系统则解析不了;
  • 补充:在webview标签上显示按钮,相信做过微信小程序开发的都了解webview标签会默认占满全屏,覆盖掉其他组件,这个时候如果我们想加一个按钮就可以用cover-view标签来实现,具体实现大家可以自己去探索。

总结:使用webview标签在系统上兼容性并不好,不能控制下载状态,而且在阅读状态上只能做到“假控制”。

2.手机app端(vue)

1. 使用 iframe、embed、新窗口打开

        <iframe class="iframe" src="http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf"></iframe>
        <embed class="iframe" src="http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf">

优点:简单,支持大部分 PC 浏览器(IE 不支持)。跨域资源同样可以(无需 cors)
缺点:不支持移动端浏览器,不支持 IE 等低版本浏览器。样式无法自定义。

2. 使用vue中的组件vue-pdf

安装:打开命令行,直接使用npm或者yarn安装

npm install --save vue-pdf
<template><div class="pdf_wrap"><div class="pdf_list"><pdf  :src="src"  style="width: 100%" ref="pdf"> </pdf></div></div>
</template><script>import pdf from 'vue-pdf'export default {name: 'myTestOne',components: {pdf},data () {return {src: 'http://cn.createpdfonline.org/pdffiles/test(20211215094117).pdf',}},methods: {}}
</script>
<style scoped>.pdf_wrap {background: #fff;height: 100vh}.pdf_list {height: 80vh;overflow: scroll;}</style>

当你运行这段代码时(在pdf链接没过期的情况下),你会惊奇地发现,会出现跨域问题,并报出以下错误:

解决方案一
你需要联系你的后端小伙伴,因为PDF 文件作为静态资源放在 nginx服务器中。
在 nginx.conf 中设置:

add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin $http_origin;

完整配置如下:

server {listen       80;server_name  localhost;add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Origin $http_origin;location / {root   pdf;index  index.html index.htm;}
}

解决方案二(存在问题,后期研究)
和vue 接口请求解决跨域问题一样,在本地开发时同样通过 webpack的devServer去代理pdf预览的url(请求),其他环境(生成及测试)则让后端去解决。

解决开发环境pdf预览跨域问题就是在devServer中添加一个代理即可:

//vue.config.js
proxy: {//当pdf和数据接口不在同一个请求地址下时,为pdf预览追加一个代理"/pdf": {target:"http://cn.createpdfonline.org/pdffiles",changeOrigin: true,pathRewrite: {'^/pdf': ''}}}

运行结果如下:

重新保存项目,这个pdf就会显示在你的眼前,但是别高兴得太早,这个pdf只有一页,所以在这个基础上进行以下优化:

  • 显示多页pdf
  • 显示pdf总页数
  • 实现一页一页翻pdf的功能
  • 监控当前页面加载进度

代码实现(多页显示):

<template><div class="pdf_wrap"><div class="pdf_list"><pdf   v-for="i in numPages" :key="i" :page="i" :src="url"  style="width: 100%"  > </pdf></div></div>
</template><script>import pdf from 'vue-pdf'export default {name: 'myTestOne',components: {pdf},data () {return {src: 'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',numPages:1,url:''}},mounted: function() {this.getNumPages()},methods: {getNumPages() {this.url = pdf.createLoadingTask(this.src)this.url.promise.then(pdf => {this.numPages = pdf.numPages // 这里拿到当前pdf总页数})},}}
</script>
<style scoped>.pdf_wrap {background: #fff;height: 100vh}.pdf_list {height: 100vh;overflow: scroll;}</style>

结果展示:

该代码在pdfjsWrapper.js文件的第196行会报错,(偷摸给注释掉了)

           //pdfRender.cancel().catch(function(err) {//emitEvent('error', err);//});

代码实现(单页展示,可翻页):

<template><div><div class="tools"><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="prePage" class="mr10"> 上一页</bk-button><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="nextPage" class="mr10"> 下一页</bk-button><div class="page">{{pageNum}}/{{pageTotalNum}} </div><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="clock" class="mr10"> 顺时针</bk-button><bk-button :theme="'default'" type="submit" :title="'基础按钮'" @click.stop="counterClock" class="mr10"> 逆时针</bk-button></div><pdf ref="pdf":src="url":page="pageNum":rotate="pageRotate"@progress="loadedRatio = $event"@page-loaded="pageLoaded($event)"@num-pages="pageTotalNum=$event"@error="pdfError($event)"@link-clicked="page = $event"></pdf></div>
</template>
<script>import pdf from 'vue-pdf'export default {name: 'Home',components: {pdf},data() {return {url: "http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf",pageNum: 1,pageTotalNum: 1,pageRotate: 0,// 加载进度loadedRatio: 0,curPageNum: 0,}},mounted: function() {},methods: {// 上一页函数,prePage() {var page = this.pageNumpage = page > 1 ? page - 1 : this.pageTotalNumthis.pageNum = page},// 下一页函数nextPage() {var page = this.pageNumpage = page < this.pageTotalNum ? page + 1 : 1this.pageNum = page},// 页面顺时针翻转90度。clock() {this.pageRotate += 90},// 页面逆时针翻转90度。counterClock() {this.pageRotate -= 90},// 页面加载回调函数,其中e为当前页数pageLoaded(e) {this.curPageNum = e},// 其他的一些回调函数。pdfError(error) {console.error(error)},}}
</script>
<style scoped></style>

结果展示

总结:在实际测试中发现以下问题

  • 场景:一个pdf列表,点击每个pdf预览;
  • 结果:在ios系统中偶尔会出现白屏的状态,而在android系统中没有这个问题。

经过以上的尝试后,最后决定基于pdf.js来实现业务要求。

引言:经上面的测试,发现了以下问题:

  1. 兼容性不好
  2. 不适用多语言场景(不能共用一套)
  3. 会出现跨域问题
  4. 难于监控阅读状态
  5. 不能控制下载状态

在基于vue开发的移动项目中,如果预览的pdf数量不是很多的话,是可以使用 vue-pdf 的,因为在实际开发测试中,ios系统依次预览多个pdf文件会出现白屏的现象,android系统不会出现。但是此时也很难监控阅读状态,所以最后采用pdf.js来实现业务需求。


目录:

  • 实现效果
  • 1.下载pdfjs
  • 2.放在项目中位置
  • 3.在页面中使用
  • 4.出现问题
  • 5.更改源码

实现效果

1.下载pdfjs

官网:

http://mozilla.github.io/pdf.js/getting_started/#download

2.放在项目中位置

将下载下来的文件解压,放在项目的public目录下


为了减小打包体积,bulid文件夹中保留pdf.js和pdf.worker.js即可正常编译。

3.在页面中使用

在我的项目中,pdf文件是以url的形式提供的,我们在页面中放一个iframe,他的src属性等于到viewer.html的相对路径 '/pdfplugin/web/viewer.html?file=' ,file后拼接你的pdf的url就可以了。

代码实现:

<template><div><iframe :src="src" style="width: 100%;height: 100vh" ></iframe></div></template><script>export default {name: "myTestTwo",data(){return {url:'http://storage.xuetangx.com/public_assets/xuetangx/PDF/PlayerAPI_v1.0.6.pdf',src:''}},mounted() {this.getUrl();},methods :{getUrl:function () {this.src = '/pdfplugin/web/viewer.html?file=' + this.url}}}
</script><style scoped></style>

效果展示

通过结果可以看出,pdf.js真的是很强大,我们可以按照需求来更改源码,实现自己想要的效果。

4.出现问题

  • 跨域问题:可参考这篇文章,推荐让后端小伙伴添加配置。
  • 当访问本地文件时,有可能会出现**Not allowed to load local resource**的问题,原因是谷歌浏览器禁止直接访问磁盘文件,在实际开发中,文件大多存在服务器中,如果个人想学习测试可以使用在线的pdf资源。
  • 在使用viewer.html相对路径时有可能找不到正确路径,我之前的路径是/public/pdfplugin/web/viewer.html?file=,发现怎么也找不到文件,后来去掉了一层/public,pdf就神奇的出来了。

5.更改源码(持续更新中)

实现微信小程序和手机app(基于vue)PDF预览功能相关推荐

  1. 微信小程序实现图片是上传、预览功能

    本文实例讲述了微信小程序实现图片上传.删除和预览功能的方法,分享给大家供大家参考,具体如下: 这里主要介绍一下微信小程序的图片上传图片删除和图片预览 1.可以调用相机也可以从本地相册选择 2.本地实现 ...

  2. 小程序 | 微信小程序实现图片是上传、预览功能

    效果图 index.wxml <!-- 打开截图 开始 --> <view class="imageContainer"><view class=&q ...

  3. 实现微信小程序和手机app远程控制51单片机控制L298N电机驱动器控制马达(ESP8266 AT89S52 http请求转串口通信系统 mqtt )

    首先你有这样的8266 这种8266自身带2个按键和烧录芯片方便调试,综合性价比较高. 还有就是你需要有一个51单片机或者其他芯片都行.有了这2个芯片我们开始吧! 1.先看一段视频效果演示,再来介绍实 ...

  4. 【小程序模板】功能模块+仿vivo手机商城微信小程序+品牌手机APP购物网页模板

    [小程序模板]功能模块+仿vivo手机商城微信小程序+品牌手机APP购物网页模板 源码简介与安装说明: 仿vivo手机商城微信小程序 品牌手机app购物网页模板源码下载. 小程序源码下载地址:(82条 ...

  5. 关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案

    关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案 参考文章: (1)关于微信小程序开发环境苹果IOS真机预览报SSL协议错误问题解决方案 (2)https://www.cnblog ...

  6. 微信小程序saveFile,openDocument方法下载、预览pdf文件不能用本地应用打开(不能另存为)的问题

    微信小程序saveFile,openDocument方法下载.预览pdf文件不能用本地应用打开(不能另存为)的问题 查看官方文档的openDocument()方法,发现加一个showMenu: tru ...

  7. 微信小程序与手机APP的区别

    最近在研究论文选题,到底是做手机APP好还是尝试一下很火热的微信小程序呢?我收集整理了一些网上资料做参考.也在这里做个记录. 是什么? 微信小程序,简称小程序,是一种不需要下载安装即可使用的应用,它实 ...

  8. 微信小程序 android内存暂用,微信小程序与手机APP占用内存 流量消耗对比介绍

    10年前的1月9日诞生了iPhone,今年的1月9日诞生了微信小程序,这无疑是2017年中国互联网圈的开年大事件.这几天,相信大家在网上到处都被微信小程序刷了屏,各种技术探讨.前景分析层出不穷,尤其是 ...

  9. MAC系统利用charles抓取微信小程序和手机APP数据包(http和https数据包)

    本文中使用的是mac上的抓包工具charles进行抓包,手机是华为荣耀8 下载并安装Charles for Mac Charles for Mac(HTTP信息抓包工具) V4.2.5 苹果电脑版 要 ...

最新文章

  1. Linux下编译一个静态链接的程序的注意点
  2. ML:推荐给小白入门机器学习一系列书籍
  3. Intel Realsense 处理帧时报错:RuntimeError: null pointer passed for argument frame_ref
  4. c语言语法分析源程序,深入浅出编译原理-5-一个简单语法分析器的C语言实现
  5. HTTP 301 跳转和302跳转的区别
  6. shell 执行失败重试_Uipath 机器人总是运行失败怎么办?
  7. 大一萌新看过来,C语言学到什么程度,才能“毕业不失业”!
  8. linux查看文件时显示行号,linux中查看文件时显示行号
  9. ubuntu 分区_系统小技巧:迁移通过Wubi方式安装的Ubuntu系统
  10. android刷机工具mac版,苹果一键刷安卓!OS X版CM刷机工具发布
  11. jsonrpc-c编译
  12. Python下载Wyoming怀俄明大学探空数据(数据网址更新)
  13. win10系统安装教程(U盘PE+UEFI安装)
  14. MacBook Pro 上网很慢
  15. JAVA微服务架构视频教程
  16. free源码分析---1
  17. PMBOK2004版44个过程的工具和技术的总结
  18. 饿了么退货显示服务器异常,外卖配送异常订单如何处理?商家必看!
  19. VS2008 使用小技巧-------快捷键
  20. python操作Excel的5种常用方式

热门文章

  1. 多线程-如何用多线程去并行传输文件
  2. VGA HDMI DVI DP接口是什么之显示器显示不清晰我该怎么办
  3. JAVA计算机毕业设计小型企业员工工资管理系统(附源码、数据库)
  4. 博客作者简介--Dynamics 365技术到项目经理之路
  5. easyExcel 数据导入
  6. Integer.bitCount(int i)的理解
  7. 喜茶VS蜜雪冰城:从茶饮争霸到双双遇阻
  8. vue中多个路由页面切换造成滚动互相影响问题的解决
  9. PK擂台:搜狗浏览器3.0预览版与IE9性能对比
  10. 联想电脑 linux bios设置,联想电脑bios启动项设置图文教程详解