背景
游戏开发中,经常需要用到EXCEL进行数值配置。现在有很多工具,可以进行转换,比如LUBAN什么的。但是它们通常有自己的一套配置和定义规则。所以我一直用的是自己写的工具。整个流程是:策划与程序,先沟通和商量好表头。接着策划进行表配置。配置完成之后,利用工具生成CSV文件,以及对应结构体与LOAD及RELOAD代码。
之前就一直在思考,像物品配置表的ICON字段,后端的CSV中,完全不需要。但是我现在的工具一直没有开发区分字段进行前后端分开转存(就是:前后端一直CSV是一模一样的)。当然主要也是懒。。。
最近,我们做到一个答题功能。对应的配置表里面有正确答案这一列。为了防止作弊,所以这一列不能出现在客户端的配置CSV里面。所以上面的功能就必须提上日程了。
实现
我现在配置表的表头有三行:字段名、类型、说明。现在增加一行:group。其值一共有四种:cs(服务器与客户端都需要)、c(客户端需要)、s(服务器需要)、空白(都不需要)。
读出所有数据
List<LinkedHashMap> data = EasyExcelFactory.read(excelFile).sheet(sheet.getSheetName()).headRowNumber(0).doReadSync();
找出需要排除的列索引与名称
根据group行,进行排除筛选。
private static LinkedHashMap<Integer, String> getExcludedCols(List<LinkedHashMap> excelData, boolean findServer) {
LinkedHashMap<Integer, String> excludedCols = new LinkedHashMap<>();
LinkedHashMap fieldNameMap = excelData.get(0);
LinkedHashMap fieldGroupMap = excelData.get(2);
for (int i = 1; i < fieldNameMap.size(); i++) {
String fieldName = fieldNameMap.get(Integer.valueOf(i)).toString();
Object group = fieldGroupMap.get(Integer.valueOf(i));
if (group == null) {
excludedCols.put(i, fieldName);
continue;
}
String groupStr = group.toString();
if (StrUtil.isEmpty(groupStr)) {
excludedCols.put(i, fieldName);
} else if (findServer && groupStr.equals("c")) {
excludedCols.put(i, fieldName);
} else if (!findServer && groupStr.equals("s")) {
excludedCols.put(i, fieldName);
}
}
return excludedCols;
}
根据排除列找出需要的数据
** 这是重点步骤。也是让我花费很多时间的一步。
我一开始使用的是excludeColumnFieldNames
。但是一直未生效。经过多次调试发现,EASYEXCEL对于使用JAVA结构体与Collection和Map走的是不同方法。addBasicTypeToExcel
,没有使用到定义的excludeColumnFieldNames
。
if (oneRowData instanceof Collection) {
this.addBasicTypeToExcel(new CollectionRowData((Collection)oneRowData), row, rowIndex, relativeRowIndex);
} else if (oneRowData instanceof Map) {
this.addBasicTypeToExcel(new MapRowData((Map)oneRowData), row, rowIndex, relativeRowIndex);
} else {
this.addJavaObjectToExcel(oneRowData, row, rowIndex, relativeRowIndex);
}
所以,就只能自己去遍历数据,根据列索列去跳行。
List<LinkedHashMap> newDataList = getNeedDatas(excludedColIndexs.keySet(), excelData);
private static List<LinkedHashMap> getNeedDatas(Set<Integer> needDelIndex, List<LinkedHashMap> allData) {
List<LinkedHashMap> reList = new ArrayList<>();
int i = 0;
for (LinkedHashMap indexAndValMap : allData) {
++i;
if (i == 3) { //去掉group行。CSV中不存该行。
continue;
}
LinkedHashMap newDataMap = new LinkedHashMap<>();
Set<Map.Entry> entry = indexAndValMap.entrySet();
int delNum = 0;
for (Map.Entry keyAndValue : entry) {
Integer index = (Integer) keyAndValue.getKey();
if (needDelIndex.contains(index)) {
++delNum;
continue;
} else {
newDataMap.put(index - delNum, keyAndValue.getValue());
}
}
if (!newDataMap.isEmpty()) {
reList.add(newDataMap);
}
}
return reList;
}
转存数据到CSV中
EasyExcel.write(savePath)
.excelType(ExcelTypeEnum.CSV)
.charset(StandardCharsets.UTF_8)
.sheet(sheet.getSheetNo())
.doWrite(newDataList);
最后
最近实在太忙,所以上班时,主要做一些需要对接的工作。这种比较独立的工作,就晚上回家了自己一个人加会儿班。
当天,以为这个功能能很快完成。然后实际好像有点不太一样。
1.网上跳列相关资料比较少。都是使用的excludeColumnFieldNames
,导致一直在这里纠结,以为自己写法不对。
2.开源框架遇到问题,去issues看看,可能会有结果。但也是看运气。
3.任何功能点,都不能太乐观了呀!!!