美文网首页
vue数据导出

vue数据导出

作者: Halomisszhang | 来源:发表于2020-04-14 23:13 被阅读0次

需求

每个订单页面导出数据【订单数据量较大】

思考

先罗列集中导出的方式

1. 纯前端实现导出(数据量小)

1. 使用插件xlsx,xlsx-style(修改样式)
2. 下载Export2Excel,Blob文件,不过如果没有用到转流的问题可以不需要下载blob.js
3. 重要代码
//这里是我下载的源码之后自行根据需求改动的,设置样式或者做一些业务改动参照下面的代码
export function export_json_to_excel (th, jsonData, defaultTitle, mode) {
  /* original data */
  var data = jsonData
  data.unshift(th)
  var ws_name = 'SheetJS'
  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data)
  /*设置worksheet每列的最大宽度*/
  const colWidth = data.map((row) =>
    row.map((val) => {
      /*先判断是否为null/undefined*/
      if (val == null) {
        return { wch: 10 }
      } /*再判断是否为中文*/
      else if (val.toString().charCodeAt(0) > 255) {
        return { wch: val.toString().length * 2 }
      } else {
        return { wch: val.toString().length }
      }
    })
  )
  /*以第一行为初始值*/
  let result = colWidth[0]
  for (let i = 1; i < colWidth.length; i++) {
    for (let j = 0; j < colWidth[i].length; j++) {
      if (result[j]['wch'] < colWidth[i][j]['wch']) {
        result[j]['wch'] = colWidth[i][j]['wch']
      }
    }
  }
  ws['!cols'] = result

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name)
  wb.Sheets[ws_name] = ws

  var dataInfo = wb.Sheets[wb.SheetNames[0]];

  // 设置样式以及具体的值
  let style = {
    font: {
      color: { rgb: 'ff0000' },
      bold: true,
    },
    alignment: {
      horizontal: "center",
      vertical: "center"
    },
    fill: {
      fgColor: { rgb: "e2efda" },
    }
  }
  let bac = {
    fill: {
      fgColor: { rgb: "e2efda" },
    }
  }
//这里给指定的列设置背景颜色
  let arr1 = ["A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "I1", "J1", "K1", "L1", "M1", "N1", "O1", "P1", "Q1", "R1", "S1", "T1", "U1", "V1", "W1", "X1", "Y1", "Z1", "AA1", "AB1", "AC1", "AD1", "AE1"];
  let arr = ["B1", "F1", "I1", "J1", "K1"];
  if (mode === 'spec') {
    for (let i = 0; i < arr1.length; i++) {
      dataInfo[arr1[i]].s = bac
    }

    for (let i = 0; i < arr.length; i++) {
      dataInfo[arr[i]].s = style
    }
  }

  var wbout = XLSX.write(wb, {
    bookType: 'xls',
    bookSST: false,
    type: 'binary'
  })
  var title = defaultTitle || 'excel-list'
  saveAs(
    new Blob([s2ab(wbout)], { type: 'application/octet-stream' }),
    title + '.xls'
  )
}
4. 使用
let excel = await import("@/js/Export2Excel");
      let tHeader, tFields, tFileName;

      if (from === "statistic") {
        tHeader = ["病案号", "院区", "病房", "科室", "调阅医生", "调阅时间", "调阅类型"];
        tFields = ["mrid", "hospitalName", "consultRoomName", "departmentName", "doctorName", "opdViewTime", "opdViewTypeName"];
        tFileName = "调阅统计";
      } else {
        tHeader = ["病案号", "患者姓名", "就诊院区", "就诊科室", "就诊医生", "就诊时间", "调阅状态", "调阅时间"];
        tFields = ["mrid", "patientName", "hosDistrictName", "departmentName", "doctorName", "consultTime", "readEMR", "opdViewTime"];
        tFileName = "挂号明细";
      }

      const data = this.datasource.list.map(v => tFields.map(j => {
        if (j === "readEMR") return v[j] ? "已调阅" : "未调阅";
        else return v[j];
      }));

      excel.export_json_to_excel(tHeader, data, tFileName);// 表头名称,数据字段,导出表名称

2. 纯前端实现导出(数据量大),建议订单还是需要后端做导出,数据量超过几万条。

