Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)

2023-10-27

一、使用插件pdfh5预览pdf

参考文档:pdfh5 - npm  

项目相关依赖版本信息

预览效果如下图所示:

1.上下滚动和缩放查看

2.左上角固定显示当前页码和总页数

3.右下角一键回到顶部按钮

4.在每页pdf上添加图片水印

①安装插件:yarn add pdfh5(pdfh5@1.4.2)

②使用pdfh5插件预览pdf

<template>
  <div class="m-pdf">
    <div id="pdf"></div>
  </div>
</template>
<script>
import Pdfh5 from 'pdfh5'
import 'pdfh5/css/pdfh5.css'
export default {
  name: 'Pdfh5',
  data () {
    return {
      pdfh5: null,
      // 可引入网络文件或者本地文件
      pdfUrl: '/Markdown.pdf' // 如果引入本地pdf文件,需要将pdf放在public文件夹下,引用时使用绝对路径(/:表示public文件夹)
    }
  },
  mounted () {
    // pdfh5实例化时传两个参数:selector选择器,options配置项参数,会返回一个pdfh5实例对象,可以用来操作pdf,监听相关事件
    // pdfh5 = new Pdfh5(selector, options) goto初始到第几页,logo设置每一页pdf上的水印
    this.pdfh5 = new Pdfh5('#pdf', { pdfurl: this.pdfUrl, goto: 1, logo: { src: require('images/logo.png'), x: 420, y: 700, width: 120, height: 120 } })
    // 监听pdf准备开始渲染,此时可以拿到pdf总页数
    this.pdfh5.on('ready', function () {
      console.log('总页数:' + this.totalNum)
    })
    // 监听pdf加载完成事件,加载失败、渲染成功都会触发
    this.pdfh5.on('complete', (status, msg, time) => {
      console.log('状态:' + status + ',信息:' + msg + ',耗时:' + time + '毫秒')
    })
  }
}
</script>
<style lang="less" scoped>
.m-pdf { // 保证pdf区域铺满整个屏幕
  // 方法1:使用vw和vh视窗单位,1vw=视窗宽度的1%;1vh=视窗高度的1%
  // width: 100vw;
  // height: 100vh;
  // 方法2:使用fixed定位
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
}
</style>

二、使用插件vue-pdf预览pdf

相关参考文档:vue-pdf - npm

安装插件:yarn add vue-pdf(@vue-pdf@4.3.0)

②使用vue-pdf插件在移动端网页进行pdf预览

  1. 一次性加载全部pdf,上下滚动查看pdf(初次加载较慢,交互体验较差)
<template>
  <div class="m-vue-pdf">
    <div v-show="loaded">
      <Pdf v-for="index in numPages" :key="index" :src="pdfUrl" :page="index" />
    </div>
  </div>
</template>
<script>
import Pdf from 'vue-pdf'
export default {
  name: 'VuePdf',
  components: {
    Pdf
  },
  data () {
    return {
      loaded: false,
      numPages: null,
      // 可引入网络文件或者本地文件
      pdfUrl: '/Markdown.pdf' // 如果引入本地pdf文件,需要将pdf放在public文件夹下,引用时使用绝对路径(/:表示public文件夹)
    }
  },
  created () {
    this.loadPdf()
  },
  methods: {
    // 上下滚动pdf加载
    loadPdf () {
      this.pdfUrl = Pdf.createLoadingTask(this.pdfUrl)
      this.pdfUrl.promise.then(pdf => {
        this.$nextTick(() => {
          this.numPages = pdf.numPages // pdf总页数
          this.loaded = true
        })
      })
    }
  }
}
</script>
<style lang="less" scoped>
.m-vue-pdf {
  overflow: hidden;
}
</style>

2.分页加载预览pdf,左上角自定义显示当前页码和总页数,通过监听手指上下(或左右)滑动进行翻页

效果如下图所示:

<template>
  <div class="m-vue-pdf">
    <div class="u-page" v-show="loaded">
      {{currentPage}}/{{totalCount}}
    </div>
    <Pdf
      :src="pdfUrl"
      :page="currentPage"
      @num-pages="totalCount=$event"
      @page-loaded="currentPage=$event"
      @loaded="loadPdfHandler"
    />
  </div>
