-
Notifications
You must be signed in to change notification settings - Fork 60
7 设置多行表头
EEC从v0.5.3开始支持多表头导出,同样的可以使用注解或者手动指定两种方式,最多支持1024层。
Java Bean可以使用多个ExcelColumn
来实现,多个ExcelColumn的顺序与导出的最终表头完全一致,具体示例如下:
@ExcelColumn("订单号")
private String orderNo;
@ExcelColumn("收件人")
private String recipient;
@ExcelColumn("收件地址")
@ExcelColumn("省")
private String province;
@ExcelColumn("收件地址")
@ExcelColumn("市")
private String city;
@ExcelColumn("收件地址")
@ExcelColumn("区")
private String area;
@ExcelColumn("收件地址")
@ExcelColumn("详细地址")
private String detail;
定义如上Java实体,在‘省’,‘市’,‘区’,和‘详细地址‘4个属性上面加了一个共同的父表头‘收件地址’,效果如下
更为复杂的示例
@ExcelColumn("TOP")
@ExcelColumn
@ExcelColumn
@ExcelColumn("订单号")
private String orderNo;
@ExcelColumn("TOP")
@ExcelColumn
@ExcelColumn
@ExcelColumn("收件人")
private String recipient;
@ExcelColumn("TOP")
@ExcelColumn
@ExcelColumn("收件地址")
@ExcelColumn("省")
private String province;
@ExcelColumn("TOP")
@ExcelColumn
@ExcelColumn("收件地址")
@ExcelColumn("市")
private String city;
@ExcelColumn("TOP")
@ExcelColumn
@ExcelColumn("收件地址")
@ExcelColumn("区")
private String area;
@ExcelColumn("TOP")
@ExcelColumn
@ExcelColumn("收件地址")
@ExcelColumn("详细地址")
private String detail;
我们在头顶再加一个共同的表头‘TOP’,展示效果如下
Column增加addSubColumn
方法用于添加子表头,顺序与注解相似,第一个在最上面最后一个需要指定字段名。这种方式多用于ListMapSheet和ResultSetSheet
new Workbook().addSheet(new ListSheet<>(data
, new Column("姓名", "name")
, new Column("性别", "sex")
, new Column("证书").addSubColumn(new Column("编号", "no"))
, new Column("证书").addSubColumn(new Column("类型", "type"))
, new Column("证书").addSubColumn(new Column("等级", "level"))
, new Column("年龄", "age")
, new Column("教育").addSubColumn(new Column("教育1", "jy1"))
, new Column("教育").addSubColumn(new Column("教育2", "jy2"))))
.writeTo(Paths.get("F:/excel"));
v0.5.6开始EEC支持指定表头位置,你可以通过Sheet#header(fromRowNum, toRowNum)
来指定表头,header
方法支持fromRowNum
和toRowNum
两个参数,为了更加直观这两个参数均从1开始,和打开excel所看到的一样,同时from和to两端都是包含的,对于多行表头来说header将以A1:A2:A3
这种格式进行纵向拼接
我们拿上面【手动添加】的文件为例子来展示如何使用header来支持多表头,我们只需要设置header(1, 2)指定两行表头即可reader.sheet(0).header(1, 2).dataRows().map(Row::toMap).forEach(System.out::println)
,通过这个命令可输入如下结果
{姓名=暗月月, 性别=男, 证书:编号=1, 证书:类型=数学, 证书:等级=3, 年龄=30, 教育:教育1=教育a, 教育:教育2=教育b}
{姓名=暗月月, 性别=男, 证书:编号=2, 证书:类型=语文, 证书:等级=1, 年龄=30, 教育:教育1=教育a, 教育:教育2=教育c}
{姓名=暗月月, 性别=男, 证书:编号=3, 证书:类型=历史, 证书:等级=1, 年龄=30, 教育:教育1=教育b, 教育:教育2=教育c}
{姓名=张三, 性别=女, 证书:编号=1, 证书:类型=英语, 证书:等级=1, 年龄=20, 教育:教育1=教育d, 教育:教育2=教育d}
{姓名=张三, 性别=女, 证书:编号=5, 证书:类型=物理, 证书:等级=7, 年龄=20, 教育:教育1=教育x, 教育:教育2=教育x}
{姓名=李四, 性别=男, 证书:编号=2, 证书:类型=语文, 证书:等级=1, 年龄=24, 教育:教育1=教育c, 教育:教育2=教育a}
{姓名=李四, 性别=男, 证书:编号=3, 证书:类型=历史, 证书:等级=1, 年龄=24, 教育:教育1=教育b, 教育:教育2=教育c}
{姓名=王五, 性别=男, 证书:编号=1, 证书:类型=高数, 证书:等级=2, 年龄=28, 教育:教育1=教育c, 教育:教育2=教育a}
{姓名=王五, 性别=男, 证书:编号=2, 证书:类型=JAvA, 证书:等级=3, 年龄=28, 教育:教育1=教育b, 教育:教育2=教育c}
我们可以看到中间合并的表头表现为证书:编号, 证书:类型, 证书:等级
,如果Java bean使用EEC注解的话也可以直接转对象reader.sheet(0).header(1, 2).dataRows().map(row -> row.to(Order.class)).forEach(Print::println)
和单行表头完全一样
v0.5.6同样也支持自定义表头,如果自动解析表头有问题则可以设置自定义表头
// 创建自定义表头
org.ttzero.excel.reader.Row headerRow2 = new org.ttzero.excel.reader.Row() {};
Cell[] cells2 = new Cell[8];
cells2[0] = new Cell((short) 1).setSv("姓名");
cells2[1] = new Cell((short) 2).setSv("性别");
cells2[2] = new Cell((short) 3).setSv("证书:编号");
cells2[3] = new Cell((short) 4).setSv("证书:类型");
cells2[4] = new Cell((short) 5).setSv("证书:等级");
cells2[5] = new Cell((short) 6).setSv("年龄");
cells2[6] = new Cell((short) 7).setSv("教育:教育1");
cells2[7] = new Cell((short) 8).setSv("教育:教育2");
headerRow2.setCells(cells2);
// 使用自定义表头
reader.sheet(0).reset().header(2).bind(Object.class, new HeaderRow().with(2, headerRow2))
.rows().map(Row::toMap).forEach(System.out::println);
让JAVA操作excel更简单