将图片和PDF二进制文件流转化为可以查看的地址

分享一个将图片和PDF二进制文件流转化为可以查看的地址

需求

继上一次在表格中需要将树类型扁平化为数组之后,产品说为了更满足客户的适用性,需要将文件名称后缀为jpg、jpeg、png的文件点击能够查看图片,后缀为pdf的文件能够查看pdf(之前的需求是点击文件名称下载文件)。其实这个需求应该是很简单的,只要后端返回src能够查看的地址就可以;但是期望总是相反的,后端大哥不返,那么就只能自己来进行转换。
在这里插入图片描述

解决步骤

1、先为每一个列表数据做一个分类-----picture、pdf、other。

在这里插入图片描述

// 为资料分类--图片和pdf可以预览
this.dataList.map(item => {
          let arr = []
          arr = item.fileName.split('.') // 以.来进行分割
          let str = arr[arr.length - 1].toLocaleLowerCase() // 可能是大写的后缀
          switch (str) {
            case 'png':
              item.type = 'picture'
              break;
            case 'jpg':
              item.type = 'picture'
              break;
            case 'jpeg':
              item.type = 'picture'
              break;
            case 'pdf':
              item.type = 'pdf'
              break;
            default:
              item.type = 'other'
              break;
          }
        })

以fileName来做区分,因为考虑到文件名称可能有多个".“符号,所以就以”."来进行分割,取数组最后一个数据来进行区分。又因为可能文件后缀有大小写的情况,所以就统一处理为小写然后来进行判断。将数据进行处理后的结构为下图:多了一个type属性来进行判断
在这里插入图片描述

<span v-if="row.type == 'other'" @click="downFile(row)" class="filename">{{row.fileName  ? row.fileName : '--'}}</span>
<span v-else-if="row.type == 'picture'" @click="pictureView(row)" class="filename">{{row.fileName  ? row.fileName : '--'}}</span>
<span v-else @click="PDFView(row)" class="filename">{{row.fileName  ? row.fileName : '--'}}</span>

HTML的结构就可以根据type来进行区分渲染,这个地方其实可以做一个优化,写一行代码,用同一个方法,在方法里面在进行type判断即可。后面我也会进行优化,当然这不是重点啦。

2、每一行数据有type分类以后,就可以根据类比进行不同的功能展示了。

首先是图片的展示-----为了单独使用element-ui的图片预览功能,所以需要将预览功能的组件单独引入。

<!-- 查看图片 -->
<el-image-viewer v-if="dig.pictureView" :on-close="closeViewer" :url-list="[dig.picurl]" />
import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
components: { commonDialog, ElImageViewer },

然后就是点击图片文件名称下载文件流进行转码,转成可以查看的src。

// 查看图片
  async pictureView(row) {
    let res = await this.axios({
       method: "get",
       url: `/service-file-app/app/file/download-id?id=${row.fileId}`,
       interface: 1,
       responseType: "arraybuffer" //这个是获取流必传的不然获取格式不成功
    })
    if (res.data) {
     this.dig.picurl = 'data:image/jpeg;base64,' + this.arrayBufferToBase64(res.data) // 进行base64转码
     this.dig.pictureView = true
    } else {
    }
  },

// 关闭查看图片
  closeViewer() {
    this.dig.pictureView = false
  },

// 二进制流转码url
  arrayBufferToBase64(buffer) {
    let binary = ''
    let bytes = new Uint8Array(buffer)
    let len = bytes.byteLength
    for (let i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i])
    }
    return window.btoa(binary)
  },

效果图如下:
在这里插入图片描述
最后就是pdf的预览功能:

// 查看PDF
    async PDFView(row) {
      let res = await this.axios({
        method: "get",
        url: `/service-file-app/app/file/download-id?id=${row.fileId}`,
        interface: 1,
        responseType: "blob",
        headers: {
          "Content-Type": "application/pdf",
        },
      })
      if (res.data) {
        let blob = new Blob([res.data], {
          type: 'application/pdf;charset=utf-8'
        }); // 这一步也是必须的,否则打开页面是一堆乱码
        window.open(URL.createObjectURL(blob)) // 其实可以在页面内用object标签内嵌一个pdf浏览图出来,但是产品说直接打开新的页面好一点0.0
      } else {
      }
    },

效果图如下:
在这里插入图片描述

功能迭代会遇见很多问题,上线周有空我就会来分享的,我的方法可能不是最优解,还希望各位大佬能够提出更高效的解决办法一起交流,为我这个小菜鸡积累一点经验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值