前端导出excel,前端纯数据导出excel

非常符合前端直接的使用

使用

先看看使用

表格数据

const tableData = [
  {
    "id": 1,
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "age": 28,
    "address": { "street": "123 Main St", "city": "Springfield", "state": "IL", "zip": "62701" }
  },
  {
    "id": 2,
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "age": 34,
    "address": { "street": "456 Elm St", "city": "Shelbyville", "state": "IL", "zip": "62565" }
  },
  {
    "id": 3,
    "firstName": "Bob",
    "lastName": "Johnson",
    "email": "bob.johnson@example.com",
    "age": 23,
    "address": { "street": "789 Oak St", "city": "Ogdenville", "state": "IL", "zip": "62075" }
  }
]

使用方法

// 导出方法
exportExcel(
    tableData, // 你的表格数据
    [
      {
        title: 'ID', // 表头
        wpx: 120, // 宽度
        render: row => row.id, // 你要渲染的数据
      },
      {
        title: '邮箱', // 表头
        render: row => row.email, // 你要渲染的数据
      },
      {
        title: '年龄',
        wpx: 120,
        render: row => (row.age < 18 ? '未成年' : '成年了'),
      },
      {
        title: '地址',
        wpx: 300,
        render: row => row.address.street + '/' + row.address.city,
      },
    ],
    '用户数据.xlsx' // 导出的表名
  )

封装

我们使用 xlsx 库的导出 Excel 功能

  1. 使用表格数据: tableData 作为数据源,你通过一个配置对象数组定义了如何渲染每一列。每个配置对象包括表头、宽度和渲染函数等信息。

  2. 渲染函数: 通过 render 函数,你可以对每一行的数据进行自定义渲染,例如年龄列的情况,你区分了未成年和成年人。

  3. 列宽度: 通过 wpx 属性,你可以为每一列设置特定的宽度。

  4. 动态导入: 你使用了动态导入 (import('xlsx').then(XLSX => {...})) 来导入 xlsx 库,这有助于代码分割和按需加载,提高了前端应用的性能。

  5. 文件名: 导出的文件名可以作为函数的参数传入,使其具有更好的灵活性。

安装xlsx

npm install xlsx -S

获取列名

通过 getColumnName来

function getColumnName(n) {
  let columnName = "";
  while (n > 0) {
    const index = (n - 1) % 26;
    columnName = String.fromCharCode(65 + index) + columnName;
    n = Math.floor((n - 1) / 26);
  }
  return columnName;
}

 getColumnName(1) // 返回 'A'
 getColumnName(27) // 返回 'AA'

获取文本的宽度,用来给列的,要不然会出现列没有宽度的情况

const getWordCh = (val) => {
  /* 先判断是否为null/undefined */
  // eslint-disable-next-line eqeqeq
  if (val == null) {
    return 10;
  } else if (val.toString().charCodeAt(0) > 255) {
    /* 再判断是否为中文 */
    return val.toString().length * 2;
  } else {
    return val.toString().length;
  }
};

导出封装

import("xlsx") 动态引入 xlsx

const exportExcel = (dataSource, columns, filename) => {
   
  import("xlsx").then((XLSX) => {
    const sheet = {};

    const defaultColumnCh = new Array(columns.length || 2);
    const cols = [];
    columns.forEach((item, index) => {
      const letter = getColumnName(index + 1);
      sheet[`${letter}1`] = { v: item.title };
      defaultColumnCh[index] = 0;
    });

    dataSource.forEach((item, rowIndex) => {
      columns.forEach((column, columIndex) => {
        // @ts-ignore next-line
        const value = column.render ? column.render(item) : item[column.field];
        const letter = getColumnName(columIndex + 1);
        sheet[letter + (rowIndex + 2)] = { v: value };

        defaultColumnCh[columIndex] = Math.max(
          defaultColumnCh[columIndex] || 0,
          getWordCh(value)
        );
      });
    });

    columns.forEach((item, index) => {
      // @ts-ignore next-line
      const { render, title, field, ...ret } = item;
      cols.push({
        wch: Math.max(defaultColumnCh[index] || 0, getWordCh(title)),
        ...ret,
      });
    });

    // 获取所有单元格的位置
    const outputPos = Object.keys(sheet);
    // 计算出范围 ,["A1",..., "H2"]
    const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;
    sheet["!cols"] = cols;
    sheet["!ref"] = ref;

    console.log(" sheet: ", sheet);
    // 导出 Excel
    XLSX.writeFileXLSX(
      {
        SheetNames: ["Sheet1"],
        Sheets: {
          Sheet1: sheet,
        },
      },
      filename
    );
  });
};

完整代码


/**
 * 获取列名
 @param {number}n 第几列,从1开始
@example
  getColumnName(1) // 返回 'A'
  getColumnName(27) // 返回 'AA'
 */
function getColumnName(n) {
  let columnName = "";
  while (n > 0) {
    const index = (n - 1) % 26;
    columnName = String.fromCharCode(65 + index) + columnName;
    n = Math.floor((n - 1) / 26);
  }
  return columnName;
}

const getWordCh = (val) => {
  /* 先判断是否为null/undefined */
  // eslint-disable-next-line eqeqeq
  if (val == null) {
    return 10;
  } else if (val.toString().charCodeAt(0) > 255) {
    /* 再判断是否为中文 */
    return val.toString().length * 2;
  } else {
    return val.toString().length;
  }
};

/**
 * 导出excel
 * @example
  exportExcel(
    tableData, // 你的表格数据
    [
      {
        title: 'ID', // 表头
        wpx: 120, // 宽度
        render: row => row.id, // 你要渲染的数据
      },
      {
        title: '邮箱', // 表头
        render: row => row.email, // 你要渲染的数据
      },
      {
        title: '年龄',
        wpx: 120,
        render: row => (row.age < 18 ? '未成年' : '成年了'),
      },
      {
        title: '地址',
        wpx: 300,
        render: row => row.address.street + '/' + row.address.city,
      },
    ],
    '用户数据.xlsx' // 导出的表名
  )
*/
export const exportExcel = (dataSource, columns, filename) => {
  import("xlsx").then((XLSX) => {
    const sheet = {};

    const defaultColumnCh = new Array(columns.length || 2);
    const cols = [];
    columns.forEach((item, index) => {
      const letter = getColumnName(index + 1);
      sheet[`${letter}1`] = { v: item.title };
      defaultColumnCh[index] = 0;
    });

    dataSource.forEach((item, rowIndex) => {
      columns.forEach((column, columIndex) => {
        // @ts-ignore next-line
        const value = column.render ? column.render(item) : item[column.field];
        const letter = getColumnName(columIndex + 1);
        sheet[letter + (rowIndex + 2)] = { v: value };

        defaultColumnCh[columIndex] = Math.max(
          defaultColumnCh[columIndex] || 0,
          getWordCh(value)
        );
      });
    });

    columns.forEach((item, index) => {
      // @ts-ignore next-line
      const { render, title, field, ...ret } = item;
      cols.push({
        wch: Math.max(defaultColumnCh[index] || 0, getWordCh(title)),
        ...ret,
      });
    });

    // 获取所有单元格的位置
    const outputPos = Object.keys(sheet);
    // 计算出范围 ,["A1",..., "H2"]
    const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;
    sheet["!cols"] = cols;
    sheet["!ref"] = ref;

    console.log(" sheet: ", sheet);
    // 导出 Excel
    XLSX.writeFileXLSX(
      {
        SheetNames: ["Sheet1"],
        Sheets: {
          Sheet1: sheet,
        },
      },
      filename
    );
  });
};


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值