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