一、e文件内容示例
<breaker>
@ 厂站ID 开关ID 开关名称
# 01120000000001 132100000000000001 xx线119开关
# 01120000000002 132100000000000002 xx线121开关
</breaker>
二、分析
每个<></>认为是一个表,第一行@开头的认为是一个表头,#开头的认为是表数据。
三、实现步骤
1、自定义表注解
import java.lang.annotation.*;
/**
* @Description: 自定义表注解
* @Author: yiwenli
* @Date: 2024/4/25
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CimeTable {
/**
* 标签名
*/
String tagName();
}
2、自定义表字段注解
import java.lang.annotation.*;
/**
* @Description: 自定义表列注解
* @Author: yiwenli
* @Date: 2024/4/25
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface CimeTableField {
/**
* 名字(在文件中显示的)
*/
String name() default "";
/**
* 顺序
*/
int order() default -1;
/**
* 是否显示
*/
boolean show() default true;
}
3、自定义模型类上有自定义CimeTableField注解的字段信息
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Description: 存放模型上有自定义表列注解的字段信息
* @Author: yiwenli
* @Date: 2024/4/25
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CimeTableFieldDTO {
/**
* 字段名(模型中的)
*/
private String fieldName;
/**
* 字段名(表格中的)
*/
private String tableFieldName;
/**
* 顺序
*/
private Integer order;
/**
* 是否显示
*/
private Boolean show;
}
4、编写通用的生成table内容的方法
import cn.hutool.core.bean.BeanUtil;
import cime.annotation.CimeTable;
import cime.annotation.CimeTableField;
import cime.aop.CimeTableFieldDTO;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Description: Cime工具类
* @Author: yiwenli
* @Date: 2024/4/25
*/
@Slf4j
public class CimeUtil {
/**
* table间隔
*/
private static final String SPLIT = " ";
/**
* 表头首字符
*/
private static final String TH_FIRST_CHAR = "@";
/**
* 表数据首字符
*/
private static final String TR_FIRST_CHAR = "#";
/**
* 生成Table
*
* @param clazz 数据对应模型类
* @param dataList 数据集
* @return {@link List<String>} 表格内容,含外层<></>及表头及表数据
* @author yiwenli
* @date 2024/4/25
*/
public static <T> List<String> generateTable(Class<T> clazz, List<T> dataList) {
List<String> result = new ArrayList<>();
try {
// 获取标签名
String tableTagName = "";
if (clazz.isAnnotationPresent(CimeTable.class)) {
CimeTable cimeTable = clazz.getAnnotation(CimeTable.class);
tableTagName = cimeTable.tagName();
} else {
log.info("模型类中未配置@CimeTable注解,无法获取表格对应的标签名");
}
// 获取所有配置注解的要放入文件中的字段信息
List<CimeTableFieldDTO> cimeTableFieldDTOList = getTableFieldMapping(clazz)
.stream()
.filter(CimeTableFieldDTO::getShow)
.sorted(Comparator.comparing(CimeTableFieldDTO::getOrder))
.collect(Collectors.toList());
// 下面开始组织文件中的表格内容
// 1.开标签
result.add("<" + tableTagName + ">");
// 2.表头
List<String> thList = cimeTableFieldDTOList
.stream()
.map(CimeTableFieldDTO::getTableFieldName)
.collect(Collectors.toList());
result.add(TH_FIRST_CHAR + SPLIT + String.join(SPLIT, thList));
// 3.数据行
StringBuilder trBuilder = new StringBuilder();
for (Object data : dataList) {
// 先清空数据
trBuilder.setLength(0);
trBuilder.append(TR_FIRST_CHAR).append(SPLIT);
for (CimeTableFieldDTO cimeTableFieldDTO : cimeTableFieldDTOList) {
String fieldName = cimeTableFieldDTO.getFieldName();
String fieldValue = String.valueOf(BeanUtil.getFieldValue(data, fieldName));
if (fieldValue == null) {
fieldValue = "";
}
trBuilder.append(fieldValue).append(SPLIT);
}
result.add(trBuilder.toString());
}
// 4.闭标签
result.add("</" + tableTagName + ">");
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
return result;
}
/**
* 获取模型中配置的需要放入文件中的字段信息
*
* @param clazz 模型类
* @return {@link List<CimeTableFieldDTO>} 字段信息集合
* @author yiwenli
* @date 2024/4/25
*/
private static <T> List<CimeTableFieldDTO> getTableFieldMapping(Class<T> clazz) {
List<CimeTableFieldDTO> result = new ArrayList<>();
Field[] fields = clazz.getDeclaredFields();
CimeTableFieldDTO cimeTableFieldDTO;
CimeTableField cimeTableField;
for (Field field : fields) {
if (field.isAnnotationPresent(CimeTableField.class)) {
cimeTableField = field.getAnnotation(CimeTableField.class);
cimeTableFieldDTO = new CimeTableFieldDTO(field.getName(), cimeTableField.name(), cimeTableField.order(), cimeTableField.show());
result.add(cimeTableFieldDTO);
}
}
return result;
}
}
5、定义模型类,与e文件中的表格内容字段对应
import cime.annotation.CimeTable;
import cime.annotation.CimeTableField;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Description: 开关信息
* @Author: yiwenli
* @Date: 2024/4/25
*/
@Data
@NoArgsConstructor
@CimeTable(tagName = "breaker")
public class Breaker {
@CimeTableField(name = "厂站ID")
private String stationId;
@CimeTableField(name = "开关ID")
private String brkId;
@CimeTableField(name = "开关名称")
private String brkName;
}
6、组织好模型数据后,调用生成table的公共方法获取e文件内容,然后输出至文件
String filePath = ...;
String fileName = ...;
List<Breaker> breakerList = ...;
List<String> fileContent = CimeUtil.generateTable(Breaker.class, breakerList);
Path filePath = Paths.get(filePath, fileName);
Files.write(filePath, fileContent, StandardCharsets.UTF_8);