java - 如何将 List<String> 写入 csv 文件并使用 supercsv 读回

标签 java csv supercsv

我正在使用 supercsv CsvBeanWriter 将值写入 csv 文件。

示例类:

public class Employee {
    private String name;

    private int empId;

    List<String> phoneNumbers;
}

我得到的输出是:

name,empId,phoneNumbers
vijay,1,"[123, 456]"

注意 List<String> phoneNumbers 是如何在 [] 中写出的

我的问题是如何使用 supercsv 将其读回 Employee 类(bean)。

我尝试使用 CsvBeanReaderCsvDozerBeanReader 但无法读取 List<String>

出现非法参数异常。 将不胜感激任何指点!

完整代码:

public class DozerBeanReader {
public static void main(String [] args){
    ICsvDozerBeanReader beanReader = null;

    try {
        beanReader = new CsvDozerBeanReader(new FileReader("Employee.csv"), 
                CsvPreference.STANDARD_PREFERENCE);

        String [] header = beanReader.getHeader(true); // ignore the header

        Class<?> [] hintTypes = {String.class, Integer.class, List.class};

        beanReader.configureBeanMapping(Employee.class, header, hintTypes);

        Employee readEmp1 = beanReader.read(Employee.class);
        readEmp1.toString();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}
}

最佳答案

您所依赖的事实是,您的电话号码List 是使用列表的toString() 格式编写为单个 CSV 列,例如[123, 456]

您将收到如下异常:

org.dozer.MappingException: Illegal object type 
for the method 'setPhoneNumbers'. 
Expected types: 
java.util.List
Actual types: 
java.lang.String

因为 Dozer 不知道如何将字符串 [123, 456] 转换为 List。您可以执行此操作,但需要编写 cell processor 将该字符串转换回List。如果您的电话号码纯粹是数字,那么应该不会太难,但如果您的电话号码有逗号,那么事情就会变得困惑!

我建议将每个电话号码写为单独的一列 - 这样会更容易(对于任何阅读您的文件的人,包括您!)。

您需要做的就是将 CsvDozerBeanReader 和 CsvDozerBeanWriter 与 indexed mapping 一起使用。

这是一个示例 - 关键部分是索引映射:

String[] fieldMapping = new String[] { "name",
    "empId", "phoneNumbers[0]", "phoneNumbers[1]" };
  • 我定义了 2 个电话号码列 - 如果您的列表有更多列,则只需添加更多列
  • 我本可以使用 fieldMapping 作为 header ,但选择使用更具可读性的自定义 header
  • 您不应该需要问题中提供的提示
  • 我使用 StringReader/StringWriter 只是为了使示例简单

示例:

// create employee to write/read
Employee employee = new Employee();
employee.setEmpId(1234);
employee.setName("Vijay");
employee.setPhoneNumbers(Arrays.asList("123", "456"));

// the CSV header
String[] header = new String[] { "name",
    "empId", "phoneNumber1", "phoneNumber2" };

// the field mapping
String[] fieldMapping = new String[] { "name",
    "empId", "phoneNumbers[0]", "phoneNumbers[1]" };

// write the employee
StringWriter out = new StringWriter();
ICsvDozerBeanWriter writer = 
    new CsvDozerBeanWriter(out,
    CsvPreference.STANDARD_PREFERENCE);
writer.configureBeanMapping(Employee.class, fieldMapping);
writer.writeHeader(header);
writer.write(employee);
writer.flush();

// read the employee
ICsvDozerBeanReader reader = 
    new CsvDozerBeanReader(new StringReader(out.toString()),
    CsvPreference.STANDARD_PREFERENCE);
reader.configureBeanMapping(Employee.class, fieldMapping);
reader.getHeader(true); // ignore header
Employee e = reader.read(Employee.class);
System.out.println(e);

假设您已经编写了 toString() 方法,这应该打印

Employee [name=Vijay, empId=1234, phoneNumbers=[123, 456]]

关于java - 如何将 List<String> 写入 csv 文件并使用 supercsv 读回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21145412/

相关文章:

java - 为什么 isAnnotationPresent 在 Java 7 和 Java 8 之间的工作方式不同?

java - Android 上的原生方法如何与电源管理生命周期交互?

java - 如何扩展 Eclipse 源格式化程序的边距?

java - 将现有的Cassandra数据集成到Elassandra

python - Pandas :比较行值并修改下一列的行值

java - 生成的 CSV 文件中不需要的双引号

Hadoop 与 supercsv

python - 排序数据框并按单词搜索

python - 无法打开在Python代码中创建的Excel文件

csv - 将 SuperCsv 与多个变量列结合使用