文章目录
- 简介
- 操作Excel相关组件
- 使用
- 工具类
简介
POI是Apache软件基金会用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
所以POI的主要功能是可以用Java操作Microsoft Office的相关文件,但是一般我们都是用来操作Excel相关文件。
操作Excel相关组件
HSSF:操作 Microsoft Excel 2003及以下(.xls)。
XSSF:操作 Microsoft Excel 2007及以上(.xlsx),POI 3.8 及以上版本才支持。
SXSSF:操作 Microsoft Excel 2007及以上(.xlsx),支持大数据量操作,POI 3.8 beta3 及以上版本支持。
使用
引入依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
实体类
@Setter
@Getter
@Accessors(chain = true)
public class User {
/**
* 用户名
*/
private String userName;
/**
* 年龄
*/
private Integer age;
/**
* 性别
*/
private String sex;
}
我这里就不建数据库了 随便塞点数据测试用
public List<User> getUserList(){
List<User> list = new ArrayList<>();
User zs = new User();
zs.setUserName("张三").setSex("男").setAge(18);
User ly = new User();
ly.setUserName("柳岩").setSex("女").setAge(20);
Collections.addAll(list,zs,ly);
return list;
}
具体实现
public void testPoi(HttpServletResponse response) throws Exception{
//创建工作簿
Workbook wb = new XSSFWorkbook();
//创建sheet页
Sheet sheet = wb.createSheet();
//创建第一行表头
Row tableRow = sheet.createRow(0);
//
String [] headerNames = {"用户名","年龄","性别"};
for (int i = 0; i < headerNames.length; i++) {
//通过行创建列
Cell cell = tableRow.createCell(i);
//往列中设置值
cell.setCellValue(headerNames[i]);
}
//获取数据
List<User> userList = getUserList();
// 封装数据
for (int i = 0; i < userList.size(); i++) {
Row dataRow = sheet.createRow(i+1);
User user = userList.get(i);
dataRow.createCell(0).setCellValue(user.getUserName());
dataRow.createCell(1).setCellValue(user.getAge());
dataRow.createCell(2).setCellValue(user.getSex());
}
String fileName = "用户信息";
//解决文件名中文乱码
response.setHeader("Content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "iso-8859-1")+".xlsx");
//导出到浏览器
wb.write(response.getOutputStream());
}
工具类
上面的代码写可以完成需求但是太麻烦了,于是我写了个工具类。
编写2个注解
一个是注解(用于指定Excel文件名)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelName {
String value() default "excel";
}
另一个还是注解(用于指定列明)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelField {
String value() default "未知列明";
}
修改实体类添加注解
@Setter
@Getter
@Accessors(chain = true)
@ExcelName("用户信息")
public class User {
@ExcelField("用户名")
private String userName;
@ExcelField("年龄")
private Integer age;
@ExcelField("性别")
private String sex;
}
编写工具类
public class ExcelUtil {
public static void excel(HttpServletResponse response, List<?> dataList){
try {
//创建工作簿
Workbook wb = new XSSFWorkbook();
//创建sheet页
Sheet sheet = wb.createSheet();
if (CollectionUtils.isEmpty(dataList)){
return;
}
//通过反射获取类对象
Class<?> objClass = dataList.get(0).getClass();
//获取实体类上的注解
ExcelName excelNameAno = objClass.getAnnotation(ExcelName.class);
//获取文件名
String tableName = excelNameAno.value();
//拿到所有的属性
Field[] headerFields = objClass.getDeclaredFields();
//行索引值 第一行为0
AtomicInteger rowNum = new AtomicInteger(0);
//创建第一行表头
Row headerRow = sheet.createRow(rowNum.getAndIncrement());
//列索引值 第一列为 0
AtomicInteger headerCellNum = new AtomicInteger(0);
//遍历所有属性
Arrays.stream(headerFields).forEach(item->{
//拿到属性上的注解
ExcelField excelFieldAno = item.getAnnotation(ExcelField.class);
//表头名称
String headerName = excelFieldAno.value();
Cell cell = headerRow.createCell(headerCellNum.getAndIncrement());
cell.setCellValue(headerName);
});
//封装数据
dataList.stream().forEach(item->{
//创建数据 从第二行开始 行索引值 1
Row dataRow = sheet.createRow(rowNum.getAndIncrement());
//通过反射获取类对象
Class<?> aClass = item.getClass();
//拿到所有的属性
Field[] fields = aClass.getDeclaredFields();
//列的索引值
AtomicInteger dataCellNum = new AtomicInteger(0);
Arrays.stream(fields).forEach(field -> {
try {
Cell cell = dataRow.createCell(dataCellNum.getAndIncrement());
field.setAccessible(true); //破封装 拿到private修饰非属性
Object val = field.get(item);//获取值
cell.setCellValue(String.valueOf(val));
} catch (IllegalAccessException e) {
throw new RuntimeException(e.getMessage());
}
});
});
//解决文件名中文乱码
response.setHeader("Content-disposition", "attachment;filename=" + new String(tableName.getBytes(), "iso-8859-1")+".xlsx");
//导出到浏览器
wb.write(response.getOutputStream());
}catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
}
service只剩这么点代码了 是不是很简单呢
public void excel(HttpServletResponse response){
List<User> userList = getUserList();
ExcelUtil.excel(response,userList);
}
运行结果