</template>
<script>
import Pdf from 'vue-pdf'
export default {
  name: 'VuePdfPaging',
  components: {
    Pdf
  },
  data () {
    return {
      loaded: false,
      rootSize: 0,
      startx: 0,
      starty: 0,
      endx: 0,
      endy: 0,
      currentPage: 1, // pdf文件页码
      totalCount: 0, // pdf文件总页数
      // 可引入网络文件或者本地文件
      pdfUrl: '/Markdown.pdf' // 如果引入本地pdf文件,需要将pdf放在public文件夹下,引用时使用绝对路径(/:表示public文件夹)
    }
  },
  created () {
    var docEl = window.document.documentElement // 即<html></html>标签
    var width = window.screen.availWidth || window.screen.width
    this.rootSize = width / 15 // 设置rem相对单位大小
    docEl.style.fontSize = this.rootSize + 'px'
  },
  mounted () {
    document.body.addEventListener('touchmove', this.touchMove, { passive: false }) // 禁用H5页面的下拉刷新
    document.body.addEventListener('touchstart', this.touchStart, false) // true: 表示在捕获阶段调用事件处理程序;false:表示在冒泡阶段调用事件处理程序
    document.body.addEventListener('touchend', this.touchEnd, false)
  },
  methods: {
    touchMove (e) {
      e.preventDefault()
      this.$once('hook:beforeDestroy', function () {
        removeEventListener('touchmove', this.touchMove)
      })
    },
    touchStart (e) {
      console.log('start:', e)
      this.startx = e.touches[0].pageX
      this.starty = e.touches[0].pageY
      console.log('start:', this.startx, this.starty)
      this.$once('hook:beforeDestroy', function () {
        removeEventListener('touchstart', this.touchStart)
      })
    },
    touchEnd (e) {
      console.log('end:', e)
      this.endx = e.changedTouches[0].pageX
      this.endy = e.changedTouches[0].pageY
      console.log('end:', this.endx, this.endy)
      // y方向上(或x方向上)滑动超过50px进行翻页
      if ((this.starty - this.endy) / this.rootSize > 5 || (this.startx - this.endx) / this.rootSize > 5) {
        this.nextPage()
      }
      if ((this.endy - this.starty) / this.rootSize > 5 || (this.endx - this.startx) / this.rootSize > 5) {
        this.prePage()
      }
      this.$once('hook:beforeDestroy', function () {
        removeEventListener('touchend', this.touchEnd)
      })
    },
    prePage () {
      if (this.currentPage > 1) {
        this.currentPage--
      }
    },
    nextPage () {
      if (this.currentPage < this.totalCount) {
        this.currentPage++
      }
    },
    // pdf加载时
    loadPdfHandler (e) {
      this.currentPage = 1 // 加载的时候先加载第一页
      this.loaded = true
    }
  }
}
</script>
<style lang="less" scoped>
.m-vue-pdf {
  overflow: hidden;
  .u-page {
    position: fixed;
    left: 2rem;
    top: 1rem;
    z-index: 999;
    font-size: 1.5rem;
    color: #FFF;
    padding: 0.2rem 0.8rem;
    border-radius: 0.64rem;
    background: rgba(0, 0, 0, 0.5);
    letter-spacing: 0.1rem;
  }
}
</style>

3.采用分页预览pdf,包括自定义跳转到指定页数,上一页,下一页按钮(初次加载更快,交互体验更好)

效果如下图:

<template>
  <div class="m-vue-pdf" v-show="loaded">
    <div class="m-page">
      <div class="m-left">
        <span class="u-label">跳至</span>
        <input v-model='jumpNum' type="number" class="u-input" />
        <span class="u-unit">页</span>
        <a class="u-button" @click="onJump">确定</a>
        <div class="assist"></div>
      </div>
      <div class="m-right">
        <svg viewBox="64 64 896 896" data-icon="left" :class="['u-arrow', { gray: currentPage===1 }]" @click="onPrePage" aria-hidden="true" focusable="false"><path d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"></path></svg>
        <span class="u-num">{{currentPage}}/{{totalCount}}</span>
        <svg :class="['u-arrow', { gray: currentPage===totalCount }]" @click="onNextPage" viewBox="64 64 896 896" data-icon="right" aria-hidden="true" focusable="false"><path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"></path></svg>
        <div class="assist"></div>
      </div>
    </div>
    <Pdf
      :src="pdfUrl"
      :page="currentPage"
      @num-pages="totalCount=$event"
      @page-loaded="currentPage=$event"
      @loaded="loadPdfHandler">
    </Pdf>
  </div>
