Java导出excel有apache 的poi包,基于该包,衍生了许多封装其的工具,但是从一个编程爱好者的视角中,我们并不满足于利用这些封装好的工具,来实现导出功能的效果,而是关心在需求变更,不断增长的时候,如何来编写有弹性,有灵活,可维护,可扩展的代码。所以此次之行是,1). 学会如何使用POI来生成excel,2)在需求不断变更,应用环境各不相同的情况下,如何逐步将基础的导出excel进行封装,打造精湛的个性化的excel导出工具。
简单的版本导出
-
非常简单,就是将User的信息导出为为excel
// 使用了lombok工具包 @Data @AllArgsConstructor public class User { private Integer Id; private String name; private String phone; }
public class Main { private static final String FILE_NAME = "./resources/test.xlsx"; public static void main(String[] args) throws IOException { List<User> users = getUserList(); try (Workbook wb = new XSSFWorkbook()){ Sheet sheet = wb.createSheet("Q10-1页"); for(int i=0;i<users.size();i++){ Row row = sheet.createRow(i); // 动态的变成对象的属性个数 row.createCell(0).setCellValue(users.get(i).getId()); row.createCell(1).setCellValue(users.get(i).getName()); row.createCell(2).setCellValue(users.get(i).getPhone()); // 设置列宽高自适应 sheet.autoSizeColumn(1); sheet.autoSizeColumn(2); } try(FileOutputStream fileOut = new FileOutputStream(FILE_NAME)){ wb.write(fileOut); System.out.println("生成excel成功"); } } } public static List<User> getUserList(){ List<User> users = new ArrayList<>(); users.add(new User(1,"Q10Viking","17801054490")); users.add(new User(2,"hzz",null)); users.add(new User(3,"壮壮","17801054490")); return users; } }
代码缺陷
我们在创建cell的时候,需要手动一个个get属性值,并且列的顺序也是写死的,这样耦合度太高了。
- 假如有这样的需求变更,我们想要自定义某个属性在excel列的第几行,则需要手动更改
row.createCell(position)
, - 假如user类加入了新的属性或者删除了某个属性,则我们也要修改其导出的代码
- 又或者需求变成,只导出客户想要的信息如用户名和电话号码,而对ID不感兴趣,那么这段写死的代码由于耦合度这么高,改起来真实令人爆炸。更何况用户的行为是不能确定的,也许它只对电话号码感兴趣呢。
- 现在导出的是User,如果是商品,又或者是学生的成绩呢?
- 标题的国际化呢?
所以上面的代码没有任何的弹性,很难维护,很难扩展。(在编写代码的时候没有充分考虑到变化的可能,导致代码耦合度太高)