一、项目结构 点我下载源码
项目结构,ExcelExpoter.java 是excel导出工具,ExcelImport.java是excel导入工具。ExcelHead.java注解标识在类成员变量上(指定在sheet中的排序、列名、列字体颜色、列宽度、数据格式化等),ExcelSheet.java注解标识在类上(指定sheet的名字)。
说明:
(1)支持导出.xls和.xlsx两种格式,根据导出的文件名自动选择,不需要显示指定。导出.xlsx格式时支持SXSSF兼容流式扩展导出海量数据,需要手动开启,否则默认使用XSSF。
(2)当导出文件名重名时,工具提供两种策略,策略一、以xxx.xls、xxx.xls(1)、xxx(2).xls格式重命名(默认自动重命名),策略二、覆写。
(3)工具内部采用了反射,为了灵活性考虑,并不是采用类的字段名和表列名映射,而是通过@ExcelHead(value=“姓名”,sort=1)中的sort字段与列相对应,sort=1表示对应sheet中的第二列,value值标识此列列名。没有被@ExcelHead注解标识的字段将不会被映射到excel中。
(4)一个list集合对应一张sheet,支持将多个list集合写入,这样会在一个工作簿中生成多张sheet。读也一样。
(5)poi读取xls格式速度比xlsx快很多,生成的xls文件相比体积也更大。xls每张sheet最多存约65000行数据,xlsx每张sheet可以达到100万行。
二、使用demo
1、写工作簿
List<Employee> employees = new ArrayList<>();//已经填充好数据
List<Department> departments = new ArrayList<>();//已经填充好数据
//demo1,将员工集合导出到xx.xls文件中,生成的sheet名称取自@ExcelSheet注解标识的值
new ExcelExporter(new File("F:/xx.xls")).list2Excel(employees, Employee.class).startWriteAndEndClose();
//demo2,将员工集合和部门集合同时导出到一个workbook中,支持链式编程
new ExcelExporter(new File("F:/xx.xlsx"),true)//重载构造函数,输入true,开启海量数据导出,速度会有显著提升的哦
.setHeadColor(ExcelHead.BLUE)//可选,设置表头字体为蓝色
.setFreezeHead(true)//可选,设置冻结表头,即向下滚动表格时第一行不动,这样看着方便
.setSavePolicy(ExcelExporter.CoverSave)//可选,设置覆写文件保存策略
.list2Excel(employees, Employee.class,"职工表1")//显示指定生成sheet的名为“职工表1”,工具将忽略@ExcelSheet注解标识的表名(这在多个sheet对应同一个bean类数据元时要显示指定,否则解析@ExcelSheet注解出来sheet名称将会重复)
.list2Excel(employees, Employee.class,"职工表2").
.list2Excel(departments, Department.class,"部门表").
.startWriteAndEndClose();//开始写入数据到文件,关闭工作簿,关闭流等操作,此步骤不可省略
2、读工作簿,支持指定表名或表的序号
//demo1 读取的工作簿只有一个sheet
ExcelImporter ei = new ExcelImporter(new File("F:/xx.xls"));
List<Employee> list = ei.excel2list(Employee.class, "职工表", 2);//指定表名读取sheet,这里的表名也可以为null,工具会自动去寻找@ExcelSheet值作为表名,若又找不到则以类名作为表名,否则报错,2,表示从第几行开始读取sheet,一般第一行是表头,从第2行开始读。等于1就是从第一行开始读。
ei.close();//关闭工作簿和流
//demo2 读取的工作簿有多个sheet
ExcelImporter ei = new ExcelImporter(new File("F:/xx.xlsx"));
List<Employee> list = ei.excel2list(Employee.class, 1, 2);//1标识读取workbook中第一个sheet,2标识从第2行开始读取sheet
List<Department> list2 = ei.excel2list(Department.class, 2, 2);//2标识读取workbook中第二个sheet,2标识从第2行开始读取sheet
ei.close();
3、被注解装饰的javabean
/**
* 注意:sort 排序字段很重要,从0开始,必须有,一定不要错。没有被注解标识的字段不会被反射读写数据
* 支持的数据类型有:int(Integer)、String、util.Date、Calendar、BigDecimal、double(Double)、boolean(Boolean)、float(Float)、byte(Byte)、short(Short)、long(Long)、char(Character)、BigInteger
* @author 陈宇超、一致启航
*/
@ExcelSheet(value = "职工表")
public class Employee {
@ExcelHead(value = "姓名", sort = 0,columnFreeze = true)//第一列,对应姓名列,此列冻结(即左右移动表格此列位置不变)
private String name;
@ExcelHead(value = "年龄", sort = 1,columnColor=ExcelHead.RED,hAlign=ExcelHead.LeftAlign)//年龄列的字体颜色为红色,单元格文本左居中,
private int age;
@ExcelHead(value = "性别", sort = 2)
private boolean sex;
@ExcelHead(value = "生日", sort = 3, columnWidth = 6000, dataFormat = "yyyy-mm-dd hh:mm:ss am/pm") //第四列,列宽6000,日期格式化
private Date date;
@ExcelHead(value = "薪水", sort = 4, dataFormat = "#,##0.00")
private float salary; //第五列,数字格式化(间隔三位加逗号,保留小数点后两位)
public Employee() {
super();
}
//---省略getter,setter方法
}
4.附录,poi dataformat数据显示格式化(并不改变数据本身)
/**
* excel数据格式化,注意:这只会影响到数据的显示格式,并不会影响数据原本真正的值,默认为空,例子如下:<br/>
* 1、dataformat="yyyy-MM-dd hh:mm:ss AM/PM" 日期的格式化 <br/>
* 2、dataformat="0" 四舍五入为整数,d <br/>
* 3、dataformat="0.00" 四舍五入保留两位小数,小数点不够的补0。eg:320.7567 变为 320.76 , 12 变为 12.00<br/>
* 4、dataFormat = "#,##0" 四舍五入为整数,且每隔三位加逗号。eg:1002320.75 变为 1,002,321。类比用法dataFormat = "#,##0.00"<br/>
* 5、dataFormat = "¥#,##0.0" 同4,前面加上货币符号(其它非预定义字符都可以)。eg:2320.7254 变为 ¥2,320.7 <br/>
* 6、dataFormat = "[green]¥#,##0.0" 同5,将字体的颜色设置为绿色。 <br/>
* 7、dataFormat = "0.0%" 原数乘以100后四舍五入保留一位小数然后添加一个百分号。eg:2320.725342 变为 232072.5% <br/>
* 8、dataFormat = "# ?/?" 小数转化为分数。eg:0.5 变为 1/2 , 1.5 变为 1 1/2 <br/>
* 9、dataFormat = "?/?" 小数转化为分数,只有分母和分子。eg:1.5 变为 3/2 <br/>
*/