JavaScriptVUE-全技术栈

vue实现文件下载、导出、前端多种方式实现文件下载

2021-08-29  本文已影响0人  爱学习的小仙女早睡早起

前端开发中,经常遇到文件下载的功能。这里对常见的文件下载方式做一些总结。

前端下载通常分为两种情形,一种是后端直接给一个文件地址,通过浏览器打开就可以下载,另外一种则需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL,实现下载。

一、后端直接返回文件路径进行下载

1、普通文件地址

情况1、直接下载 - 针对一些浏览器无法识别的文件格式

针对一些浏览器无法识别的文件格式(如pdf、xls、ppt)。可以直接在地址栏上输入URL即可触发浏览器的下载功能。

* 地址栏输入文件URL
* window.location.href = URL
* window.open(URL)

该方式将下载逻辑放在后端处理,后端给出固定的url,前端使用window.location.herf下载
路径可以是相对路径也可以是绝对路径

情况2、直接下载 (使用a标签download属性)

直接下载仅支持使用的浏览器无法识别的文件。如果是浏览器支持的文件格式(如:html、jpg、png、mp4、mp3)等。则不会触发文件下载,而是被浏览器直接触发解析展示。

针对这种情况,我们可以使用a标签的download属性,可以设置成文件的文件名。

<a  :href="scope.row.vPath" :download="scope.row.vName" class="downloadBtn">
      <el-button type="text">{{ $t("message.work.Download") }}</el-button>
</a>

2、OSS存储方式的文件地址

这种方式的文件地址被访问时,访问文件路径默认是下载还是预览跟后端设置的服务器配置有关。
如果访问oss地址的文件只能预览,那么这种文件要下载的解决方式:



举个例子:
在阿里云 oss 通过链接下载文件 而不是 直接打开链接文件 在页面中显示
通过 a 标签下载 oss 中的文件,需要在连接的后面添加 response-content-type=application/octet-stream 的参数 就可以直接下载了

<a href="http://oss.com.cn?response-content-type=application/octet-stream" target="_blank" download="" ></a>

二、通过后端接口返回流,前端对流进行文件预览 or 文件下载

通过接口的方式,前端首先要将接口的返回头设置为blob方式,然后解析二进制流

具体实现步骤:

1、axios 设置响应头 responseType: 'blob',
export function downloadExcelApi(data) {
  return request({
    url: prefix + `/member/download/template/?tenantCode=${data.tenantCode}`,
    method: 'get',
    responseType: 'blob',  // 这里相应的要在request接收
    data
  });
}

这里可以在axios拦截器中设置d1响应头,可以设置 延长超时时间、加载动画,例如:

const service = axios.create({
  baseURL: config.BASE_API,  //
  timeout: 30000 // 请求超时
});

service.interceptors.request.use(
  (config) => {
     var xtoken = localStorage.getItem('loginToken');
      if (xtoken != null) {
        config.headers['X-User'] = xtoken;
        config.headers['System'] = 'M';
        config.headers['crmversion'] = 'V1.0.0';
        config.headers['channel'] = 'PC';
        config.headers['Content-Type'] = 'application/json';
      }
      if (config.responseType === 'blob') {
          config.timeout = 60000;
          loadingInstance = Loading.service({
              lock: true,
              text: 'Loading',
              spinner: 'el-icon-loading',
              background: 'rgba(0, 0, 0, 0.7)'
          });
       }

   //  ....................
})


service.interceptors.response.use( 
 (response) => {
     if (response.config.responseType === 'blob') {
        // 下载时直接返回blob
        loadingInstance && loadingInstance.close();
        return response.data;
      }

     // ................
})



解析二进制流,下载和预览是两种不同的处理:

处理1:请求后的二进制流转为下载文件

