zoukankan      html  css  js  c++  java
  • Antd将Table导出为Excel

    Antd将Table导出为Excel


    在最近的项目中,需要把表格中的数据导出给财务进行统计,网上很多一键导出的按钮都没用。经过东拼西凑,最终搞定了导出,自己封装了组件。

    import { File } from 'better-xlsx';
    import { saveAs } from 'file-saver';
    
    function ExportExcel(column, dataSource, fileName = 'example') {
      // 新建工作谱
      const file = new File();
      // 新建表
      let sheet = file.addSheet('sheet-test');
      // 获取表头行数
      let depth = getDepth(column);
      // 获取表头的列数
      let columnNum = getColumns(column);
      // 新建表头行数
      let rowArr = [];
      for (let k = 0; k < depth; k++) {
        rowArr.push(sheet.addRow());
      }
      // 根据列数填充单元格
      rowArr.map(ele => {
        for (let j = 0; j < columnNum; j++) {
          let cell = ele.addCell();
          cell.value = j;
        }
      });
      // 初始化表头
      init(column, 0, 0);
      // 按顺序展平column
      let columnLineArr = [];
      columnLine(column);
      // 根据column,将dataSource里面的数据排序,并且转化为二维数组
      let dataSourceArr = [];
      dataSource.map(ele => {
        let dataTemp = [];
        columnLineArr.map(item => {
          dataTemp.push({
            [item.dataIndex]: ele[item.dataIndex],
            value: ele[item.dataIndex],
          });
        });
        dataSourceArr.push(dataTemp);
      });
      // debugger;
      // 绘画表格数据
      dataSourceArr.forEach((item, index) => {
        //根据数据,创建对应个数的行
        let row = sheet.addRow();
        row.setHeightCM(0.8);
        //创建对应个数的单元格
        item.map(ele => {
          let cell = row.addCell();
          if (ele.hasOwnProperty('num')) {
            cell.value = index + 1;
          } else {
            cell.value = ele.value;
          }
          cell.style.align.v = 'center';
          cell.style.align.h = 'center';
        });
      });
      //设置每列的宽度
      for (let i = 0; i < 4; i++) {
        sheet.col(i).width = 20;
      }
      file.saveAs('blob').then(function(content) {
        saveAs(content, fileName + '.xlsx');
      });
    
      // 按顺序展平column
      function columnLine(column) {
        column.map(ele => {
          if (ele.children === undefined || ele.children.length === 0) {
            columnLineArr.push(ele);
          } else {
            columnLine(ele.children);
          }
        });
      }
      // 初始化表头
      function init(column, rowIndex, columnIndex) {
        column.map((item) => {
          let hCell = sheet.cell(rowIndex, columnIndex);
          // 如果没有子元素, 撑满列
          if (item.title === '操作') {
            hCell.value = '';
            return null;
          } else if (item.children === undefined || item.children.length === 0) {
            // 第一行加一个单元格
            hCell.value = item.title;
            hCell.vMerge = depth - rowIndex - 1;
            hCell.style.align.h = 'center';
            hCell.style.align.v = 'center';
            columnIndex++;
            // rowIndex++
          } else {
            let childrenNum = 0;
            function getColumns(arr) {
              arr.map(ele => {
                if (ele.children) {
                  getColumns(ele.children);
                } else {
                  childrenNum++;
                }
              });
            }
            getColumns(item.children);
            hCell.hMerge = childrenNum - 1;
            hCell.value = item.title;
            hCell.style.align.h = 'center';
            hCell.style.align.v = 'center';
            let rowCopy = rowIndex;
            rowCopy++;
            init(item.children, rowCopy, columnIndex);
            // 下次单元格起点
            columnIndex = columnIndex + childrenNum;
          }
        });
      }
      // 获取表头rows
      function getDepth(arr) {
        const eleDepths = [];
        arr.forEach(ele => {
          let depth = 0;
          if (Array.isArray(ele.children)) {
            depth = getDepth(ele.children);
          }
          eleDepths.push(depth);
        });
        return 1 + max(eleDepths);
      }
    
      function max(arr) {
        return arr.reduce((accu, curr) => {
          if (curr > accu) return curr;
          return accu;
        });
      }
      // 计算表头列数
      function getColumns(arr) {
        let columnNum = 0;
        arr.map(ele => {
          if (ele.children) {
            getColumns(ele.children);
          } else {
            columnNum++;
          }
        });
        return columnNum;
      }
    }
    
    export default ExportExcel;
    
    

    注意,这个函数传入的column参数格式是这样的:

    [
          {
            title: '序号',
            dataIndex: 'id'
          },
          {
            title: '日期',
            dataIndex: 'createTime',
            render: val => <span>{moment(val).format('YYYY-MM-DD HH:mm:ss')}</span>,
          },
          {
            title: '运动',
            dataIndex: 'steps',
            render: val => `${val}步`
          },
          {
            title: '睡眠',
            dataIndex: 'sleep',
            render: val => `${val}分钟`
          },
          {
            title: '心率',
            dataIndex: 'heartRate',
            render: val => `${val}次/分钟`
          },
          {
            title: '血糖',
            dataIndex: 'bloodGlucose',
            render: val => `${val}mol/L`
          },
          {
            title: '血压',
            dataIndex: 'bloodPressure',
            render: val => `${val}mmHG`,
          },
          {
            title: '体重',
            dataIndex: 'weight',
            render: val => `${val}KG`
          },
          {
            title: '身高',
            dataIndex: 'height',
            render: val => `${val}cm`
          },
          {
            title: '年龄',
            dataIndex: 'age',
            render: val => `${val}岁`
          }
        ]
    
  • 相关阅读:
    stax(和dom4j功能一样,这个是基于流的一种处理方式)
    JAXB(xml和对象的转换)
    wsdl理解
    webservice心得
    ZT 分智网博客 – 职场、面试技巧、职业规划
    discern concern fifth sixth
    ZT I Believe I Can Fly(我相信我能飞)
    ZT 理解class.forName()
    ZT 第9章 Framework的启动过程
    android 智能指针的学习先看邓凡平的书扫盲 再看前面两片博客提升
  • 原文地址:https://www.cnblogs.com/tian874540961/p/11923294.html
Copyright © 2011-2022 走看看