[alibaba/easyexcel]写Excel时不支持数据格式为List或List<Map<>>

2024-06-20 958 views
3

在进行写Excel的demo测试时,发现将数据格式修改为List<Map<>>或List后无法正确识别内容并输出

// WriteTest.java中源代码
private List<DemoData> data() {
    List<DemoData> list = new ArrayList<DemoData>();
    for (int i = 0; i < 10; i++) {
        DemoData data = new DemoData();
        data.setString("字符串" + i);
        data.setDate(new Date());
        data.setDoubleData(0.56);
        list.add(data);
    }
    return list;
}

// 修改成以下代码后,生成的Excel内容为空
private List<Map<String, Object>> data() {
    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    for (int i = 0; i < 10; i++) {
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("string", "字符串" + i);
        data.put("date", new Date());
        data.put("doubleData", 0.56);
        list.add(data);
    }
    return list;
}

翻了一下源码

// ExcelBuilderImpl.java中的源代码片段
// 109-124行
// 也就是说不是List就会被当成JavaObject处理
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, List<Field> fieldList) {
    beforeRowCreate(n, relativeRowIndex);
    Row row = WorkBookUtil.createRow(context.writeSheetHolder().getSheet(), n);
    afterRowCreate(row, relativeRowIndex);
    if (oneRowData instanceof List) {
        addBasicTypeToExcel((List)oneRowData, row, relativeRowIndex);
    } else if(oneRowData instanceof Map || oneRowData instanceof JSONObject) {
        // 不支持Map或JSONObject
    }else {
        addJavaObjectToExcel(oneRowData, row, relativeRowIndex, fieldList);
    }
}

// 193-242行
// 由于是Map<>类型,没有办法成功转换成beanMap
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex, List<Field> fieldList) {
    WriteHolder currentWriteHolder = context.currentWriteHolder();
    BeanMap beanMap = BeanMap.create(oneRowData);
    Set<String> beanMapHandledSet = new HashSet<String>();
    Map<Integer, Head> headMap = context.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
    Map<Integer, ExcelContentProperty> contentPropertyMap =
        context.currentWriteHolder().excelWriteHeadProperty().getContentPropertyMap();
    int cellIndex = 0;
    for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) {
        cellIndex = entry.getKey();
        ExcelContentProperty excelContentProperty = entry.getValue();
        String name = excelContentProperty.getField().getName();
        if (!beanMap.containsKey(name)) {
            continue;
        }
        Head head = headMap.get(cellIndex);
        beforeCellCreate(row, head, relativeRowIndex);
        Cell cell = WorkBookUtil.createCell(row, cellIndex);
        Object value = beanMap.get(name);
        CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell,
            value, excelContentProperty);
        afterCellCreate(head, cellData, cell, relativeRowIndex);
        beanMapHandledSet.add(name);
    }
    ... 省略
}

也就是说如果我的业务接口返回值是List<Map<>>或比较常用的List的话, 想要直接导出是不行的,必需在导出之前先手动转为List才可以?感觉这次转换是比较多余的。 难道是我打开的方式不对?希望可以直接支持List<Map<>>或List格式的数据

回答

3

JSONObject 一定不会支持。 关于map 你说的map是 index,value 还是 字段名,value。第一个还好支持,但是估计一般人用不到。 字段名,value,如果你head 用的class ,在myabits 返回的时候 请用这个class。如果你head也用的list ,Map是无序的,难道根据head里面的中文去匹配顺序?我感觉需求不是特别合理。或者我理解的有问题?

8

map是Map<字段名,value>的,head也是用的class,正如你所说,只要mybatis返回的时候用这个class,一切都会变得顺利。而我尴尬的点在于接口返回是List的数据(我的实际情况中数据并不是来源于mybatis结果),那么在导出前我需要将List转换为List。当然,你既然表示了JSONObject得不到支持,我想也只能这样了。

0

请问List<Map<String,Value>>的结果该怎么处理?我mybatis返回的resultType是LinkedHashMap,得到的结果顺序与我sql写的字段顺序是一致的.所以我key为表头,value为值处理不了?

6

LinkedHashMap

请自己新开一个问题 并描述清楚干嘛。直接提供代码 你想要干嘛 结果却干嘛