前一段有个需求需要将从数据库读取到的信息保存到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;
}
posted on 2018-04-04 15:50  流沙De记忆  阅读(837)  评论(0编辑  收藏  举报