let str =
          "订单号,病案号,患者姓名,申请人,申请时间,是否继续复印,复印项目,订单金额,接收方式,订单状态\n";
      this.$store.state.resList[3].list.map(v => {
        str += `${v.orderNumber}\t,${v.mrid}\t,${v.patientName}\t,${v.applyPeople}\t,${v.applyTime}\t,${v.isPathologyName}\t,${v.printReceptionMridList}\t,${v.orderAmount}\t,${v.mailName}\t,${v.status},\n`;
      });
      let blob = new Blob([str], { type: "text/plain;charset=utf-8" });
      blob = new Blob([String.fromCharCode(0xfeff), blob], {
        type: blob.type
      });
      let url = window.URL.createObjectURL(blob);
      let link = document.createElement("a");
      link.href = url;
      link.download = "全部订单.xls";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

3. 配合后端做数据导出

 // var that = this;
      this.$axios({
        method: "get",
        url: `${window.config.server}/Order/ExprotOrderList`,
        params: {
          fileName: "待邮寄",
          PickupCode: "",
          ReceptionType: this.hdwaydata,
          OrderIds: orderid,
          Status: "3",
          EndTime: this.AplTime.endTime,
          BeginTime: this.AplTime.startTime
        },
        responseType: "blob",
        // transformResponse: [
        //   function(data) {
        //     console.log(data);
        //     var reader = new FileReader();
        //     reader.readAsText(data, "GBK");
        //     reader.onload = function(e) {
        //       var music = JSON.parse(reader.result);
        //       console.log(music);
        //       that.data = music;
        //     };
        //     return data;
        //   }
        // ],
        // headers: {
        //   "X-Requested-With": "XMLHttpRequest",
        //   "Content-Type": "application/x-www-form-urlencoded"
        // }
      }).then(res => {
        console.log(res);
        const link = document.createElement("a");
        let blob = new Blob([res.data], {
          type: "application/vnd.ms-excel; charset=UTF-8"
        });
        link.style.display = "none";
        link.href = URL.createObjectURL(blob);
        link.download = res.headers["content-disposition"];
        link.setAttribute("download", "待邮寄" + ".xls");
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });

4. 可能存在问题

4.1 不同的请求可实现不同的结果(原声请求,axios)

最简单的办法:

// 直接用后端的链接
window.location = `${
        window.config.server
      }/Order/ExprotOrderList?EndTime=${
        this.AplTime.endTime === null ? "" : this.AplTime.endTime
      }&BeginTime=${
        this.AplTime.startTime === null ? "" : this.AplTime.startTime
      }&Status=3&ReceptionType=&ISMail=1&OrderIds=${orderid}&fileName=待邮寄`;

4.2 可能引起的乱码问题

一般情况下按照第3个代码是没有乱码的,乱码出现原因有两点1. 转换blob没成功,有其他请求在干扰(mock)2. 不是utf-8格式
解决办法: 1. 可以去掉引入mock 2. 用原生请求,不用axios

let xhr = new XMLHttpRequest();
      xhr.open(
        "get",
        `${window.config.server}/Order/ExprotOrderList?EndTime=${
          this.AplTime.endTime === null ? "" : this.AplTime.endTime
        }&BeginTime=${
          this.AplTime.startTime === null ? "" : this.AplTime.startTime
        }&Status=3&ReceptionType=&ISMail=1&OrderIds=${orderid}&fileName=待邮寄`,
        true
      );
      xhr.send();
      xhr.onreadystatechange = function(res) {
        // 判断服务器是否正确响应
        console.log(xhr);
        xhr.responseType = "blob";
        if (xhr.readyState === 4 && xhr.status === 200) {
          const link = document.createElement("a");
          let blob = new Blob([xhr.responseText], {
            type: "application/vnd.ms-excel; charset=UTF-8"
          });
          link.style.display = "none";
          link.href = URL.createObjectURL(blob);
          // link.download = xhr.headers["content-disposition"];
          link.setAttribute("download", "待邮寄");
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
      };

因为加入mock的话,即使不使用mock.mock,也会拦截请求

5. 综上所述:经过查看源码,怎么封装一个属于自己的导出的简单实现,实现更轻量。

6.拓展复习:

6.1 xhr请求的封装

6.2 http请求相关的知识

相关文章

网友评论

      本文标题:vue数据导出

      本文链接:https://www.haomeiwen.com/subject/jsffvhtx.html