2

I am using jsefa library to selectively deserialize a csv for eg. maping only header no. 1,3,5 to my object, this works fine.

Now I want to do the opposite of it selectively serialize my object to header postion 1,3,5 and rest positions should get separated by semicolon (;) automatically. So the output would look something like this:

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

Can anybody suggest, how can this be done with jsefa or with any other library.

Ashish
  • 198
  • 3
  • 11
  • It is unclear what and how you tried. And how opencsv and supercsv are tried by you. – Rob Audenaerde Oct 24 '14 at 10:48
  • @RobAu Hi I have't tried opencsv or supercsv, I added these tags so guys who have used these libraries can give some advise. I have only tried jsefa. Let me try to make it more clear. – Ashish Oct 24 '14 at 11:53

2 Answers2

0

This is certainly achievable with Super CSV. Just supply a null entry in the nameMapping array to always write a blank column.

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);
        }
    }
}

You should get the following output:

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

That's probably the easiest solution, but if you're after something more flexible (you might want to validate the field value, but never write it for example), then you can create a custom cell processor to ensure the field is never written. Just define a cell processor that always ignores the value in the bean:

public class Ignore extends CellProcessorAdaptor {

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

}

And then use it:

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);
        }
    }
}

So you could chain it together new NotNull(new Ignore()) to validate that the bean's middleName field always has a value, but to never write it. It also means if you change your mind later on and want to write the value, you can replace the Ignore() processor with Optional() (or NotNull(), or whatever you like) and see that it should then write the middle name field, instead of ignoring it.

James Bassett
  • 9,458
  • 4
  • 35
  • 68
0

Just use uniVocity-parsers as it is MUCH simpler and faster than any other CSV parsing library for Java:

To read:

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

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

To write:

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

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

Disclosure: I am the author of this library. It's open-source and free (Apache V2.0 license).

josliber
  • 43,891
  • 12
  • 98
  • 133
Jeronimo Backes
  • 6,141
  • 2
  • 25
  • 29