学而时习之,不亦说乎
利用反射修改注解中的值
实现这个功能,主要是为了解决EasyPoi中未实现多语言国际化的问题
EasyPoi通过简单的导出工具类,配合实体类中增加的相应注解,实现数据的Excel导出功能。
但如何实现表头多语言国际化的功能,根据传入的语言标识,来确定表头部分的文字是简体中文,还是繁体中文,还是英文。
主要的思路是,利用反射原理,获取注解中对应的值,并对该值进行修改。
如下简单创建一个实体类,增加easypoi的@Excel注解,注解中name的值,即是导出的时候表头的信息,现在以逗号分隔三种语言的文字,根据传入语言标识,重新设置对应的文字。
@Data
public class StaOrgPost {
@Excel(name = "岗位名称,崗位名稱,Post Name", width = 40)
private String postName;
@Excel(name = "岗位人数,崗位人數,Post Count", width = 10)
private Integer userCnt;
}
创建一个导出语言工具类,利用反射,重新赋予@Excel中name字段的值
public class ExcelLangUtils {
private static final int VALUE_SIZE = 3;
private ExcelLangUtils() {
}
public static Class chooseLang(Class<?> pojoClass, String lang)
throws NoSuchFieldException, IllegalAccessException {
//获取实体类中所有字段
Field[] fields = pojoClass.getDeclaredFields();
for (Field field : fields) {
// 获取字段上的注解
Excel anoExcel = field.getAnnotation(Excel.class);
if (anoExcel != null) {
// 获取代理处理器
InvocationHandler invocationHandler = Proxy.getInvocationHandler(anoExcel);
// 获取私有 memberValues 属性
Field f = invocationHandler.getClass().getDeclaredField("memberValues");
f.setAccessible(true);
// 获取实例的属性map
Map<String, Object> memberValues = (Map<String, Object>) f.get(invocationHandler);
// 获取属性值
String excelValue = (String) memberValues.get("name");
if (StringUtils.isNotBlank(excelValue)) {
//根据传入的语言标识,重新设置属性值
List<String> valueList = Arrays.asList(excelValue.split(","));
if (valueList.size() == VALUE_SIZE) {
if (RptConstants.LANGUAGE_ZH.equals(lang)) {
memberValues.put("name", valueList.get(0));
}
if (RptConstants.LANGUAGE_TW.equals(lang)) {
memberValues.put("name", valueList.get(1));
}
if (RptConstants.LANGUAGE_EN.equals(lang)) {
memberValues.put("name", valueList.get(2));
}
}
}
}
}
return pojoClass;
}
}
导出工具类中列用该工具类,重新处理入参StaOrgPost.class
workbook = ExcelExportUtil.exportBigExcel(exportParams, ExcelLangUtils.chooseLang(StaOrgPost.class, RptConstants.LANGUAGE_TW), staOrgPostList);
这样就简单实现了easypoi导出表头的国际化多语言功能