前端使用xlsx-js-style导出Excel文件并修饰单元格样式

前端 0

xlsx-js-style

      • 安装
      • 引入
      • 需要导出的数据源
      • 将数据源转成需要的二维数组
      • 定义 Excel 表头
      • 将定义好的表头添加到 body 中
      • 将二维数组转成 sheet
      • !merges 设置单元格合并
      • !cols 设置列宽
      • !rows 设置行高
      • 创建虚拟的 workbook
      • 向 workbook 中添加 sheet
      • 导出 workbook
      • 完整示例
      • 效果图
      • 总结

安装

导出 excel 较常见的 js 库是之一是 xlsx,xlsx 算是基础版本,不能对单元格进行样式(对齐方式、文字颜色、背景颜色等)的修饰,如果需要修饰单元格,可使用 xlsx-js-style

npm install xlsx-js-style

引入

import XLSXS from 'xlsx-js-style';

需要导出的数据源

// 一般我们拿到的是从接口中请求到的对象数组,在使用是需要转成二维数组,下面有介绍const data = [  { name: '商品01', mb_num: 50, mb_sum: 5000, pc_num: 30, pc_sum: 3000, total_num: 80, total_sum: 8000 },  { name: '商品02', mb_num: 50, mb_sum: 5000, pc_num: 30, pc_sum: 3000, total_num: 80, total_sum: 8000 },  { name: '商品03', mb_num: 50, mb_sum: 5000, pc_num: 30, pc_sum: 3000, total_num: 80, total_sum: 8000 },]

将数据源转成需要的二维数组

const body = data.map(x => ([x.name, x.mb_num, x.mb_sum, x.pc_num, x.pc_sum, x.total_num, x.total_sum]))// 转换后的数据为一个二维数组[  ['商品01', 50, 5000, 30, 3000, 80, 8000]  ['商品02', 50, 5000, 30, 3000, 80, 8000]  ['商品03', 50, 5000, 30, 3000, 80, 8000]]

定义 Excel 表头

