Выборочная сериализация в CSV, Java

Я использую библиотеку jsefa для выборочной десериализации csv, например. сопоставление только заголовок №. 1,3,5 к моему объекту, это отлично работает.

Теперь я хочу сделать наоборот, выборочно сериализовать мой объект в позицию заголовка 1,3,5, а остальные позиции должны автоматически разделяться точкой с запятой (;). Таким образом, вывод будет выглядеть примерно так:

Header1;Header2;Header3;Header4;Header5;Header6;Header7
bla1;;bla3;;bla5

Кто-нибудь может подсказать, как это можно сделать с помощью jsefa или любой другой библиотеки.


person Ashish    schedule 24.10.2014    source источник
comment
Непонятно что и как вы пробовали. А как вы пробуете opencsv и supercsv.   -  person RobAu    schedule 24.10.2014
comment
@RobAu Привет, я не пробовал opencsv или supercsv, я добавил эти теги, чтобы ребята, которые использовали эти библиотеки, могли дать несколько советов. Я пробовал только jsefa. Позвольте мне попытаться сделать это более ясным.   -  person Ashish    schedule 24.10.2014


Ответы (2)


Это, безусловно, достижимо с Super CSV. Просто укажите запись null в массиве nameMapping, чтобы всегда записывать пустой столбец.

private static void writePartial() throws IOException {
    Person person1 = new Person("John", "K", "Smith");
    Person person2 = new Person("Sally", "T", "Brown");

    CsvPreference csvPrefs = new CsvPreference.Builder('"', ';', "\n").build();
    String[] nameMapping = new String[] { "firstName", null, "lastName" };

    try (ICsvBeanWriter writer = new CsvBeanWriter(new FileWriter("output.csv"), csvPrefs)) {
        writer.writeHeader("firstName", "middleName", "lastName");
        for( Person p : Arrays.asList(person1, person2) ) {
            writer.write(p, nameMapping);
        }
    }
}

Вы должны получить следующий результат:

firstName;middleName;lastName
John;;Smith
Sally;;Brown

Это, вероятно, самое простое решение, но если вам нужно что-то более гибкое (например, вы можете проверить значение поля, но никогда не записывать его), вы можете создать собственный обработчик ячеек, чтобы гарантировать, что поле никогда не будет записано. Просто определите обработчик ячейки, который всегда игнорирует значение в bean-компоненте:

public class Ignore extends CellProcessorAdaptor {

    @Override
    public Object execute(Object value, CsvContext context) {
        return null;
    }

}

А затем используйте его:

private static void writePartial() throws IOException {
    Person person1 = new Person("John", "K", "Smith");
    Person person2 = new Person("Sally", "T", "Brown");

    CsvPreference csvPrefs = new CsvPreference.Builder('"', ';', "\n").build();
    String[] nameMapping = new String[] { "firstName", "middleName", "lastName" };
    CellProcessor[] processors = new CellProcessor[] { new Optional(), new Ignore(), new Optional() };

    try (ICsvBeanWriter writer = new CsvBeanWriter(new FileWriter("output.csv"), csvPrefs)) {
        writer.writeHeader(nameMapping);
        for( Person p : Arrays.asList(person1, person2) ) {
            writer.write(p, nameMapping, processors);
        }
    }
}

Таким образом, вы можете связать их вместе new NotNull(new Ignore()), чтобы проверить, что поле middleName компонента всегда имеет значение, но никогда не записывать его. Это также означает, что если вы позже передумаете и захотите записать значение, вы можете заменить процессор Ignore() на Optional() (или NotNull(), или что угодно) и увидеть, что он должен затем записать поле отчества, вместо того, чтобы игнорировать его. .

person James Bassett    schedule 25.10.2014
comment
Это, безусловно, работает, но как этого добиться с помощью jsefa? - person Ashish; 26.10.2014

Просто используйте uniVocity-parsers, так как это НАМНОГО проще и быстрее, чем любая другая библиотека для анализа CSV. Джава:

Читать:

CsvParserSettings settings = new CsvParserSettings();
settings.selectIndexes(1, 3, 5);

CsvParser parser = new CsvParser(settings);
List<String[]> parsedRows = parser.parseAll(yourJavaIoReader);

Написать:

CsvWriterSettings settings = new CsvWriterSettings();
settings.selectIndexes(1, 3, 5);

CsvWriter writer = new CsvWriter(outputWriter, settings);
writer.writeAllRowsAndClose(buildMyListOfRowsWith3Elements());

Раскрытие информации: я являюсь автором этой библиотеки. Это бесплатно и с открытым исходным кодом (лицензия Apache V2.0).

person Jeronimo Backes    schedule 05.05.2015