关于javascript:前端导出组件

30次阅读

共计 6322 个字符,预计需要花费 16 分钟才能阅读完成。

<template>
  <div>
    <Modal
      v-model="modal.isShow"
      :title="options.title?options.title:' 信息导出 '":mask-closable="false"
    >
      <h4 slot="header">{{options.title?options.title:'信息导出'}}</h4>
      <div v-if="getData" center> 暂无数据导出 </div>
      <Row style="margin-bottom:10px;" v-if="!getData">
        <Row style="padding:5px;" v-for="(exportItem,index) in exportArr" :key="index">
          <Col span="20">
            <Progress :percent="exportItem.percent"></Progress>
          </Col>
          <Col span="4">
            <Button
              type="primary"
              size="small"
              style="float:right"
              :disabled="exportItem.percent == 100 ? false : true"
              @click="_export(exportItem.export)"
            > 确认导出 </Button>
          </Col>
        </Row>
      </Row>
      <div slot="footer"></div>
    </Modal>
  </div>
</template>
<script>
import XLSX from "xlsx";
import "xlsx/dist/xlsx.full.min.js";
import saveAs from "file-saver/FileSaver.min.js";
import filters from "../filter";
import moment from "moment";

export default {data() {
    return {
      modal: {isShow: false,},
      getData: false,
      limitNumber: 30000, // 单个 excel 下限数据量
      totalCount: 0,
      exportArr: [],
      changeObj: {},
      provinceList: [],};
  },
  methods: {show(flag) {
      this.modal.isShow = flag;
      this.totalCount = 0;
      this.exportArr = [];
      this.changeObj = {};
      if (flag) {this.startExport();
      }
    },

    startExport() {
      let _this = this;
      this.options.columns.forEach((item) => {if (item.filter) {this.changeObj[item.prop] = item.filter;
        }
      });
      let params = this.options.params;
      params.pageIndex = 1;
      params.pageSize = 500;
      this.getData = false;
      this.$http.get(`api/${this.options.api}`, {params}).then((res) => {if (res.body.status === "SUCCEED" || !!res.body.status) {if (res.body.totalCount < 1) {
            this.getData = true;
            return;
          }
          this.getData = false;
          this.totalCount = res.body.totalCount;
          let pageNum = Math.ceil(this.totalCount / params.pageSize);
          let excelNum = Math.ceil(this.totalCount / this.limitNumber);
          for (let i = 0; i < excelNum; i++) {
            this.exportArr.push({export: [],
              percent: 0,
            });
          }
          let datas = res.body.datas || res.body.data;
          if (!!this.options.special) {datas.forEach((item, index) => {item = { ...item, ...item[this.options.special] };
              this.$set(datas, index, item);
            });
          }
          // 增加额定数据
          if (!!this.options.addData) {datas.forEach((item, index) => {item = {...this.options.addData,...item}
              this.$set(datas, index, item);
            });
          }

          datas.forEach((item) => {for (let key in this.changeObj) {if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){item[key]+='';
                // item[key] = filters[this.changeObj[key]](item[key]);
              }
              if (!!item[key]) {item[key] = filters[this.changeObj[key]](item[key]);
              }
            }
            if (!!this.options.otherFunction) {this.options.otherFunction(item);
            }
          });

          this.exportArr[0].export.push(...datas);
          if (pageNum === 1) {this.exportArr[0].percent = 100;
            // this._export(datas);
          } else {
            params.pageIndex = 2;
            if (excelNum == 1) {
              // 一个 Excel 表
              this.circleGetSingExc(params);
            } else {
              // 多个 Excel 表
              this.circleGet(params);
            }
          }
        }
      });
    },

    /* 循环下载 单个 Excel 表 */
    circleGetSingExc(params) {this.$http.get(`api/${this.options.api}`, {params}).then((res) => {if (res.body.status === "SUCCEED" || !!res.body.status) {
          let datas = res.body.datas || res.body.data;
          if (!!this.options.special) {datas.forEach((item, index) => {item = { ...item, ...item[this.options.special] };
              this.$set(datas, index, item);
            });
          }

          datas.forEach((item) => {for (let key in this.changeObj) {if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){item[key]+='';
              }
              if (!!item[key]) {item[key] = filters[this.changeObj[key]](item[key]);
              }
            }
            if (!!this.options.otherFunction) {this.options.otherFunction(item);
            }
          });
          this.exportArr[0].export.push(...datas);
          if (params.pageIndex * params.pageSize < this.totalCount) {this.exportArr[0].percent = Math.ceil(((params.pageIndex * params.pageSize) / this.totalCount) * 100
            );
            params.pageIndex++;
            this.circleGetSingExc(params);
          } else {this.exportArr[0].percent = 100;
          }
        }
      });
    },

    /* 循环下载 多个 Excel 表 */
    circleGet(params, single) {
      let _index = Math.ceil((params.pageIndex * params.pageSize) / this.limitNumber
      ); // 以后第几个 EXCEL 表格
      this.$http.get(`api/${this.options.api}`, {params}).then((res) => {if (res.body.status === "SUCCEED" || !!res.body.status) {
          let datas = res.body.datas || res.body.data;

          if (!!this.options.special) {datas.forEach((item, index) => {item = { ...item, ...item[this.options.special] };
              this.$set(datas, index, item);
            });
          }
          datas.forEach((item) => {for (let key in this.changeObj) {if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){item[key]+='';
              }
              if (!!item[key]) {item[key] = filters[this.changeObj[key]](item[key]);
              }
            }
            if (!!this.options.otherFunction) {this.options.otherFunction(item);
            }
          });
          this.exportArr[_index - 1].export.push(...datas);
          if (params.pageIndex * params.pageSize < this.totalCount) {this.exportArr[_index - 1].percent = Math.ceil((this.exportArr[_index - 1].export.length / this.limitNumber) *
                100
            );
            params.pageIndex++;
            this.circleGet(params);
          } else {this.exportArr[_index - 1].percent = 100;
          }
        }
      });
    },

    // 省份
    getProvinceList() {
      let _this = this;
      _this.$http
        .get("api/findProvincesAndCities", {params: { keywords: "中国", level: "COUNTRY", sub: 2},
        })
        .then(function (res) {if (res.body.status && res.body.data[0]) {_this.provinceList = res.body.data[0].divisions;
          }
        });
    },

    // 性别切换
    genderChange(gender) {if (gender === "M") {return "男";} else if (gender === "F") {return "女";}
    },

    // 省份切换
    searchByprovinceCode: function (provinceCode) {for (let i in this.provinceList) {if (this.provinceList[i].id == provinceCode) {return this.provinceList[i].name;
        }
      }
    },

    // 城市切换
    searchByCityCode: function (cityCode) {for (let i in this.provinceList) {for (let j in this.provinceList[i].divisions) {if (this.provinceList[i].divisions[j].id == cityCode) {return this.provinceList[i].divisions[j].name;
          }
        }
      }
    },

    _export(data) {console.log(data)
      let _this = this;
      let returnArr = [];
      let columns = this.options.columns;
      let tempArr = [];
      columns.forEach((item) => tempArr.push(item.label));
      returnArr.push(tempArr);
      data.forEach((item) => {item.provinceCode = _this.searchByprovinceCode(item.provinceCode);
        item.cityCode = _this.searchByCityCode(item.cityCode);
        item.gender = _this.genderChange(item.gender);
        // item.saleDate = moment(item.saleDate).format("YYYY-MM-DD");
        item.serviceDate = item.serviceDate;
        let keyArr = [];
        columns.forEach((col) => keyArr.push(item[col.prop]));
        returnArr.push(keyArr);
      });
      const wopts = {bookType: "xlsx", bookSST: false, type: "binary"};
      const wb = {SheetNames: ["Sheet1"], Sheets: {}, Props: {} };
      let objName = this.options.name ? this.options.name : "车主信息列表";
      wb.Sheets["Sheet1"] = XLSX.utils.aoa_to_sheet(returnArr);
      saveAs.saveAs(new Blob([s2ab(XLSX.write(wb, wopts))], {type: "application/octet-stream",}),
        objName + "." + (wopts.bookType == "biff2" ? "xls" : wopts.bookType)
      );
      function s2ab(s) {if (typeof ArrayBuffer !== "undefined") {var buf = new ArrayBuffer(s.length);
          var view = new Uint8Array(buf);
          for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
          return buf;
        } else {var buf = new Array(s.length);
          for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff;
          return buf;
        }
      }
    },
  },

  created() {this.getProvinceList();
  },

  props: ["options"],
};
</script>

正文完
 0