POI导出Excle工具类(反射读取Java类)

简介

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);
 }

运行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_29917503/article/details/131477676
今日推荐