浙政钉H5端pdf预览功能 安卓端 踩坑记录

需求:

客户在浙政钉需要文件预览功能(包括PDF和Word)。原本都是使用浙政钉提供的API,但是新版本已经不在提供文件预览API了。组员和浙政钉工作人员沟通后对方表示需要我们自行实现。

问题:

一般预览PDF都会使用PDF.js这个库,在本地实现完成后,上传到浙政钉,ios没什么问题,一看安卓,好家伙,直接报错了。后来排除发现基本上机型自带的浏览器都可以预览,但是浙政钉里内置的浏览器版本太低了…所以在这里卡了很久
换了好多的组件库,但是基本上的组件都是基于pdfjs来实现文件预览。

项目相关:vue3 + vite 2.9.9

解决:

下载 pdfjs-dist ,注意下载依赖时要下载 ^2.5.207 这个版本,这个版本提供ES5的依赖,下面是实现的代码demo

onMounted(async () => {
  pdfjs = await import('pdfjs-dist/es5/build/pdf')
  pdfjsWorker = await import('pdfjs-dist/es5/build/pdf.worker.entry')
  // 注意这里引入时 需要引入es5中的js 来兼容低版本的安卓浏览器
  pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker
  await resolvePdf()
})
const resolvePdf = () => {
  var getPreviewUrl =
    Tool.apiurl() + '/api/dev/download/getPreview?resource=' + encodeURI('web/fileatt/' + filepath)
  axios({
    url: getPreviewUrl,
    method: 'post',
    responseType: 'blob'
  }).then((res) => {
  // 根据接口返回文件流来实现预览
    let blob = new Blob([res.data], { type: 'application/pdf' }) // 设置类型
    blobToArrayBuffer(blob).then((arrayBuffer) => {
      const loadingTask = pdfjs.getDocument(arrayBuffer)
      loadingTask.promise.then((pdf) => {
        state.pdfCtx = pdf
        state.pageNum = pdf.numPages
        nextTick(() => {
          renderPdf(1, 1)
        })
      })
    })
  })
}
const renderPdf = (num, scale) => {
  state.pdfCtx.getPage(num).then((page) => {
    // const canvas: any = document.getElementById(`pdf-canvas-${num}`);
    const canvas = document.getElementById('pdf-canvas')
    const ctx = canvas.getContext('2d')
    // test
    let dpr = window.devicePixelRatio || 1
    let bsr =
      ctx.webkitBackingStorePixelRatio ||
      ctx.mozBackingStorePixelRatio ||
      ctx.msBackingStorePixelRatio ||
      ctx.oBackingStorePixelRatio ||
      ctx.backingStorePixelRatio ||
      1
    let ratio = dpr / bsr
    let scalNum = scale || 1
    let viewport = page.getViewport({
      scale: screen.availWidth / page.getViewport({ scale: 1 }).width
    })

    canvas.width = viewport.width * ratio * scalNum
    canvas.height = viewport.height * ratio * scalNum

    state.width = viewport.width * ratio * scalNum
    state.height = viewport.height * ratio * scalNum

    canvas.style.width = viewport.width * scalNum + 'px'
    canvas.style.height = viewport.height * scalNum + 'px'
    let renderContext = {
      //这里transform比较关键 保证根据手势缩放后的清晰度和等比例
      transform: [ratio * scalNum, 0, 0, ratio * scalNum, 0, 0],
      canvasContext: ctx,
      viewport: viewport
    }
  })
}

原作者在实现上写的更详细,但是本文主要是在原文章基础上再加了pdfjs 低版本的更新
参考代码:
https://blog.csdn.net/qq_44848480/article/details/135583649

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值