React项目中,如何把数据导出到Excel文件

写在前面

无论是做项目还是自己学习过程中,我们可能会遇到导出数据的需求,比如导出数据到Excel文件。

为了方便大家的学习和开发,这里介绍一种导出数据到Excel文件的方法。

方法简介

我在这里使用 「exceljs」 包来导出数据,如果你有兴趣,可以阅读一下他们的文档:

英文文档:https://github.com/exceljs/exceljs/blob/HEAD/README.md

中文文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md

图片

导出后的数据如下:

图片

方法代码详解

1.  引入依赖包和需要导出的数据

首先我们需要引入依赖包,定义导出Excel文件需要的数据,这里提供一个对象数组即可,后面的代码会从该数组中提取需要的数据。实例代码如下:

import ExcelJs from "exceljs";

const mockData = [
  {
    Name: "Allen",
    Gender: "Male",
    Height: "175"
  },
  {
    Name: "Tom",
    Gender: "Male",
    Height: "180"
  },
  {
    Name: "Jane",
    Gender: "Female",
    Height: "170"
  }
];

2.  使用依赖包定义一个对象,后期使用该对象设置参数和导出数据

// 获取sheet对象,设置当前sheet的样式
// showGridLines: false 表示不显示表格边框
let workbook = new ExcelJs.Workbook();
let sheetName = "Allen_test.xlsx";
let sheet = workbook.addWorksheet(sheetName, {
 views: [{ showGridLines: false }]
});
// 每一个sheet对象对应一个Excel文件中的表,如果你想子一个Excel中显示多个表,可以定义多个sheet
// let sheet2 = workbook.addWorksheet("Second sheet", { views: [{ showGridLines: false }] });

3.  获取表格数据的header信息

我们在制作Excel表格的时候,一般都需要给每一列设置一个表头,用来说明这一列展示的是什么信息,我们之前只定义了表格数据(前面的对象数组),这里根据表格数据,获取对应的表头信息:

let columnArr = [];
for (let i in mockData[0]) {
  let tempObj = { name: "" };
  tempObj.name = i;
  columnArr.push(tempObj);
}

4.  设置表格顶部的信息及样式

在表格中,顶部可以展示该表格的标题,说明,注意事项等信息。如上图中的“This is the header text” 和“As of: 07/09/2021”。

我们可以使用如下代码进行设置顶部信息,设置过程中,可以定义一个起始单元格,然后从该单元格开始,根据columns和rows数组,以此向右和向下的单元格中进行绘制。

sheet.addTable({
  name: `Header`,
  ref: "A1", // 头部信息从A1单元格开始显示
  headerRow: true,
  totalsRow: false,
  style: {
    theme: "",
    showRowStripes: false,
    showFirstColumn: true,
    width: 200
  },
  columns: [{ name: "This is the header text" }],  // 如果传递多个数组元素,会以此在B1, C3...单元格中绘制
  rows: [[`As of: 07/09/2021`]]   // 如果传递多个数组元素,会以此在A2, A3...单元格中绘制
});

5.  设置表格的主要数据部分

顶部数据绘制完成之后,下面继续绘制主题的数据部分,这是最关键的,我们导出Excel文件就是为了导出这些数据嘛。

// 设置表格的主要数据部分
let headerName = "RequestsList";
sheet.addTable({
  name: headerName,
  ref: "A5", // 主要数据从A5单元格开始
  headerRow: true,
  totalsRow: false,
  style: {
    theme: "TableStyleMedium2",
    showRowStripes: false,
    width: 200
  },
  columns: columnArr ? columnArr : [{ name: "" }],  // 把之前定义的表头数据传递进来
  rows: mockData.map((e) => {
    let arr = [];
    for (let i in e) {
      arr.push(e[i]);
    }
    return arr;
  })
});

6.  美化数据部分的样式

现在数据可以正常导出了,但是导出的数据样式是比较丑的,可以参考一下代码,优化这部分的样式。对代码不明白可以阅读注释。

// 设置单元格的文字样式
sheet.getCell("A1").font = { size: 20, bold: true };

// 设置每一列的宽度
sheet.columns = sheet.columns.map((e) => {
  const expr = e.values[5];
  switch (expr) {
    case "Name":
      return { width: 50 };
    case "Gender":
      return { width: 40 };
    case "Height":
      return { width: 30 };
    default:
      return { width: 20 };
  }
});

const table = sheet.getTable(headerName);
for (let i = 0; i < table.table.columns.length; i++) {
  // 表格主体数据是从A5开始绘制的,一共有三列。这里是获取A5到,B5,C5单元格,定义表格的头部样式
  sheet.getCell(`${String.fromCharCode(65 + i)}5`).font = { size: 12 };
  sheet.getCell(`${String.fromCharCode(65 + i)}5`).fill = {
    type: "pattern",
    pattern: "solid",
    fgColor: { argb: "c5d9f1" }
  };

  // 获取表格数据部分,定义其样式
  for (let j = 0; j < table.table.rows.length; j++) {
    let rowCell = sheet.getCell(`${String.fromCharCode(65 + i)}${j + 6}`);
    rowCell.alignment = { wrapText: true };
    rowCell.border = {
      bottom: {
        style: "thin",
        color: { argb: "a6a6a6" }
      }
    };
  }
}
table.commit();