// 根据路径下载文件流
    fileDown(row) {
      console.log('根据路径下载文件流', this.url(row.signDocumentPath) , row.documentName)
      const params={
        filePath: this.url(row.signDocumentPath),
      }
      API_Audit.downloadFile(params).then((res)=>{
          const url = window.URL.createObjectURL(new Blob([res]))
          const name = `${row.documentName}`
          const link = document.createElement('a')
          link.style.display = 'none'
          link.href = url
          link.setAttribute('download', name)
          document.body.appendChild(link)
          link.click()
      })
    },

      const res = await this.$api.user.downloadExcelApi({ tenantCode: tenantInfo.code })
      const url = window.URL.createObjectURL(new Blob([res]))
      const name = '用户导入模板.xlsx'
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', name)
      document.body.appendChild(link)
      link.click()

处理2:请求后的blob转为文件预览

const blob = new Blob([res], { type: 'application/pdf;chartset=UTF-8' })
const r = new FileReader();
r.readAsText(blob);
const url = window.URL.createObjectURL(blob)
window.open(url);

后台返回的二进制数据文件流格式如图:

image.jpeg

参考这个样子

PK����}�S�_rels/.rels���J�1��_%̽�m��iڋ�������?�&����ooЃ�l�B���|��I��ɏ�R�9�XV5(
�]�Z�����=�,�����@`�n�/4�����1���@'���ζ#���H�t�N�������-�U]������L�s���-A�1�$��Q�p�ޘ��`K�3�%��4��G��OAf�O&@ϻ�~]����e�c��MB��[Ē@Iz��nf�,'����Gў��
~S/����:da��+�PO��ѷ�|�PK�{<�$���PK����}�S�[Content_Types].xml�T�n�0�����*6�PU��C������\{C,���P��n�TJ%*��Ǚٙ�(�h�v�ZA�&��
��U�U�����6{�oY�Qz-m��0��d<�m"�F}nX���Ȫ�'3��<!mHN"m�\D��r��z0��*x��5��l<z�V.-V���t�d��(��J�����w�<�-�ܙ������5�lOChf����~Os/�K2���-��Q��Z:��Ыj�uLDLh`�s*�>KG���SB� i~��W-*$8ʰ'��wZ����qօzN���H�;t��N&Я��M��cm����s�����P�s:#}�pȪ����ʝ4�P�����!,.��;������EY�{��g6��PK�G��R�
�PK����}�S�docProps/app.xml��AN�0�E����uR!�"���B���k�LZK�m�CT8��X q�6p�@��'UK
�������F��US��|���4�'��Q��f������N��/�u�QC �    9]"�������0�c�'����X���U���[u݀A6I���+�SB9r�@�N�Z�ohiU��.�7.�    ~�\���x��,f��������a����,��A�����ZO����N(����Ĝ��ki��m�׵��������]\�ٶ�ˡu���H{C��F��z�p���pV��������g������_|�M?���w�/PK��q�P��"�PK����}�S�docProps/core.xml���N�0�E�%�>���TV��A]Q � �;�~m-�A�!�SX����Nhø@��������r�Wm���K�+�g�%���Ro+tӬ��J|`Z��h��6hY��Rn�\9c��   >���)��څ`)ƞ�@1�E����8�B<�-��?�-���9V��`����ڑ��H�G�}t���C�
t�8�r��hv   �^��(j@�E����g��g^�D�q�����\���oE0�a��6x�Q�C���j��G�h��]-������M�d|�3\ù�v�����:���[��0��n:5Dm
�[5�X��*    ;�u_[w��A�]m2(�|�i?c{�1�gܟgD�����`pA�=1h���h��J���L�y�=�).��VT�+\O�,݅���s����l�꩔�4��������j��V��PK��()�����PK�����}�S{<�$����_rels/.relsPK�����}�SG��R�
��*�[Content_Types].xmlPK�����}�S�q�P��"����docProps/app.xmlPK�����}�SU�~�7�3����docProps/core.xmlPK�����}�S�E6��������docProps/custom.xmlPK�����}�S7l]��������xl/sharedStrings.xmlPK�����}�S�g�OYwO
.   xl/styles.xmlPK�����}�Se4��������xl/theme/theme1.xmlPK�����}�S�a!p�������xl/workbook.xmlPK�����}�S���!����h�xl/_rels/workbook.xml.relsPK�����}�S�()��������xl/worksheets/sheet1.xmlPK������Y�
上一篇 下一篇

猜你喜欢

热点阅读