【vue3+vue-pdf-embed】实现PDF+图片预览

【vue3+vue-pdf-embed】实现PDF+图片预览

项目背景

技术栈:vue3+Ts+elementplus

需要实现PDF和图片预览

图片预览很好解决了,可以用elementplus 自带的组件el-image 可实现

PDF预览可以用搜了一圈,有两个方案,一个是vue-office-pdf ,另一个是vue-pdf-embed

由于项目需求,只需要做预览 ,且只支持 PDF ,也不需要什么高级文档操作功能,所以我就采用了vue-pdf-embed

项目代码

html 代码

javascript 复制代码
<my-dialog ref="myDialogRef" width="60%" max-height="70vh">
   <div v-loading="dialogLoading" class="reviewDiv">
      <el-image v-if="imageDialogVisible" :src="imageSrc" style="max-width: 100%;" fit="contain" />
      <vue-pdf-embed v-else ref="pdfRef" :source="imageSrc" :page="pdfPage" @password-requested="handlePasswordRequest" @rendered="handleDocumentRender" />
      <div v-show="!imageDialogVisible && pageCount" class="text-center">
          <el-button :disabled="pdfPage <= 1" @click="pdfPage--">❮</el-button>
          <span class="mx-4">{{ pdfPage }} / {{ pageCount }}</span>
          <el-button :disabled="pdfPage >= pageCount" @click="pdfPage++">❯</el-button>
      </div>
    </div>
</my-dialog>

js 代码

javascript 复制代码
const imageSrc = ref('')
const myDialogRef = ref()
const imageDialogVisible = ref<boolean>(false)
const dialogLoading = ref<boolean>(false)
const openFileDialog = (file: any) => {
  dialogLoading.value = true
  // 释放之前创建的对象URL
  if (imageSrc.value) {
    URL?.revokeObjectURL(imageSrc.value)
  }
  // 创建新的对象URL
  if (file.raw) {
    // 本地预览
    imageSrc.value = URL?.createObjectURL(file.raw)
    dialogLoading.value = false
  } else {
    // 编辑远程预览
    const targetFile = getTargetFile.value(file)
    apiDownloadFile(targetFile[0].fileDocumentId).then((response: any) => {
      imageSrc.value = response.request.responseURL
      setTimeout(() => {
        dialogLoading.value = false
      }, 1000)
    })
  }
  const isImage = judgeIcon(file) === 'image'
  myDialogRef.value?.openDialog(isImage ? '图片预览' : 'PDF预览')
  if (isImage) {
    imageDialogVisible.value = true
  } else {
    imageDialogVisible.value = false
  }
}

const pdfPage = ref<number>(1)
const pageCount = ref<number>(0)
const pdfRef = ref()
function handleDocumentRender () {
  pageCount.value = pdfRef.value?.doc?.numPages // 这里是重点
}

function handlePasswordRequest (callback: any, retry: boolean) {
  callback(prompt(retry ? 'Enter password again' : 'Enter password'))
}

分析代码

首先预览有本地预览和远程预览

  1. 本地预览顾名思义:就是在本地上传还没有调接口的PDF或图片进行预览,这时候通过URL 接口里面的静态方法并往里面传file.raw 便可得到 本地PDF/图片链接了
    具体请看这里URL:createObjectURL() 静态方法
  2. 远程预览:即从后端接口返回回来的PDF/图片 进行预览,这时候需要先调用下载接口 ,接口会返回 对应的链接
    通过以上两步:可以把 需要传递的 source 的值搞定

需要PDF很大,有很多页,这时候预览需要分页,但是分页的时候有一个问题,就是一直找不到对应的总页码即pageCount ,有看很多文章,要么通过rendered方法传参,但文档根据不支持传参,
vue-pdf-embed

后面自己试了一下,居然 使用 ref 的方式 pdfRef.value?.doc?.numPages ,拿到了总页码,至此,后面就很容易解决了

相关推荐
江拥羡橙13 小时前
Vue和React怎么选?全面比对
前端·vue.js·react.js
千码君201613 小时前
React Native:快速熟悉react 语法和企业级开发
javascript·react native·react.js·vite·hook
暮之沧蓝15 小时前
Vue总结
前端·javascript·vue.js
木易 士心16 小时前
Promise深度解析:前端异步编程的核心
前端·javascript
excel16 小时前
深入解析 Vue 3 源码:computed 的底层实现原理
前端·javascript·vue.js
zero13_小葵司16 小时前
在Vue项目中构建后端配置的动态路由及权限控制体系
前端·javascript·vue.js
GISer_Jing16 小时前
前端框架篇——Vue&React篇
前端·javascript
子兮曰16 小时前
WebSocket 连接:实现实时双向通信的前端技术
前端·javascript·websocket
zhangfeng113318 小时前
R 导出 PDF 时中文不显示 不依赖 showtext** 的最简方案(用 extrafont 把系统 TTF 真正灌进 PDF 内核)
开发语言·r语言·pdf·生物信息