</template>
<script>
import Pdf from 'vue-pdf'
export default {
  naem: 'VuePdfJump',
  components: {
    Pdf
  },
  data () {
    return {
      loaded: false,
      numPages: '',
      currentPage: 1, // pdf文件页码
      totalCount: 0, // pdf文件总页数
      jumpNum: null,
      // 可引入网络文件或者本地文件
      pdfUrl: '/Markdown.pdf' // 如果引入本地pdf文件,需要将pdf放在public文件夹下,引用时使用绝对路径(/:表示public文件夹)
    }
  },
  created () {
    var docEl = window.document.documentElement
    var width = window.screen.availWidth || window.screen.width
    var rootSize = width / 15
    docEl.style.fontSize = rootSize + 'px'
  },
  methods: {
    onJump () {
      if (this.jumpNum) {
        if (Number(this.jumpNum) <= this.totalCount && Number(this.jumpNum) >= 1) {
          this.currentPage = Number(this.jumpNum)
          this.jumpNum = null
        } else {
          this.$toast('请输入正确的跳转页码', this.toastParams)
        }
      } else {
        this.$toast('请输入要跳转的页码', this.toastParams)
      }
    },
    onPrePage () {
      if (this.currentPage > 1) {
        this.currentPage--
      }
    },
    onNextPage () {
      if (this.currentPage < this.totalCount) {
        this.currentPage++
      }
    },
    // pdf加载时
    loadPdfHandler (e) {
      this.currentPage = 1 // 加载的时候先加载第一页
      this.loaded = true
    }
  }
}
</script>
<style lang="less" scoped>
.m-vue-pdf {
  overflow: hidden;
  .m-page {
    position: sticky;
    top: 0;
    left: 0;
    right: 0;
    height: 1.5rem;
    display: flex;
    z-index: 9;
    justify-content: space-between;
    .m-left {
      margin-left: 0.8rem;
      font-size: 0.64rem;
      color: #333;
      .u-label {
        display: inline-block;
        vertical-align: middle;
      }
      .u-input {
        width: 1rem;
        height: 0.64rem;
        border: 0.04rem solid #999;
        border-radius: 0.1rem;
        margin: 0 0.16rem;
        text-align: center;
        background: #FFF;
        outline: none;
        vertical-align: middle;
      }
      .u-unit {
        margin-right: 0.24rem;
        vertical-align: middle;
      }
      .u-button {
        color: #333;
        display: inline-block;
        padding: 0.01rem 0.2rem;
        border-radius: 0.08rem;
        border: 0.04rem solid #999;
        font-size: 0.54rem;
        background: transparent;
        outline: none;
        vertical-align: middle;
        -webkit-tap-highlight-color: transparent;
      }
      .assist {
        height: 100%;
        width: 0;
        display: inline-block;
        vertical-align: middle;
      }
    }
    .m-right {
      margin-right: 0.8rem;
      font-size: 0.64rem;
      color: #333;
      .u-arrow {
        width: 0.64rem;
        height: 0.64rem;
        fill: #333;
        vertical-align: middle;
        cursor: pointer;
      }
      .gray {
        fill: #999;
        cursor: default;
      }
      .u-num {
        letter-spacing: 0.1rem;
        display: inline-block;
        margin: 0 0.2rem;
        vertical-align: middle;
      }
      .assist {
        height: 100%;
        width: 0;
        display: inline-block;
        vertical-align: middle;
      }
    }
  }
}
</style>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf) 的相关文章

