利用java反射读写csv中的数据

时间:2024-07-31 11:06:20

  前一段有个需求需要将从数据库读取到的信息保存到csv文件中,在实现该需求的时候发现资料比较少,经过收集反射和csv相关资料,最终得到了如下程序。
  1.在使用java反射读取csv文件数据时,先通过csvreader jar包得到相关数据信息,然后格局反射去读指定对象的成员变量的信息,并转换数据格式最终将csv数据转化为对应的java实体类,该类是一个工具方法,只需要传入符合要求的数据就可以得到结果。
  2.向csv文件写入指定的对象,文件的首行是该对象的成员变量名称。先根据指定的路径,编码格式创建csvwriter,然后根据反射读取对象的成员变量信息,将成员变量的名称写入csv文件的第一行,然后遍历数据集合,根据反射获取到信息并一一写入文件中。
  大体思路是这样的,亲测可用,详细的方法代码如下:

使用java反射读取csv

/**
* 读取指定目录下的xxx.csv文件,并转化为java对象
*
* @param t 读取csv文件之后将要转换成的对象
* @param readFilePath csv文件所在路径
* @param charSet 编码格式
* @return 实体对象列表
*/ public static <T> List<T> readCsvDataToObject(T t, String readFilePath, String charSet) {
List<T> resultList = new ArrayList<T>();
// 创建CSV读对象
CsvReader csvReader = null;
try {
csvReader = new CsvReader(readFilePath, ',', Charset.forName(charSet));
// 所有成员变量
Field[] fields = t.getClass().getDeclaredFields();
// 成员变量的值
Object entityMemberValue = "";
//读取csv文件列标题
csvReader.readHeaders();
while (csvReader.readRecord()) {
Object newInstance = t.getClass().newInstance();
// 读一整行
csvReader.getRawRecord();
for (int f = 0; f < fields.length; f++) {
fields[f].setAccessible(true);
String fieldName = fields[f].getName();
entityMemberValue = getEntityMemberValue(entityMemberValue, fields, f, csvReader.get(fieldName));
// 赋值
PropertyUtils.setProperty(newInstance, fieldName, entityMemberValue);
}
resultList.add((T) newInstance);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != csvReader) {
csvReader.close();
}
}
return resultList;
} /**
* 根据实体成员变量的类型得到成员变量的值
*
* @param realValue 要赋值的对象
* @param fields 赋值对象所有的成员变量
* @param f 具体赋值的第几个成员变量
* @param value 将要写入的值
* @return 转换之后的属性
*/
private static Object getEntityMemberValue(Object realValue, Field[] fields, int f, String value) throws ParseException, ClassNotFoundException {
String type = fields[f].getType().getName();
switch (type) {
case "char":
case "java.lang.Character":
case "java.lang.String":
realValue = value;
break;
case "java.util.Date":
realValue = "".equals(value) ? null : TimeTools.getStringToDate(value);
break;
case "java.lang.Integer":
realValue = "".equals(value) ? null : Integer.valueOf(value);
break;
case "int":
case "float":
case "double":
case "java.lang.Double":
case "java.lang.Float":
case "java.lang.Long":
case "java.lang.Short":
case "java.math.BigDecimal":
realValue = "".equals(value) ? null : new BigDecimal(value);
break;
default:
realValue = null;
break;
}
return realValue;
}

将指定数据写入csv文件中

/**
* 使用csvjava通过反射导出csv文件(通用方法)
*
* @param objectData 需要导出的java对象数据
* @param saveFilePath 导出文件所在路径
* @param charSet 文件编码格式
* @return 成功返回true 失败返回false
*/
public static <T> boolean generateCsv(List<T> objectData, String saveFilePath, String charSet) {
// 创建CSV写对象
CsvWriter csvWriter = null;
boolean flag = true;
try {
csvWriter = new CsvWriter(saveFilePath, ',', Charset.forName(charSet));
//获取数据属性信息并写入第一行
T firstData = objectData.get(0);
Field[] dataFields = firstData.getClass().getDeclaredFields();
for (Field field : dataFields) {
String fieldName = field.getName();
csvWriter.write(fieldName);
}
//第一行结束,换行
csvWriter.endRecord();
// 遍历集合数据,产生数据行
for (T data : objectData) {
// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
for (Field field : dataFields) {
if (field.toString().contains("static")) {
continue;
}
String fieldName = field.getName();
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Class dataClass = data.getClass();
Method getMethod = dataClass.getMethod(getMethodName, new Class[]{});
Object value = getMethod.invoke(data, new Object[]{});
// 判断值的类型后进行强制类型转换
String textValue;
if (value instanceof Date) {
Date date = (Date) value;
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd hh:mm:ss");
textValue = sdf.format(date);
} else {
// 其它数据类型都当作字符串简单处理
if (value == null) {
value = "";
}
textValue = value.toString();
}
csvWriter.write(textValue);
}
//换行
csvWriter.endRecord();
}
} catch (Exception e) {
flag = false;
e.printStackTrace();
} finally {
//关闭
if (null != csvWriter) {
csvWriter.close();
}
}
return flag;
}