Как записать List‹String› в 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 записывается в []

Мой вопрос заключается в том, как мне прочитать его обратно в класс Employee (bean), используя supercsv.

Я пытался использовать CsvBeanReader и CsvDozerBeanReader, но не смог прочитать 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();
    }


}
}

person Vijay    schedule 15.01.2014    source источник


Ответы (1)


Вы полагаетесь на тот факт, что ваши List телефонных номеров записываются в виде одного столбца CSV с использованием формата toString() списка, например. [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. Вы можете сделать это, но вам потребуется написать процессор ячеек чтобы преобразовать эту строку обратно в List. Если ваши телефонные номера — это просто цифры, это не должно быть слишком сложно, но если в ваших телефонных номерах есть запятые, тогда все станет грязным!

Я бы порекомендовал записывать каждый номер телефона в отдельный столбец — так будет намного проще (для всех, кто читает ваш файл, включая вас!).

Все, что вам нужно сделать, это использовать CsvDozerBeanReader и CsvDozerBeanWriter с индексированным сопоставлением.

Вот пример — ключевой частью является индексированное сопоставление:

String[] fieldMapping = new String[] { "name",
    "empId", "phoneNumbers[0]", "phoneNumbers[1]" };
  • Я определил 2 столбца телефонных номеров - если в вашем списке будет больше, просто добавьте больше столбцов.
  • Я мог бы использовать fieldMapping для заголовка, но решил использовать более читаемый настраиваемый заголовок.
  • Вам не нужны подсказки, как в вашем вопросе
  • Я использовал 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]]
person James Bassett    schedule 16.01.2014
comment
Любая идея, как установить String [] fieldMapping, когда я точно не знаю, сколько элементов в списке? - person Vijay; 18.01.2014