/*    定义表头,每一行即是一个数组,数组中的元素即是一个个单元格内容。    如果单元格不需要样式,那么每个元素类型为字符串即可。如:['一月(2022年01月)'],     如果单元格需要样式,那么数组中的元素就需要为一个个对象,在此对象中定义单元格的样式等等。*/    const header = [      // 第一行,需要样式,则数组中元素为对象,进行定义样式。      [        {          v: '一月(2023年01月)',          t: 's',          s: {            // font 字体属性            font: {              bold: true,              sz: 14,              name: '宋体',            },            // alignment 对齐方式            alignment: {              vertical: 'center', // 垂直居中              horizontal: 'center', // 水平居中            },            // border 边框属性            border: {              top: { style: 'thin' },              bottom: { style: 'thin' },              left: { style: 'thin' },              right: { style: 'thin' }            },            // fill 颜色填充属性            fill: {              fgColor: { rgb: '87CEEB' },            },          },        },      ],      ['商品名称', '手机客户端', '', '电脑客户端', '', '总计', ''],      ['', '销售数量', '销售金额', '销售数量', '销售金额', '销售数量', '销售金额']    ]

将定义好的表头添加到 body 中

body.unshift(...header);

将二维数组转成 sheet

// 这里我们举例是用 aoa_to_sheet ,所以是需要将数据源转成一个二维数组const sheet = XLSXS.utils.aoa_to_sheet(body);// aoa_to_sheet  	是将【一个二维数组】转化成 sheet// json_to_sheet 	是将【由对象组成的数组】转化成sheet// table_to_sheet  	是将【table的dom】直接转成sheet

!merges 设置单元格合并

如果需要设置单元格合并,则定义好merges ,添加到 sheet 中。

merges 为一个对象数组,每个对象设定了单元格合并的规则。

{ s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }, 即为一个规则,s:开始位置, e:结束位置, r:行, c:列

const merges = [  { s: { r: 0, c: 0 }, e: { r: 0, c: 6 } },  { s: { r: 1, c: 1 }, e: { r: 1, c: 2 } },  { s: { r: 1, c: 3 }, e: { r: 1, c: 4 } },  { s: { r: 1, c: 5 }, e: { r: 1, c: 6 } },  { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },]sheet['!merges'] = merges; // 添加到sheet中

!cols 设置列宽

cols 为一个对象数组,依次表示每一列的宽度。

const cols = [    { wch: 10 },    { wch: 10 },     { wch: 10 },    { wch: 10 },    { wch: 10 },    { wch: 10 },     { wch: 10 }];sheet['!cols'] = cols; // 添加到sheet中

!rows 设置行高

rows 为一个对象数组,依次表示每一行的高度

const rows = [    { hpx: 20 },     { hpx: 16 },    { hpx: 18 }]sheet['!rows'] = rows; // 添加到sheet中

创建虚拟的 workbook

Excel整个表格可称为 workbook。里面的每张表分别是 sheet

const workbook = xlsx.utils.book_new();

向 workbook 中添加 sheet

XLSXS.utils.book_append_sheet(workbook, sheet, 'sheet名称');// 一个 workbook 允许添加多个 sheet,即可以同时创建多个表// xlsx.utils.book_append_sheet(workbook, sheet2, 'sheet名称2');

导出 workbook

// 注意:定义导出 excel 的名称时需要加上后缀 .xlsxxlsx.writeFile(workbook, 'excel名称.xlsx');

完整示例

import XLSXS from 'xlsx-js-style';......// 需要导出的数据源const data = [  { name: '商品01', mb_num: 50, mb_sum: 5000, pc_num: 30, pc_sum: 3000, total_num: 80, total_sum: 8000 },  { name: '商品02', mb_num: 50, mb_sum: 5000, pc_num: 30, pc_sum: 3000, total_num: 80, total_sum: 8000 },  { name: '商品03', mb_num: 50, mb_sum: 5000, pc_num: 30, pc_sum: 3000, total_num: 80, total_sum: 8000 },]// 将数据源转成我们需要的二维数组const body = data.map(x => ([x.name, x.mb_num, x.mb_sum, x.pc_num, x.pc_sum, x.total_num, x.total_sum]))/* 定义表头    定义表头,每一行即是一个数组,数组中的元素即是一个个单元格内容。    如果单元格不需要样式,那么每个元素类型为字符串即可。如:['一月(2022年01月)'],     如果单元格需要样式,那么数组中的元素就需要为一个个对象,在此对象中定义单元格的样式等等。    这里只针对第一行进行举例:*/const header = [  [    {      v: '一月(2023年01月)',      t: 's',      s: {        // font 字体属性        font: {          bold: true,          sz: 14,          name: '宋体',        },        // alignment 对齐方式        alignment: {          vertical: 'center', // 垂直居中          horizontal: 'center', // 水平居中        },        // fill 颜色填充属性        fill: {          fgColor: { rgb: '87CEEB' },        },      },    },  ],  ['商品名称', '手机客户端', '', '电脑客户端', '', '总计', ''],  ['', '销售数量', '销售金额', '销售数量', '销售金额', '销售数量', '销售金额']]body.unshift(...header);// 将定义好的表头添加到 body 中const sheet = xlsx.utils.aoa_to_sheet(body);// aoa_to_sheet 将二维数组转成 sheet// 设置合并单元格const merges = [  { s: { r: 0, c: 0 }, e: { r: 0, c: 6 } },  { s: { r: 1, c: 1 }, e: { r: 1, c: 2 } },  { s: { r: 1, c: 3 }, e: { r: 1, c: 4 } },  { s: { r: 1, c: 5 }, e: { r: 1, c: 6 } },  { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },]sheet['!merges'] = merges; // 将merges添加到sheet中// 设置列宽const cols = [ { wch: 10 },{ wch: 10 },{ wch: 10 },{ wch: 10 },{ wch: 10 },{ wch: 10 },{ wch: 10 } ];sheet['!cols'] = cols; // 将cols添加到sheet中// const rows = [ { hpx: 20 },{ hpx: 16 },{ hpx: 18 }]sheet['!rows'] = rows; // 将rows添加到sheet中,设置行高const workbook = XLSXS.utils.book_new();// 创建虚拟的 workbookXLSXS.utils.book_append_sheet(workbook, sheet, 'sheet名称'); // 向 workbook 中添加 sheetXLSXS.writeFile(workbook, 'excel名称.xlsx'); // 导出 workbook// 注意:定义导出 excel 的名称时需要加上后缀 .xlsx

效果图

在这里插入图片描述

总结

  • 创建虚拟的 workbook将数组转成 sheet向workbook中添加sheet导出workbook,这四个步骤是必要的。
  • 设置合并单元格设置列宽设置行高是可选的,根据需求进行添加。
  • 如果添加样式需要 border 则需要在被合并的单元格位置进行占位。

也许您对下面的内容还感兴趣: