diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 8dfa3af6..5f442c17 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -39,7 +39,8 @@ - + + CSVFormat#withHeader doesn't work with CSVPrinter CSVFormat is missing a print(...) method CSVRecord.toMap() throws NPE on formats with no headers. diff --git a/src/main/java/org/apache/commons/csv/CSVFormat.java b/src/main/java/org/apache/commons/csv/CSVFormat.java index a6fde0ab..5963edbe 100644 --- a/src/main/java/org/apache/commons/csv/CSVFormat.java +++ b/src/main/java/org/apache/commons/csv/CSVFormat.java @@ -605,8 +605,10 @@ public final class CSVFormat implements Serializable { * @param out * the output * @return a printer to an output + * @throws IOException + * thrown if the optional header cannot be printed. */ - public CSVPrinter print(final Appendable out) { + public CSVPrinter print(final Appendable out) throws IOException { return new CSVPrinter(out, this); } diff --git a/src/main/java/org/apache/commons/csv/CSVPrinter.java b/src/main/java/org/apache/commons/csv/CSVPrinter.java index d048f890..d2968b53 100644 --- a/src/main/java/org/apache/commons/csv/CSVPrinter.java +++ b/src/main/java/org/apache/commons/csv/CSVPrinter.java @@ -45,24 +45,31 @@ public final class CSVPrinter implements Flushable, Closeable { /** * Creates a printer that will print values to the given stream following the CSVFormat. *

- * Currently, only a pure encapsulation format or a pure escaping format is supported. Hybrid formats - * (encapsulation and escaping with a different character) are not supported. + * Currently, only a pure encapsulation format or a pure escaping format is supported. Hybrid formats (encapsulation + * and escaping with a different character) are not supported. *

- * + * * @param out - * stream to which to print. Must not be null. + * stream to which to print. Must not be null. * @param format - * the CSV format. Must not be null. + * the CSV format. Must not be null. + * @throws IOException + * thrown if the optional header cannot be printed. * @throws IllegalArgumentException - * thrown if the parameters of the format are inconsistent or if either out or format are null. + * thrown if the parameters of the format are inconsistent or if either out or format are null. */ - public CSVPrinter(final Appendable out, final CSVFormat format) { + public CSVPrinter(final Appendable out, final CSVFormat format) throws IOException { Assertions.notNull(out, "out"); Assertions.notNull(format, "format"); this.out = out; this.format = format; this.format.validate(); + // TODO: Is it a good idea to do this here instead of on the first call to a print method? + // It seems a pain to have to track whether the header has already been printed or not. + if (format.getHeader() != null) { + this.printRecord((Object[]) format.getHeader()); + } } // ====================================================== diff --git a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java index ee460ba3..63f66ea4 100644 --- a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java +++ b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java @@ -485,6 +485,17 @@ public class CSVPrinterTest { printer.close(); } + @Test + public void testHeader() throws IOException { + final StringWriter sw = new StringWriter(); + final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuoteChar(null) + .withHeader("C1", "C2", "C3")); + printer.printRecord("a", "b", "c"); + printer.printRecord("x", "y", "z"); + assertEquals("C1,C2,C3\r\na,b,c\r\nx,y,z\r\n", sw.toString()); + printer.close(); + } + @Test public void testEOLPlain() throws IOException { final StringWriter sw = new StringWriter();