随机推荐

  • Hibernate学习笔记 多表映射

    前面说了Hibernate的单表映射 由于是实体类和数据表之间一对一的映射 所以比较简单 现在就来说说多表映射 这需要涉及到多个实体类和数据表之间的关系 因此稍微复杂一点 建立实体类 我建立了两个实体类 一个作者类 一个文章类 其他方法都忽
  • Pytorch使用DDP加载模型时出现多进程在GPU0上占用过多显存的问题

    使用pytorch DDP DistributedDataParallel 分布式数据并行 可以进行多卡训练 涉及到模型保存与加载问题时 一般会涉及到以下两种需求 将多卡训练的模型保存到磁盘 从磁盘加载模型 在多卡上继续训练 如何无bug且
  • MySQL server安装流程

    1 进入到mysql官网MySQL 这里显示的是32位 但是实际下载的时候也会下载64位的 双击进行安装 然后一路点击next 配置保持默认 然后点击next 2 配置环境变量 如果想要在dos面板中使用mysql命令 需要到系统变量pat
  • 【牛客网】找出字符串中第一个只出现一次的字符

    题目描述 找出字符串中第一个只出现一次的字符 输入描述 输入一个非空字符串 输出描述 输出第一个只出现一次的字符 如果不存在输出 1 示例 输入 asdfasdfo 输出 o 完整代码 include
  • AddString[LeetCode]

    class Solution public string addStrings string num1 string num2 string res int m num1 size 1 记录字符串num1最后一位 int n num2 si
  • 阿里云飞天系统

    阿里云飞天系统 有幸在阿里云飞天部门工作几年 下面给出基础架构一览
  • 能拟合任何函数的神经网络只是个分段线性函数

    原文 https mp weixin qq com s XA1zS9bvgAfRkmTh e 78g 阅读本文 你可以理解 能逼近 拟合 任何函数只是个分段线性函数 让你深刻理解神经网络能力的边界 消除你对神经网络的神秘感 需要你具备的知识
  • PMOS管经典开关电路-PMOS开关典型电路工作原理及分析-KIA MOS管

    PMOS管经典开关电路 下图是两种PMOS管经典开关电路应用 其中第一种NMOS管为高电平导通 低电平截断 Drain端接后面电路的接地端 第二种为PMOS管典型开关电路 为高电平断开 低电平导通 Drain端接后面电路的VCC端 首先要进
  • 在本地配置nginx配置负载均衡

    首先建一个工程 确保在idea上能跑通 2 把这个项目打成war包 在tomcat下跑 1 为了不影响idea项目的正常运行 我在复制一个tomact 命名为tomcat 1 这个时候是要给tomcat 1配置环境变量的 有两种配置方案 一
  • 机械寿命预测(基于NASA C-MAPSS数据的剩余使用寿命RUL预测,Python代码,CNN_LSTM模型,有详细中文注释)

    1 效果视频 机械寿命预测 NASA涡轮风扇发动机剩余使用寿命RUL预测 Python代码 CNN LSTM模型 有详细中文注释 哔哩哔哩 bilibili 环境库版本 2 数据来源 https www nasa gov intellige
  • 基于Anycloud平台移植zxing-cpp(glassechidna )

    基于Anycloud平台移植zxing cpp 0 环境准备 系统环境Ubuntu 16 04 7 zxing cpp下载 本次使用的是 glassechidna 的代码 git clone https github com glassec
  • STM32F103C8T6+ST7735TFT LCD彩屏驱动程序

    使用环境 蓝色粗体字为特别注意内容 1 软件环境 Keil MDK 5 15 2 硬件环境 STM32F103C8T6最小系统 ST7735 1 44寸TFT LCD 某宝看到一块1 44寸的LCD 性价比蛮高 图片如下 主要参数如下 点阵
  • 使用git管理keil工程

    1 gitignore规则 使用git管理工程时 工程目录下有许多文件是不需要跟踪管理的 因此 我们一般会在工程目录下创建 gitignore文件 在其中编写忽略规则即可 gitignore忽略规则如下表所示 格式 说明 示例 注释 本行为
  • 安全工具箱必备技术之静态分析安全测试(SAST)

    有几种技术可以识别软件和系统的漏洞 聪明的组织把它们放在他们的 安全工具箱 中 并使用各种测试工具的组合 包括 静态分析安全测试 SAST 动态分析安全测试 DAST 源成分分析 SCA 漏洞扫描器 渗透测试 通过自动化工具提高安全性的动机
  • 第一周-1.1栈

    栈 描述 实现一个栈 完成以下功能 入栈 出栈 询问栈中位置Y是谁 一开始栈为空 栈中的位置从1开始 即栈底位置为1 输入 第一行一个整数n 表示操作个数 接下来n行 每行第一个数字表示操作 见描述 若为数字1 则接下来有一串字符串X 表示
  • js闭包作用(避免使用全局变量)

    js闭包作用 避免使用全局变量 一 总结 1 优点 可以把局部变量驻留在内存中 可以避免使用全局变量 2 缺点 也有占用更多内存的缺点 用完要及时让垃圾回收器回收 fn null 应及时解除引用 否则会占用更多存 3 闭包两种访问方式会有不
  • 虚拟服务器整合器,虚拟服务器整合关键技术研究

    摘要 虚拟服务器整合技术是将集群中多个物理服务器上运行的应用程序通过虚拟机封装后再整合到少数物理服务器上运行的技术 在企业级数据中心规模不断扩大的今天 虚拟服务器整合技术能够大大减少集群中使用的服务器的数量 从而帮助企业大幅降低硬件和运营成
  • 照成“未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突”的三种可能性

    可能性 3 种 1 数据越界或是定义的指针未释放 2 空的指针的可能性最大 使用指针前最好能显式的赋值 应该是指针的问题 3 内存访问错误 检查指针 是否为空 是否越界等
  • VuforiaSDK

    由于课程原因学习了Unity平台下VuforiaSDK的AR应用开发 制作过程中也遇到了不少问题 作为记录发在这里 希望对大家有帮助 目录 一 准备工作 二 创建一个单张图预定义目标识别的应用 三 用户自定义目标识别应用实现 四 模型动画
  • Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)

    一 使用插件pdfh5预览pdf 参考文档 pdfh5 npm 项目相关依赖版本信息 预览效果如下图所示 1 上下滚动和缩放查看 2 左上角固定显示当前页码和总页数 3 右下角一键回到顶部按钮 4 在每页pdf上添加图片水印 安装插件 ya