Merge branch 'main' of github.com:zfoo-project/zfoo into main

This commit is contained in:
jianan
2022-07-08 19:02:24 +08:00
8 changed files with 101 additions and 31 deletions
@@ -59,7 +59,6 @@ public abstract class JsonUtils {
DefaultPrettyPrinter prettyPrinter = (DefaultPrettyPrinter) MAPPER.getSerializationConfig().getDefaultPrettyPrinter();
DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(StringUtils.TAB_ASCII, FileUtils.LS);
prettyPrinter.indentObjectsWith(indenter);
prettyPrinter.indentArraysWith(indenter);
MAPPER_TURBO.setSerializationInclusion(JsonInclude.Include.NON_NULL);
MAPPER_TURBO.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+6 -4
View File
@@ -5,6 +5,8 @@
- 利用Java动态语言的反射特性,用最少的代码去解析Excel
- 支持Excel导出Json文件
### Ⅱ. 自动映射
- Excel的第一行对应Java类属性,第二行和第三行不会起到注释的作用,其中第一列必须是Id属性
@@ -16,7 +18,7 @@
![Image text](../doc/image/storage/storage02.png)
- 解析过后有两种使用方式
1. 通过注解
1. 通过注解
```
@Component
public class StudentManager {
@@ -26,7 +28,7 @@
}
```
2. 通过类动态获取
2. 通过类动态获取
```
Storage<Integer, StudentResource> studentResources = (Storage<Integer, StudentResource>) StorageContext.getStorageManager().getStorage(StudentResource.class);
```
@@ -45,10 +47,10 @@ var students = studentResources.getIndex("name", "james0");
- 唯一索引通过Storage.getUniqueIndex()获取,需要把索引注解标注为@Index(unique = true)
### Ⅲ. 热更新Excel
### Ⅲ. 热更新Excel/Json
- [tank](https://github.com/zfoo-project/tank-game-server/blob/main/common/src/main/java/com/zfoo/tank/common/util/HotUtils.java)
分布式热更新Excel配置文件实现
分布式热更新Excel/Json配置文件实现
### Ⅳ. 用途
@@ -76,11 +76,11 @@ public class ResourceReader implements IResourceReader {
var iterator = resource.getRows().iterator();
// 从ROW_SERVER这行开始读取数据
while (iterator.hasNext()) {
var row = iterator.next();
var columns = iterator.next().getColumns();
var instance = ReflectionUtils.newInstance(clazz);
for (var fieldInfo : fieldInfos) {
var content = row.get(fieldInfo.index);
var content = columns.get(fieldInfo.index);
if (StringUtils.isNotEmpty(content) || fieldInfo.field.getType() == String.class) {
inject(instance, fieldInfo.field, content);
}
@@ -27,7 +27,15 @@ public class ResourceData {
// 配置表字段名
private List<ResourceHeader> headers = new ArrayList<>();
// 配置表数据
private List<List<String>> rows = new ArrayList<>();
private List<ResourceRow> rows = new ArrayList<>();
public static ResourceData valueOf(String name, List<ResourceHeader> headers, List<ResourceRow> rows) {
var resourceData = new ResourceData();
resourceData.name = name;
resourceData.headers = headers;
resourceData.rows = rows;
return resourceData;
}
public String getName() {
return name;
@@ -45,11 +53,11 @@ public class ResourceData {
this.headers = headers;
}
public List<List<String>> getRows() {
public List<ResourceRow> getRows() {
return rows;
}
public void setRows(List<List<String>> rows) {
public void setRows(List<ResourceRow> rows) {
this.rows = rows;
}
@@ -13,6 +13,7 @@
package com.zfoo.storage.model.resource;
import com.zfoo.protocol.util.AssertionUtils;
import com.zfoo.protocol.util.StringUtils;
import org.springframework.lang.Nullable;
import java.util.HashMap;
@@ -58,6 +59,15 @@ public enum ResourceEnum {
return typeMap.containsKey(type);
}
public static boolean isExcel(String type) {
var resourceEnum = getResourceEnumByType(type);
return resourceEnum == ResourceEnum.EXCEL_XLS || resourceEnum == ResourceEnum.EXCEL_XLSX;
}
public static String typesToString() {
return StringUtils.joinWith(StringUtils.SPACE, typeMap.values().toArray());
}
public String getType() {
return type;
}
@@ -25,13 +25,12 @@ public class ResourceHeader {
//列
private int index;
public ResourceHeader() {
}
public ResourceHeader(String name, String type, int index) {
this.name = name;
this.type = type;
this.index = index;
public static ResourceHeader valueOf(String name, String type, int index) {
var resourceHeader = new ResourceHeader();
resourceHeader.name = name;
resourceHeader.type = type;
resourceHeader.index = index;
return resourceHeader;
}
public String getName() {
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.storage.model.resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author godotg
* @version 4.0
*/
public class ResourceRow {
private int row;
private List<String> columns = new ArrayList<>();
public static ResourceRow valueOf(int row, List<String> columns) {
var resourceRow = new ResourceRow();
resourceRow.row = row;
resourceRow.columns = columns;
return resourceRow;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public List<String> getColumns() {
return columns;
}
public void setColumns(List<String> columns) {
this.columns = columns;
}
}
@@ -20,6 +20,7 @@ import com.zfoo.protocol.util.StringUtils;
import com.zfoo.storage.model.resource.ResourceData;
import com.zfoo.storage.model.resource.ResourceEnum;
import com.zfoo.storage.model.resource.ResourceHeader;
import com.zfoo.storage.model.resource.ResourceRow;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
@@ -42,27 +43,28 @@ public class ExcelToJsonUtils {
public static void excelConvertJson(String inputDir, String outputDir) throws IOException {
var listFiles = FileUtils.getAllReadableFiles(new File(inputDir))
.stream()
.filter(it -> ResourceEnum.containsResourceEnum(FileUtils.fileExtName(it.getName())))
.filter(it -> ResourceEnum.isExcel(FileUtils.fileExtName(it.getName())))
.collect(Collectors.toList());
for (var file : listFiles) {
var fileName = StringUtils.format("{}.json", FileUtils.fileSimpleName(file.getName()));
var fileSimpleName = FileUtils.fileSimpleName(file.getName());
var jsonFileName = StringUtils.format("{}.json", fileSimpleName);
var inputStream = FileUtils.openInputStream(file);
var resourceData = readResourceDataFromExcel(inputStream, fileName);
FileUtils.writeStringToFile(new File(FileUtils.joinPath(outputDir, fileName)), JsonUtils.object2StringPrettyPrinter(resourceData));
var resourceData = readResourceDataFromExcel(inputStream, file.getName());
var outputFilePath = FileUtils.joinPath(outputDir, jsonFileName);
FileUtils.deleteFile(new File(outputFilePath));
FileUtils.writeStringToFile(new File(outputFilePath), JsonUtils.object2StringPrettyPrinter(resourceData));
}
}
public static ResourceData readResourceDataFromExcel(InputStream inputStream, String fileName) {
// 只读取代码里写的字段
var wb = createWorkbook(inputStream, fileName);
var resource = new ResourceData();
resource.setName(fileName);
// 默认取到第一个sheet页
var sheet = wb.getSheetAt(0);
//设置所有列
var headers = getHeaders(sheet, fileName);
resource.setHeaders(headers);
// 行数定位到有效数据行,默认是第四行为有效数据行
var iterator = sheet.iterator();
@@ -70,19 +72,18 @@ public class ExcelToJsonUtils {
iterator.next();
iterator.next();
// 从ROW_SERVER这行开始读取数据
List<List<String>> data = new ArrayList<>();
List<ResourceRow> rows = new ArrayList<>();
while (iterator.hasNext()) {
var row = iterator.next();
List<String> rowData = new ArrayList<>();
var columns = new ArrayList<String>();
for (var header : headers) {
var cell = row.getCell(header.getIndex());
var content = CellUtils.getCellStringValue(cell);
rowData.add(content);
columns.add(content);
}
data.add(rowData);
rows.add(ResourceRow.valueOf(row.getRowNum() + 1, columns));
}
resource.setRows(data);
return resource;
return ResourceData.valueOf(fileName, headers, rows);
}
// 只读取代码里写的字段
@@ -122,7 +123,7 @@ public class ExcelToJsonUtils {
if (Objects.nonNull(previousValue)) {
throw new RunException("资源[class:{}]的Excel文件出现重复的属性控制列[field:{}]", fileName, fieldName);
}
headerList.add(new ResourceHeader(fieldName, typeName, i));
headerList.add(ResourceHeader.valueOf(fieldName, typeName, i));
}
return headerList;
}