解决前端导出excel文件,打开为乱码

前端开发中,导入和导出文件是比较常见的业务场景,常见的情况是:后端返回一个二进制的流文件,前端将其转化为excel文件即可。但是往往会出现转化后的excel文件内容位乱码的情况,本文中提供了两个解决方案:

方案一:用户自定义上传方法

    <el-upload
      :on-error="uploadError"
      :accept="accept"
      class="uploadContent"
      :action="uploadurl"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      multiple
      :limit="limit"
      ref="uploadComponent"
      :on-exceed="handleExceed"
      :auto-upload="autoupload"
      :file-list="fileList"
      :data="uploadData"
      :on-change="fileStateChange"
      :http-request="handleupload"
    >
      <span v-if="showtip">添加附件</span>
      <el-button class="btnColor2" size="small" type="primary">添加附件 </el-button>
    </el-upload>

代码解读:上述代码采用了element-ui的el-upload文件上传的组件。改组件有两种文件上传的方式:

        1.组件自带的上传方法,只需要给其设置action地址参数,即可完成上传,但是其弊端为无法在改组件的基础上设置后端相应的数据格式:responseType,或者是拿到后端响应的二进制流后将其转换为blob对象并为其设置responseType:'blob'无效的问题,从而导致导出的excl文件打开后为乱码的问题。

        2.:http-request自定义上传方法。改方法也是本次主要的上传方法,此处使用自定义方法上传的有点便是可自定义上传接口的参数,上代码:

       定义接口:

// 文件上传
export const userNameListUpload = (data, uploadurl) => axios.request({
  url: uploadurl,
  baseURL,
  data,
  method: 'post',
  contentType: 'application/json;charset=UTF-8',
  responseType: 'blob',
});

         

        上述代码引用接口:userNameListUpload,在该接口的axios部分需要设置一下参数:        

                contentType: 'application/json;charset=UTF-8',
                responseType: 'blob',

其含义是指定后端相应的数据类型为blob类型。

        :http-request自定义上传函数: 

    async handleupload(option) {
      const formData = new FormData();
      if (option.data) {
        Object.keys(option.data).forEach((key) => {
          formData.append(key, option.data[key]);
        });
      }
      formData.append(option.filename, option.file, option.file.name);
      const loading = this.$loading({ text: '上传中...' });
      const res = await userNameListUpload(formData, this.uploadurl);
      loading.close();
      if (res) {
        this.$emit('uploadComplete', res); // 展示导入结果
      }
    },

        前端在拿到后盾响应的数据后,只需将其转换为Blob对象,然后再以a标签的形式进行访问即可,上代码:

    // 展示失败明细
    falidDetail() {
      // 有Success的直接展示
      if (this.sendResponse.Success) {
        if (this.sendResponse.Success) {
          this.$message.success(this.sendResponse.Msg);
        } else {
          this.$message.error(this.sendResponse.Msg);
        }
      } else {
        //=========================进行流转换为excel表格的操作,并导出excel===============
        // 没有Success的直接展示ecxel表格
        const blob = new Blob([this.sendResponse]);
        const link = document.createElement('a');
        link.style.display = 'none';
        // setAttribute() 方法添加指定的属性,并为其赋指定的值。
        link.setAttribute('download', '错误信息.xlsx');
        link.href = window.URL.createObjectURL(blob);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        window.URL.revokeObjectURL(blob);
      }
    },

进行了这些设置后,即可正常导出excel文件了。

方案二:直接设置el-upload组件的headers树属性

el-upload组件提供了一个headers属性,可设置上传的请求头部::headers="headers"

  <el-upload
      :on-error="uploadError"
      :accept="accept"
      class="uploadContent"
      :headers="header"
      :action="uploadurl"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      multiple
      :limit="limit"
      ref="uploadComponent"
      :on-exceed="handleExceed"
      :auto-upload="autoupload"
      :file-list="fileList"
      :data="uploadData"
      :on-change="fileStateChange"
      :http-request="handleupload"
    >
      <span v-if="showtip">添加附件</span>
      <el-button class="btnColor2" size="small" type="primary">添加附件 </el-button>
    </el-upload>

给组件绑定一个headers属性,其值为对象header,属性值:responseType: 'blob'即可。

data(){
  return {
    header: { responseType: 'blob' },
  };
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值