java导出Excel文件的步骤全纪录

网友投稿 374 2023-01-22


java导出Excel文件的步骤全纪录

一、背景

当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统、银行系统)。或者是:我们已经习惯用Excel打印。这样在我们实际的开发中,很多时候需要实现导入、导出Excel的应用。

最近在java上做了一个EXCEL的导出功能,写了一个通用类,在这里分享分享,该类支持多sheet,且无需手动进行复杂的类型转换,只需提供三个参数即可:

1、fileName

excel文件名

2、HasMap> data

具体的数据,每个List代表一张表的数据,?表示可为任意的自定义对象

3、LinkedHashMap headers

Stirng代表sheet名。每个String[][]代表一个sheet的定义,举个例子如下:

String[][] header = {

{"field1","参数1"}

,{"field2","参数2"}

,{"field3","参数3"}

}

其中的field1,field2,field3为对象中的属性名,参数1,参数2,参数3为列名,实际上这个指定了列的名称和这个列用到数据对象的哪个属性。

二、怎么用

以一个例子来说明怎么用,假设有两个类A和B定义如下:

public class A{

private String name;

private String address;

}

public class B{

private int id;

private double sum;

private String cat;

}

现在我们通过查询数据库获得了A和B的两个列表:

List dataA = .....;

List dataB = .....;

我们将这两个导出到excel中,首先需要定义sheet:

String[][] sheetA = {

{"name","姓名"}

,{"address","住址"}

}

String[][] sheetB = {

{"id","ID"}

,{"sum","余额"}

,{"cat","猫的名字"}

}

然后将数据汇总构造一个ExcelUtil:

String fileName = "测试Excel";

HashMap> data = new HashMap<>();

//ASheet为表名,后面headers里的key要跟这里一致

data.put("ASheet",dataA);

data.put("BSheet",dataB);

LinkedHashMap headers = new LinkedHashMap<>();

headers.put("ASheet",sheetA);

headers.put("BSheet",sheetB);

ExcelUtil excelUtil = new ExcelUtil(fileNamhttp://e,data,headers);

//获取表格对象

HSSFWorkbook workbook = excelUtil.createExcel();

//这里内置了一个写到response的方法(判断浏览器类型设置合适的参数),如果想写到文件也是类似的

workbook.writeToResponse(workbook,request,response);

当然通常数据是通过数据库查询的,这里为了演示方便没有从数据库查找。

三、实现原理

这里简单说明下实现过程,从调用createExcel()这里开始

1、遍历headers创建sheet

public HSSFWorkbook createExcel() throws Exception {

try {

HSSFWorkbook workbook = new HSSFWorkbook();

//遍历headers创建表格

for (String key : headers.keySet()) {

this.createSheet(workbook, key, headers.get(key), this.data.get(key));

}

return workbook;

} catch (Exception e) {

log.error("创建表格失败:{}", e.getMessage());

throw e;

}

}

将workbook,sheet名,表头数据,行数据传入crateSheet方法中创建sheet。

2、创建表头

表头也就是一个表格的第一行,通常用来对列进行说明

HSSFSheet sheet = workbook.createSheet(sheetName);

// 列数

int cellNum = header.length;

// 单元行,单元格

HSSFRow row;

HSSFCell cell;

// 表头单元格样式

HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);

// 设置表头

row = sheet.createRow(0);

for (int i = 0; i < cellNum; i++) {

cell = row.createCell(i);

cell.setCellStyle(columnTopStyle);

String str = header[i][1];

cell.setCellValue(str);

// 设置列宽为表头的文字宽度+6个半角符号宽度

sheet.setColumnWidth(i, (str.getBytes("utf-8").length + 6) * 256);

}

3、插入行数据

这里是最重要的部分,首先通过数据的类对象获取它的反射属性Field类,然后将属性名和Field做一个hash映射,避免循环查找,提高插入速度,接着通过一个switch语句,根据属性类别设值,主要代码如下:

/**

* 设置单元格,根据fieldName获取对应的Field类,使用反射得到值

*

* @param cell 单元格实例

* @param obj 存有属性的对象实例

* @param fieldMap 属性名与Field的映射

* @param fieldName 属性名

*/

private void setCell(HSSFCell cell, Object obj, Map fieldMap, String fieldName) throws Exception {

//获取该属性的Field对象

Field field = fieldMap.get(fieldName);

//通过反射获取属性的值,由于不能确定该值的类型,用下面的判断语句进行合适的转型

Object value = field.get(obj);

if (value == null) {

cell.setCellValue("");

} else {

switch (field.getGenericType().getTypeName()) {

case "java.lang.String":

cell.setCellValue((String) value);

break;

case "java.lang.Integer":

case "int":

cell.setCellValue((int) value);

break;

case "java.lang.Double":

case "double":

cell.setCellValue((double) value);

break;

case "java.util.Date":

cell.setCellValue(this.dateFormat.format((Date) value));

break;

default:

cell.setCellValue(obj.toString());

}

}

}

完整代码可以到github上查看下载,这里就不列出来了。

github地址:点击跳转

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:webuploader+springmvc实现图片上传功能
下一篇:Java线程等待用法实例分析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~