Записать CSV из списка хэш-карт с заголовком, используя Apache Commons CSV

#java #apache-commons #apache-commons-csv

#java #apache-commons #apache-commons-csv

Вопрос:

Я должен взять ArrayList из HashMap и создать CSV, используя Apache Commons CSV. Однако, это не записывает значения в правильные заголовки. Есть ли простой способ заставить библиотеку автоматически помещать значения в правильные заголовки с помощью перечисления? Я не хочу назначать его вручную, поскольку я буду добавлять больше столбцов.

Это то, что он создает:

введите описание изображения здесь

Вот что у меня есть:

Header.java

 public enum Header
{
    FIRST_NAME(),
    LAST_NAME(),
    GENDER();
}
  

Главная

 public static void main(String[] args)
{
    List<Map<Header, String>> output = new ArrayList<>();

    Map<Header, String> map = new HashMap<>();
    map.put(Header.FIRST_NAME, "John");
    map.put(Header.LAST_NAME, "Andrew");
    map.put(Header.GENDER, "Male");
    output.add(map);

    Map<Header, String> map2 = new HashMap<>();
    map2.put(Header.FIRST_NAME, "Sally");
    map2.put(Header.LAST_NAME, "Andrew");
    map2.put(Header.GENDER, "Female");
    output.add(map2);

    String outputFile = System.getProperty("java.io.tmpdir") "test.csv";

    try (
            BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputFile));
            CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
                    .withHeader(Header.class));)
    {
        csvPrinter.printRecords(output);
        csvPrinter.flush();
    } catch (IOException ex)
    {
        Logger.getLogger(TestCSV.class.getName()).log(Level.SEVERE, null, ex);
    }

}
  

Комментарии:

1. вы, мужчина, хотите использовать jackson csv или open csv для чтения csv как java pojo, поэтому вам не нужно объявлять больше перечислений

2. Не уверен, что вы имеете в виду, поскольку я хочу конкретно определить заголовки

Ответ №1:

Как насчет этого:

 try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputFile));
        CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(Header.class));) {
    for (Map<Header, String> row : output) {
        csvPrinter.printRecord(Arrays.asList(Header.values())
                                     .stream()
                                     .map(header -> row.get(header))
                                     .collect(Collectors.toList()));
    }
} catch (IOException ex) {
    Logger.getLogger(TestCSV.class.getName())
          .log(Level.SEVERE, null, ex);
}
  

Комментарии:

1. Спасибо, это выглядит даже лучше, чем у меня, поскольку порядок берется из перечисления.

Ответ №2:

Хорошо, разобрался. Я изменил карты на LinkedHashMap , чтобы сохранить порядок, затем сделал это:

    try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(outputFile));
        CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT
        .withHeader(Header.class));)
   {

        for (Map<Header, String> val : output)
        {
            csvPrinter.printRecord(val.values().toArray());
        }

        csvPrinter.flush();

    } catch (IOException ex)
    {
        Logger.getLogger(TestCSV.class.getName()).log(Level.SEVERE, null, ex);
    }