- 设计该项目的初衷是为了解决嵌套对象自动生成表头并自动合并行的问题,同时在考虑如果写代码跟操作excel一样简单易懂那就更好了,如我先设置全局样式,在设置表头样式,列格式,在一行一行添加数据等等,所以才有以下代码的实现。
- 通过匹配单元格可以自定义单元格样式,处理值、值格式化、批注等。
- 通过注解支持excel原生格式化、列宽、表头样式、表头批注等。
- 支持多个嵌套对象、无限嵌套对象等等(自动合并单元格->横向扩展纵向合并),你也可以实现其他任何样式或格式。
- 对poi无侵入性,支持构建普通行、多个sheet等,每个sheet可以单独设置样式等等。最终生成原生workbook。 拿到原生workbook后你想做其他任何事情请自便。
代码已开源:GitHub - yyfcode/fastexcel: 快速读写excel,代码简洁。支持嵌套对象导出。
更多样例: GitHub - yyfcode/fastexcel-demo: 读写示例
疑问加群:钉钉群:2880006273
<dependency>
<groupId>com.jeeapp</groupId>
<artifactId>fastexcel</artifactId>
<version>0.0.3</version>
</dependency>
/**
* @author Justice
*/
@Data
@AllArgsConstructor
public class Class {
@ExcelProperty(name = "班级", format = "#,##", column = 1)
private String name;
@ExcelProperty(name = "班主任", column = 2, width = 15)
private String teacher;
@ExcelProperty(name = "班级人数", format = "#,##", column = 3)
private Long number;
@ExcelProperty(name = "教师列表", column = 4,
header = @Header(fillForegroundColor = IndexedColors.GREY_25_PERCENT))
private List<Teacher> teachers;
@ExcelProperty(name = "学生列表", column = 5,
header = @Header(fillForegroundColor = IndexedColors.ORANGE))
private List<Student> students;
}
/**
* @author Justice
*/
@Data
@AllArgsConstructor
public class Family {
@ExcelProperty(name = "家长类型", column = 0)
private String type;
@ExcelProperty(name = "家长姓名", column = 1)
private String name;
}
/**
* @author Justice
*/
@Data
@AllArgsConstructor
public class Student {
@ExcelProperty(name = "姓名", column = 1)
private String name;
@ExcelProperty(name = "性别", format = "[=1]\"男\";[=2]\"女\"", column = 2)
private Integer sex;
@ExcelProperty(name = "出生日期", format = "yyyy-MM-dd", column = 3, width = 15)
private Date birthday;
@ExcelProperty(name = "语文", format = "#,##0.00", column = 4,header = @Header(fillForegroundColor = IndexedColors.LIGHT_GREEN))
private BigDecimal chinese;
@ExcelProperty(name = "数学", format = "#,##0.00", column = 5,header = @Header(fillForegroundColor = IndexedColors.LIGHT_BLUE))
private Double math;
@ExcelProperty(name = "英语", format = "#,##0.00", column = 6,header = @Header(fillForegroundColor = IndexedColors.LIGHT_YELLOW))
private Float english;
@ExcelProperty(name = "家庭成员", column = 7)
private List<Family> families;
}
/**
* @author Justice
*/
@Data
@AllArgsConstructor
public class Teacher {
@ExcelProperty(name = "老师姓名", column = 0)
private String name;
@ExcelProperty(name = "教学内容", column = 1)
private String type;
}
public static void main(String[] args) throws IOException {
Family f1 = new Family("父亲", "张三父");
Family f2 = new Family("母亲", "张三母");
Family f3 = new Family("父亲", "李四父");
Family f4 = new Family("母亲", "李四母");
Family f5 = new Family("爷爷", "李四爷");
Family f6 = new Family("奶奶", "李四奶");
Family f7 = new Family("父亲", "小红父");
Family f8 = new Family("母亲", "小红母");
Family f9 = new Family("妹妹", "小红妹");
Family f10 = new Family("哥哥", "小红哥");
Family f11 = new Family("父亲", "小明父");
Family f12 = new Family("母亲", "小明母");
Family f13 = new Family("父亲", "小兰父");
Family f14 = new Family("母亲", "小兰母");
Family f15 = new Family("弟弟", "小兰弟");
Teacher t1 = new Teacher("张老师", "语文");
Teacher t2 = new Teacher("李老师", "语文");
Teacher t3 = new Teacher("王老师", "数学");
Teacher t4 = new Teacher("合老师", "英语");
Teacher t5 = new Teacher("黄老师", "音乐");
Teacher t6 = new Teacher("牛老师", "体育");
Student st1 = new Student("张三", 1, new Date(), BigDecimal.valueOf(59.1), 82d, 80f, Arrays.asList(f1, f2));
Student st2 = new Student("李四", 1, new Date(), BigDecimal.valueOf(69), 50.4d, 90.2f, Arrays.asList(f3, f4, f5, f6));
Student st3 = new Student("小红", 2, new Date(), BigDecimal.valueOf(100), 70.32d, 92f, Arrays.asList(f7, f8, f9, f10));
Student st4 = new Student("小明", 1, new Date(), BigDecimal.valueOf(42), 63.34d, 50f, Arrays.asList(f11, f12));
Student st5 = new Student("小兰", 2, new Date(), BigDecimal.valueOf(80), 84d, 90f, Arrays.asList(f13, f14, f15));
Class cl1 = new Class("1班", "李老师", 3L, Arrays.asList(t1, t5, t3, t4,t6), Arrays.asList(st1, st2, st3));
Class cl2 = new Class("2班", "王老师", 2L, Arrays.asList(t2, t5, t6), Arrays.asList(st4, st5));
Workbook workbook = new WorkbookBuilder(new SXSSFWorkbook())
.setDefaultRowHeight(20)
// 全局样式
.matchingAll()
.setFontHeight(12)
.setFontName("微软雅黑")
.setVerticalAlignment(VerticalAlignment.CENTER)
.setAlignment(HorizontalAlignment.CENTER)
.setWrapText(true)
.addCellStyle()
.matchingCell(cell -> {
// 只匹配分数列
if (cell == null || cell.getColumnIndex() < 7) {
return false;
}
// 小于60分的标红
String cellValue = CellUtils.getCellValue(cell);
if (NumberUtils.isCreatable(cellValue)) {
return Double.parseDouble(cellValue) < 60D;
}
return false;
})
.setStrikeout(true)
.setFontColor(IndexedColors.RED.getIndex())
.addCellStyle()
.matchingCell(cell -> {
// 只匹配分数列
if (cell == null || cell.getColumnIndex() < 7) {
return false;
}
// 等于100分的标蓝
String cellValue = CellUtils.getCellValue(cell);
if (NumberUtils.isCreatable(cellValue)) {
return Double.parseDouble(cellValue) == 100D;
}
return false;
})
.setFontColor(IndexedColors.BLUE.getIndex())
.addCellStyle()
.createSheet("成绩单")
.createRow("班级概况")
.addCellRange(0, 0, 0, 12)
.merge()
.rowType(Class.class)
.createHeader()// 可以指定导出部分字段,不传代表导出所有
.createRows(Arrays.asList(cl1, cl2))
.end()
.build();
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
workbook.write(os);
File resFile = new File("src/test/resources/test.xlsx");
if (resFile.isFile()) {
resFile.delete();
}
FileUtils.writeByteArrayToFile(resFile, os.toByteArray());
}
}
最终效果: