JS导出复杂多级表头的Excel

使用方式
1、安装依赖

npm install xlsx-js-style

2、复制代码文件exportExcel.js至工程
https://github.com/EnthuDai/export-excel-in-one-line

3、在引入excel.js后调用

Excel.export(columns, dataSource, '导出文件名')

4、代码demo
在这里插入图片描述

5、效果
在这里插入图片描述
适用范围
对于使用vue ant-design 组件库中table组件的场景,可直接将table的 columns 和 data-source、 导出文件名称 作为参数传入export方法,调用即可导出相同格式的excel文件。

Excel.export(this.demoColumn, this.demoData, '测试数据')

对于其他场景,需要对数据格式适配至ant-design table相同格式,具体为:

表头格式需符合以下条件
标题的key为 title
数据字段key为 dataIndex
子表头key为 children
如:

	[
        {title:'类别',dataIndex:'type'},
        {title:'总计',children:[
            {title:'销量',children:[
                {title:'今天', dataIndex:'today'},
                {title:'昨天', dataIndex:'yesterday'}]
            }
          ]
        },
        {title:'趋势',children:[
            {title:'上涨率',dataIndex:'raise'},
            {title:'上涨金额', dataIndex:'raiseAmount'}
          ]
        }
      ]

2.数据格式格式需符合以下条件
数据项key为表头格式中对应项 dataIndex 的值
子数据key为children
如:

	[
        {type:'笔', today:100, yesterday: 200, raise:'20%', raiseAmount:20, children:[
            {type:'毛笔',today:50, yesterday: 100, raise:'20%', raiseAmount:10},
            {type:'钢笔',today:50, yesterday: 100, raise:'20%', raiseAmount:10}
          ]},
        {type:'墨', today:100, yesterday: 200, raise:'20%', raiseAmount:20},
        {type:'纸', today:100, yesterday: 200, raise:'20%', raiseAmount:20},
        {type:'砚', today:100, yesterday: 200, raise:'20%', raiseAmount:20},
    ]

实现原理
原理基本参考了使用xlsx.js导出有复杂表头的excel这篇文章,其该文合并表头方法doMerges 存在bug,实测中会出现问题。所以该组件中使用了树中递归处理的算法计算合并项,解决问题的同时也提高了代码的简洁程度。
实现过程:

根据表头描述 columns 生成全为空的表头二维数组,二维数组行数为 columns 中子项树的最深深度,列数为 columns 中所有子项树的叶子节点数之和。分别通过 columnHeight(columns)、columnWidth(columns)方法递归求得。

在这里插入图片描述
2.将 columns 中title填入对应位置,也是循环+递归实现。此间分两种情况
1.无children的叶子节点

{title:'类别',dataIndex:'type'}

在数组左上角第一项填入 title,合并单元格时需要向下合并所有单元格,记录下合并的起始和终点项的偏移量 {s:{r:0,c:0},e:{r:0,c:2}}

在这里插入图片描述

2.有children的节点
 {
     title:'总计',children:[
       {title:'销量',children:[
           {title:'今天', dataIndex:'today'},
           {title:'昨天', dataIndex:'yesterday'}]
    }
  ]
}

在这里插入图片描述

在二维数组剩余的部分(红框区域)中,左上角第一项填入title,并记录下横向合并的起终点偏移量,横向合并的数目为该项的children数组中所有节点的叶节点总数。
然后对 向下的剩余部分(绿框区域)递归操作。
3.最终得到表头区域数据
在这里插入图片描述
合并excel单元格的数据描述
在这里插入图片描述

  1. 其余部分就是填入数据调api即可,可以参考使用xlsx.js导出有复杂表头的excel这篇文章,此处空白太小所以不再赘述
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java导出Excel多级表头可以使用Apache POI库,递归创建表头行,设置单元格样式和合并单元格,实现复杂多级表头。 首先,创建一个方法用于递归创建表头,并返回表头行的最终行数。方法参数为表头数据、Excel Sheet对象、起始行、最后一列、当前级别。在方法内部,根据当前级别创建表头行并设置样式,根据下一级别的数据递归创建子表头行,最后合并单元格并返回创建的最终行数。 其次,调用上述方法创建所有表头行后,根据数据填充Excel表格并设置单元格样式。最后将数据写入Excel文件并保存即可。 示例代码: private static int createHeader(List<List<String>> headerData, Sheet sheet, int startRow, int lastCol, int level) { int endRow = startRow; Row row = sheet.createRow(startRow); row.setHeightInPoints(25f); CellStyle style = sheet.getWorkbook().createCellStyle(); Font font = sheet.getWorkbook().createFont(); font.setBold(true); style.setFont(font); for (int i = 0; i < headerData.size(); i++) { Cell cell = row.createCell(i); cell.setCellValue(headerData.get(i).get(0)); cell.setCellStyle(style); if (headerData.get(i).size() > 1) { int rowspan = createHeader(headerData.get(i).subList(1, headerData.get(i).size()), sheet, startRow + 1, lastCol, level + 1); sheet.addMergedRegion(new CellRangeAddress(startRow, startRow + rowspan - 1, i, i)); } else { endRow = Math.max(endRow, startRow); } } if (level == 0) { for (int i = headerData.size(); i <= lastCol; i++) { Cell cell = row.createCell(i); cell.setCellStyle(style); } } return endRow - startRow + 1; } public static void writeExcel(List<List<String>> headerData, List<List<Object>> data, String filePath) throws IOException { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet(); int lastCol = headerData.get(0).size() - 1; int lastRow = createHeader(headerData, sheet, 0, lastCol, 0); CellStyle style = sheet.getWorkbook().createCellStyle(); style.setBorderBottom(BorderStyle.THIN); style.setBorderLeft(BorderStyle.THIN); style.setBorderRight(BorderStyle.THIN); style.setBorderTop(BorderStyle.THIN); for (int i = 0; i < data.size(); i++) { Row row = sheet.createRow(lastRow + i); List<Object> rowData = data.get(i); for (int j = 0; j <= lastCol; j++) { Cell cell = row.createCell(j); cell.setCellValue(rowData.get(j).toString()); cell.setCellStyle(style); } } FileOutputStream outputStream = new FileOutputStream(filePath); workbook.write(outputStream); outputStream.close(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值