7.  将数据导出Excel,自动下载到本地

现在Excel已经绘制完成了,我们需要把数据导出到本地,代码如下,非常简单:

// 定义下载文件的方法
const writeFile = (fileName, content) => {
  const link = document.createElement("a");
  const blob = new Blob([content], {
    type: "application/vnd.ms-excel;charset=utf-8;"
  });
  link.download = fileName;
  link.href = URL.createObjectURL(blob);
  link.click();
};

// 表格的数据绘制完成,定义下载方法,将数据导出到Excel文件
workbook.xlsx.writeBuffer().then((buffer) => {
  writeFile(sheetName, buffer);
});

代码总览

到这里就完成了导出Excel的所有工作,这里列出所有代码,方便你进一步参考。

如果你想设置表格的其他属性,可以查看官方文档,我认为是非常详细的。

英文文档:https://github.com/exceljs/exceljs/blob/HEAD/README.md

中文文档:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md

import React from "react";
import ExcelJs from "exceljs";

const mockData = [
  {
    Name: "Allen",
    Gender: "Male",
    Height: "175"
  },
  {
    Name: "Tom",
    Gender: "Male",
    Height: "180"
  },
  {
    Name: "Jane",
    Gender: "Female",
    Height: "170"
  }
];

const ExportToExcel = () => {
  const exportToExcel = (data) => {
    let sheetName = "Allen_test.xlsx";
    let headerName = "RequestsList";

    // 获取sheet对象,设置当前sheet的样式
    // showGridLines: false 表示不显示表格边框
    let workbook = new ExcelJs.Workbook();
    let sheet = workbook.addWorksheet(sheetName, {
      views: [{ showGridLines: false }]
    });
    // let sheet2 = workbook.addWorksheet("Second sheet", { views: [{ showGridLines: false }] });

    // 获取每一列的header
    let columnArr = [];
    for (let i in data[0]) {
      let tempObj = { name: "" };
      tempObj.name = i;
      columnArr.push(tempObj);
    }

    // 设置表格的头部信息,可以用来设置标题,说明或者注意事项
    sheet.addTable({
      name: `Header`,
      ref: "A1", // 头部信息从A1单元格开始显示
      headerRow: true,
      totalsRow: false,
      style: {
        theme: "",
        showRowStripes: false,
        showFirstColumn: true,
        width: 200
      },
      columns: [{ name: "This is the header text" }, { name: "Hahaha" }],
      rows: [[`As of: 07/09/2021`], [`Allen`]]
    });

    // 设置表格的主要数据部分
    sheet.addTable({
      name: headerName,
      ref: "A5", // 主要数据从A5单元格开始
      headerRow: true,
      totalsRow: false,
      style: {
        theme: "TableStyleMedium2",
        showRowStripes: false,
        width: 200
      },
      columns: columnArr ? columnArr : [{ name: "" }],
      rows: data.map((e) => {
        let arr = [];
        for (let i in e) {
          arr.push(e[i]);
        }
        return arr;
      })
    });

    sheet.getCell("A1").font = { size: 20, bold: true }; // 设置单元格的文字样式

    // 设置每一列的宽度
    sheet.columns = sheet.columns.map((e) => {
      const expr = e.values[5];
      switch (expr) {
        case "Name":
          return { width: 50 };
        case "Gender":
          return { width: 40 };
        case "Height":
          return { width: 30 };
        default:
          return { width: 20 };
      }
    });

    const table = sheet.getTable(headerName);
    for (let i = 0; i < table.table.columns.length; i++) {
      // 表格主体数据是从A5开始绘制的,一共有三列。这里是获取A5到,B5,C5单元格,定义表格的头部样式
      sheet.getCell(`${String.fromCharCode(65 + i)}5`).font = { size: 12 };
      sheet.getCell(`${String.fromCharCode(65 + i)}5`).fill = {
        type: "pattern",
        pattern: "solid",
        fgColor: { argb: "c5d9f1" }
      };

      // 获取表格数据部分,定义其样式
      for (let j = 0; j < table.table.rows.length; j++) {
        let rowCell = sheet.getCell(`${String.fromCharCode(65 + i)}${j + 6}`);
        rowCell.alignment = { wrapText: true };
        rowCell.border = {
          bottom: {
            style: "thin",
            color: { argb: "a6a6a6" }
          }
        };
      }
    }
    table.commit();

    const writeFile = (fileName, content) => {
      const link = document.createElement("a");
      const blob = new Blob([content], {
        type: "application/vnd.ms-excel;charset=utf-8;"
      });
      link.download = fileName;
      link.href = URL.createObjectURL(blob);
      link.click();
    };

    // 表格的数据绘制完成,定义下载方法,将数据导出到Excel文件
    workbook.xlsx.writeBuffer().then((buffer) => {
      writeFile(sheetName, buffer);
    });
  };

  return (
    <button
      onClick={() => {
        exportToExcel(mockData);
      }}
    >
      Export to Excel
    </button>
  );
};

export default ExportToExcel;
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值