笔记记录

杂记

前端导出带样式的Excel,导入Excel (二)

npm install xlsx-style  没有验证,应该差不多

npm install js-xlsx  亲自验证


import引入报错,提示fs模块错误,修改node_modules中package.json,参考xlsx加入下面代码

"browser": {
    "buffer": false,
    "crypto": false,
    "stream": false,
    "process": false,
    "fs": false
  },

使用XLSX.writeFile直接导出报错,可以使用XLSX.write 配合   file-saver 使用

import XLSX from 'js-xlsx';
import * as FileSaver from 'file-saver';


exportExcel = (headers, data, fileName = 'excel.xlsx') => {
    const head = headers
    .map((item, i) => Object.assign({}, { key: item.key, title: item.title, position: String.fromCharCode(65 + i) + 2 }))
    .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { key: next.key, v: next.title } }), {});

    const excelData = data
    .map((item, i) => headers.map((key, j) => Object.assign({}, { content: item[key.key], position: String.fromCharCode(65 + j) + (i + 3) })))
    // 对刚才的结果进行降维处理(二维数组变成一维数组)
    .reduce((prev, next) => prev.concat(next))
    // 转换成 worksheet 需要的结构
    .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { v: next.content } }), {});

    // 合并 headers 和 data
    const title = { A1: { v: '1' }, B1: { v: '2' }, C1: { v: '3' } };
    const output = Object.assign({}, title, head, excelData);
    // 获取所有单元格的位置
    const outputPos = Object.keys(output);
    // 计算出范围 ,["A1",..., "H2"]
    const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;

    const merges = [
      {// 合并[A1~C1]
        s: {
          c: 0,
          r: 0,
        },
        e: {
          c: 2,
          r: 0,
        }
      }
    ];

    output['A2'].s = {
      numFmt: 'General',
      font: {
        sz: '30',
        color: {
          theme: '1'
        },
        name: 'Calibri'
      },
      border: {
        left: {
          style: 'thin',
          color: {
            rgb: 'FFFFAA00'
          }
        },
        top: {
          style: 'thin',
          color: {
            rgb: 'FFFFAA00'
          }
        },
        right: {
          style: 'thin',
          color: {
            rgb: 'FFFFAA00'
          }
        },
        bottom: {
          style: 'thin',
          color: {
            rgb: 'FFFFAA00'
          }
        }
      }
    };

    output['A1'] = {
      v: 'Arial',
      s: {
        font: {
          name: 'Arial',
          sz: 24,
          color: {
            theme: '5'
          }
        }
      },
      t: 's'
    };

    // 构建 workbook 对象
    const wb = {
      SheetNames: ['mySheet'],
      Sheets: {
        mySheet: Object.assign(
          {},
          output,
          {
            '!ref': ref,
            '!merges': merges,
            '!cols': [{ wpx: 245 }, { wpx: 100 }, { wpx: 200 }, { wpx: 80 }, { wpx: 150 }, { wpx: 100 }, { wpx: 300 }, { wpx: 300 }],
          },
        ),
      },
    };

    // 导出 Excel
    this.saveAsExcelFile(XLSX.write(wb, { type: 'buffer' }), fileName);
  }

  saveAsExcelFile = (buffer: any, fileName: string) => {
    const data: Blob = new Blob([buffer], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'
    });
    FileSaver.saveAs(data, fileName);
  }
  

  
  
 const columns = [{
  title: 'Name',
  dataIndex: 'name',
  key: 'name'
}, {
  title: 'Age',
  dataIndex: 'age',
  key: 'age'
}, {
  title: 'Address',
  dataIndex: 'address',
  key: 'address'
}];

const tableData = [];
for (let i = 0; i < 46; i += 1) {
  tableData.push({
    key: i,
    name: `Edward King ${i}`,
    age: 32,
    address: `London, Park Lane no. ${i}`,
  });
}  
  
<Button type="primary" size={size} onClick={() => { this.exportExcel(columns, tableData, '人员名单.xlsx'); }}>导出Excel</Button>


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-BlogPHP 1.5.2 Zero

Copyright Your WebSite.Some Rights Reserved.