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

 更新时间:2018年09月09日 10:37:23   作者:烦嚣的人  
这篇文章主要给大家介绍了关于java导出Excel文件的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、背景

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

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

1、fileName

excel文件名

2、HasMap<String,List<?>> data

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

3、LinkedHashMap<String,String[][]> 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<A> dataA = .....;
List<B> dataB = .....;

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

String[][] sheetA = {
 {"name","姓名"}
 ,{"address","住址"}
}
String[][] sheetB = {
 {"id","ID"}
 ,{"sum","余额"}
 ,{"cat","猫的名字"}
}

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

String fileName = "测试Excel";
HashMap<String,List<?>> data = new HashMap<>();
//ASheet为表名,后面headers里的key要跟这里一致
data.put("ASheet",dataA);
data.put("BSheet",dataB);
LinkedHashMap<String,String[][]> headers = new LinkedHashMap<>();
headers.put("ASheet",sheetA);
headers.put("BSheet",sheetB);
ExcelUtil excelUtil = new ExcelUtil(fileName,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<String, Field> 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地址:点击跳转

总结

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

相关文章

  • 熟悉maven:使java开发变得更高效

    熟悉maven:使java开发变得更高效

    在日常的开发过程中,maven是很常见的项目构建工具。maven可以极大的提高我们的开发效率,帮助我们简化开发过程中一些解决依赖和项目部署的相关问题,所以学习掌握maven的相关知识是非常有必要的
    2021-06-06
  • MyBatis-Plus3.x版本使用入门和踩过的坑

    MyBatis-Plus3.x版本使用入门和踩过的坑

    Mybatis-Plus是Mybatis的增强版,他只是在Mybatis的基础上增加了功能,且并未对原有功能进行任何的改动,本文给大家说一下MyBatis-Plus3.x版本使用入门和踩过的坑,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • java多线程编程之捕获子线程异常示例

    java多线程编程之捕获子线程异常示例

    java多线程程序中所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉。但是无法避免的是unchecked exception,也就是RuntimeException,当抛出异常时子线程会结束,但不会影响主线程
    2014-02-02
  • SpringMVC表单标签使用详解

    SpringMVC表单标签使用详解

    这篇文章主要为大家详细介绍了SpringMVC表单标签的使用方法,教大家如何用Spring封装的一系列表单标签
    2017-03-03
  • Java8中Lambda表达式使用和Stream API详解

    Java8中Lambda表达式使用和Stream API详解

    这篇文章主要给大家介绍了关于Java8中Lambda表达式使用和Stream API的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java8具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • java中读取配置文件中数据的具体方法

    java中读取配置文件中数据的具体方法

    java中读取配置文件中数据的具体方法,需要的朋友可以参考一下
    2013-06-06
  • java.sql.SQLException问题解决以及注意事项

    java.sql.SQLException问题解决以及注意事项

    这篇文章主要给大家介绍了关于java.sql.SQLException问题解决以及注意事项的相关资料,这个问题其实很好解决,文中通过图文将解决的办法介绍的很详细,需要的朋友可以参考下
    2023-07-07
  • 详解Mybatis-plus(MP)中CRUD操作保姆级笔记

    详解Mybatis-plus(MP)中CRUD操作保姆级笔记

    本文主要介绍了Mybatis-plus(MP)中CRUD操作保姆级笔记,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Java String初始化String域例题解析

    Java String初始化String域例题解析

    这篇文章主要介绍了Java String初始化String域例题解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • 解决Spring Security 用户帐号已被锁定问题

    解决Spring Security 用户帐号已被锁定问题

    这篇文章主要介绍了解决Spring Security 用户帐号已被锁定问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01

最新评论