Java实现集合和Excel文件相互转换
作者:CAT_cwds
一、集合转化为Excel文件
效果如下,是将集合转化为Excel文件,Excel包含合并单元格。
实体类:
@Data public class ClassGrade { /** 年级 */ private String grade; /** 班主任 */ private String leader; /** 学生列表 */ private List<Student> students; @Data public static class Student { /** 姓名 */ private String name; /** 年龄 */ private Integer age; /** 性别 */ private String sex; /** 成绩 */ private Integer gradeResult; } }
需求就是将ClassGrade的集合转化为Excel表格对外输出。没有针对当前类去逐个取值处理,用到了反射来处理,达到了简化代码通用的目的。这个只针对有一个合并单元格的情形,如果是合并单元格中包含合并单元格的话,还需要加代码去处理。
实现代码如下:
1.初始化表头类,参数为表头集合
public static SXSSFWorkbook makeExcelHead(String[] titles) { SXSSFWorkbook workbook = new SXSSFWorkbook(); CellStyle styleTitle = getTitleStyle(workbook, (short) 16); SXSSFSheet sheet = workbook.createSheet(); SXSSFRow rowTitle = sheet.createRow(0); for (int i = 0; i < titles.length; i++) { sheet.setDefaultColumnWidth(25); SXSSFCell cellTitle = rowTitle.createCell(i); // 为标题设置背景颜色 styleTitle.setFillPattern(FillPatternType.SOLID_FOREGROUND); styleTitle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex()); cellTitle.setCellValue(titles[i]); cellTitle.setCellStyle(styleTitle); } return workbook; }
2.反射获取实体的值
public static <T> Object getProperty(T t, String propertyName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IndexOutOfBoundsException { Class<?> aClass = t.getClass(); propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); Method method = aClass.getMethod("get" + propertyName); Object invoke = method.invoke(t); return invoke; }
2.将集合转化为Excel
@Test public void exportExcel() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { //初始化数据 List<ClassGrade> fileList = new ArrayList<>(); for (int m = 1; m <= 1; m++) { fileList.addAll(getGrades()); } //表头名称 String[] title = {"班主任", "学生姓名", "学生年龄", "学生性别", "学生成绩", "班级"}; SXSSFWorkbook workbook = SXSSFWorkbookUtil.makeExcelHead(title); //每一列表头属性,如果子类里面的,则提取子类里面对应的属性名 String[] properties = {"leader", "name", "age", "sex", "gradeResult", "grade"}; //获取当前sheet SXSSFSheet sheet = workbook.getSheetAt(0); int initRowNum = 0; //遍历数据,需要根据业务逻辑去处理是否合并单元格 for (int i = 0; i < fileList.size(); i++) { ClassGrade file = fileList.get(i); int size = file.getStudents().size(); //创建行,以子类的集合数为准 int startRowNum = initRowNum + 1; int lastRowNum = startRowNum + size - 1; SXSSFRow row = sheet.getRow(startRowNum); if (row == null) { row = sheet.createRow(startRowNum); } //班主任一列,处理合并单元格 for (int m = 0; m < 1; m++) { if (lastRowNum - startRowNum > 0) { sheet.addMergedRegion(new CellRangeAddress(startRowNum, lastRowNum, m, m)); } createCell(row, m, SXSSFWorkbookUtil.getProperty(file, properties[m])); } //处理学生姓名~学生成绩四列,非合并单元格信息 int xRowNum = startRowNum; List<ClassGrade.Student> receiptItems = file.getStudents(); for (ClassGrade.Student student : receiptItems) { SXSSFRow row1 = sheet.getRow(xRowNum); if (row1 == null) { row1 = sheet.createRow(xRowNum); } for (int q = 1; q <= 4; q++) { //利用反射获取到值,并且设置到cell里面 createCell(row1, q, SXSSFWorkbookUtil.getProperty(student, properties[q])); } xRowNum++; } //处理班级信息合并单元格 for (int n = 5; n <= 5; n++) { if (lastRowNum - startRowNum >= 1) { sheet.addMergedRegion(new CellRangeAddress(startRowNum, lastRowNum, n, n)); } createCell(row, n, SXSSFWorkbookUtil.getProperty(file, properties[n])); } initRowNum = lastRowNum; } //导出 try ( FileOutputStream excel = new FileOutputStream("excel.xls"); BufferedOutputStream bos = new BufferedOutputStream(excel)) { workbook.write(bos); System.out.println("导出完成"); } catch ( IOException e) { System.out.println("导出失败:" + e.getMessage()); } } private void createCell(SXSSFRow row, int column, Object value) { SXSSFCell cell = row.createCell(column); if (value != null) { cell.setCellValue(String.valueOf(value)); } }
效果
二、Excel文件转化为集合
如题,将获取到的excel文件流转化为集合进行处理。挺简单的。思路就是将一个文件流转化为一个备用类,再将备用类转化为想要的集合。
excel:
备用类代码:
@Data public class ClassGrade2 { /** 年级 */ private String grade; /** 班主任 */ private String leader; /** 姓名 */ private String name; /** 年龄 */ private Integer age; /** 性别 */ private String sex; /** 成绩 */ private Integer gradeResult; }
转化代码:
@Test public void test1() { ExcelReader reader = ExcelUtil.getReader("excelToList.xls"); List<List<Object>> rows = reader.read(); //根据excel的结构,需要准备一个备用类接收数据 List<ClassGrade2> listBaks = new ArrayList<>(); //初始化属性,属性是备用类的属性名 String[] properties = {"leader", "name", "age", "sex", "gradeResult", "grade"}; for (int j = 1; j < rows.size(); j++) { List<Object> cells = rows.get(j); try { //反射获取值,组装成备用类 ClassGrade2 file = new ClassGrade2(); Class<?> clz = file.getClass(); Method[] methods = clz.getDeclaredMethods(); for (int i = 0; i < cells.size(); i++) { String propertyName = properties[i].substring(0, 1).toUpperCase() + properties[i].substring(1); Method method = Arrays.stream(methods).filter(m -> Objects.equal(m.getName(), "set" + propertyName)).findFirst().orElse(null); Object cell = cells.get(i); if (cell == null) { continue; } Field field = clz.getDeclaredField(properties[i]); String fieldType = field.getType().getName(); if (fieldType.equals("java.lang.String")) { method.invoke(file, String.valueOf(cell)); } else if (fieldType.equals("java.math.BigDecimal")) { method.invoke(file, new BigDecimal(String.valueOf(cell))); } } listBaks.add(file); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } finally { } } //备用类转化为想要的集合类 int i = 0; List<ClassGrade> files = new ArrayList<>(); for (int m = 0; m < listBaks.size(); m++) { ClassGrade2 fileBak = listBaks.get(m); if (Strings.isNotEmpty(fileBak.getGrade())) { ClassGrade file = BeanUtil.copyProperties(fileBak, ClassGrade.class); files.add(file); ClassGrade.Student item = BeanUtil.copyProperties(fileBak, ClassGrade.Student.class); List<ClassGrade.Student> items = new ArrayList<>(); items.add(item); file.setStudents(items); i++; } else { ClassGrade.Student item = BeanUtil.copyProperties(fileBak, ClassGrade.Student.class); ClassGrade file = files.get(i - 1); List<ClassGrade.Student> items = CollectionUtils.isEmpty(file.getStudents()) ? new ArrayList<>() : file.getStudents(); items.add(item); file.setStudents(items); } } log.info("{}", JSONArray.toJSONString(listBaks)); log.info("{}", JSONArray.toJSONString(files)); }
实现效果:
11:47:03.635 [main] INFO Excel3Test - [{"grade":"八年级1班","leader":"赵老师","name":"张三","sex":"女"},{"grade":"八年级1班","leader":"赵老师","name":"李四","sex":"女"},{"grade":"八年级1班","leader":"赵老师","name":"王五","sex":"女"}]
11:47:03.647 [main] INFO Excel3Test - [{"grade":"八年级1班","leader":"赵老师","students":[{"name":"张三","sex":"女"}]},{"grade":"八年级1班","leader":"赵老师","students":[{"name":"李四","sex":"女"}]},{"grade":"八年级1班","leader":"赵老师","students":[{"name":"王五","sex":"女"}]}]
到此这篇关于Java实现集合和Excel文件相互转换的文章就介绍到这了,更多相关Java集合和Excel文件相互转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!