Add CSVPrinter.printRecord[s](Stream).
This commit is contained in:
parent
0af5d428d6
commit
8f7e3a6682
|
@ -50,6 +50,7 @@
|
|||
<action issue="CSV-291" type="add" dev="ggregory" due-to="Gary Gregory">Make CSVRecord#values() public.</action>
|
||||
<action issue="CSV-264" type="add" dev="ggregory" due-to="Sagar Tiwari, Seth Falco, Alex Herbert, Gary Gregory">Add DuplicateHeaderMode for flexibility with header strictness. #114.</action>
|
||||
<action issue="CSV-295" type="add" dev="ggregory" due-to="Gary Gregory">Support for parallelism in CSVPrinter.</action>
|
||||
<action issue="CSV-295" type="add" dev="ggregory" due-to="Gary Gregory">Add CSVPrinter.printRecord[s](Stream).</action>
|
||||
<action type="add" dev="ggregory">Add github/codeql-action.</action>
|
||||
<!-- UPDATE -->
|
||||
<action type="update" dev="kinow" due-to="Dependabot, Gary Gregory">Bump actions/cache from 2.1.6 to 3.0.6 #196, #233, #243.</action>
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Prints values in a {@link CSVFormat CSV format}.
|
||||
|
@ -69,8 +70,21 @@ import java.util.Objects;
|
|||
*/
|
||||
public final class CSVPrinter implements Flushable, Closeable {
|
||||
|
||||
/**
|
||||
* Throws the given throwable.
|
||||
*
|
||||
* @param <T> The throwable cast type.
|
||||
* @param throwable The throwable to rethrow.
|
||||
* @return nothing because we throw.
|
||||
* @throws T Always thrown.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T extends Throwable> RuntimeException rethrow(final Throwable throwable) throws T {
|
||||
throw (T) throwable;
|
||||
}
|
||||
/** The place that the values get written. */
|
||||
private final Appendable appendable;
|
||||
|
||||
private final CSVFormat format;
|
||||
|
||||
/** True if we just began a new record. */
|
||||
|
@ -242,7 +256,7 @@ public final class CSVPrinter implements Flushable, Closeable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Prints the given values a single record of delimiter separated values followed by the record separator.
|
||||
* Prints the given values as a single record of delimiter separated values followed by the record separator.
|
||||
*
|
||||
* <p>
|
||||
* The values will be quoted if needed. Quotes and newLine characters will be escaped. This method adds the record
|
||||
|
@ -262,7 +276,7 @@ public final class CSVPrinter implements Flushable, Closeable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Prints the given values a single record of delimiter separated values followed by the record separator.
|
||||
* Prints the given values as a single record of delimiter separated values followed by the record separator.
|
||||
*
|
||||
* <p>
|
||||
* The values will be quoted if needed. Quotes and newLine characters will be escaped. This method adds the record
|
||||
|
@ -279,11 +293,46 @@ public final class CSVPrinter implements Flushable, Closeable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Prints all the objects in the given collection handling nested collections/arrays as records.
|
||||
* Prints the given values as a single record of delimiter separated values followed by the record separator.
|
||||
*
|
||||
* <p>
|
||||
* If the given collection only contains simple objects, this method will print a single record like
|
||||
* {@link #printRecord(Iterable)}. If the given collections contains nested collections/arrays those nested elements
|
||||
* The values will be quoted if needed. Quotes and newLine characters will be escaped. This method adds the record
|
||||
* separator to the output after printing the record, so there is no need to call {@link #println()}.
|
||||
* </p>
|
||||
*
|
||||
* @param values
|
||||
* values to output.
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
* @since 1.10.0
|
||||
*/
|
||||
public synchronized void printRecord(final Stream<?> values) throws IOException {
|
||||
values.forEachOrdered(t -> {
|
||||
try {
|
||||
print(t);
|
||||
} catch (IOException e) {
|
||||
throw rethrow(e);
|
||||
}
|
||||
});
|
||||
println();
|
||||
}
|
||||
|
||||
private void printRecordObject(final Object value) throws IOException {
|
||||
if (value instanceof Object[]) {
|
||||
this.printRecord((Object[]) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
this.printRecord((Iterable<?>) value);
|
||||
} else {
|
||||
this.printRecord(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints all the objects in the given {@link Iterable} handling nested collections/arrays as records.
|
||||
*
|
||||
* <p>
|
||||
* If the given Iterable only contains simple objects, this method will print a single record like
|
||||
* {@link #printRecord(Iterable)}. If the given Iterable contains nested collections/arrays those nested elements
|
||||
* will each be printed as records using {@link #printRecord(Object...)}.
|
||||
* </p>
|
||||
*
|
||||
|
@ -293,7 +342,7 @@ public final class CSVPrinter implements Flushable, Closeable {
|
|||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* List<String[]> data = ...
|
||||
* List<String[]> data = new ArrayList<>();
|
||||
* data.add(new String[]{ "A", "B", "C" });
|
||||
* data.add(new String[]{ "1", "2", "3" });
|
||||
* data.add(new String[]{ "A1", "B2", "C3" });
|
||||
|
@ -319,13 +368,7 @@ public final class CSVPrinter implements Flushable, Closeable {
|
|||
*/
|
||||
public void printRecords(final Iterable<?> values) throws IOException {
|
||||
for (final Object value : values) {
|
||||
if (value instanceof Object[]) {
|
||||
this.printRecord((Object[]) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
this.printRecord((Iterable<?>) value);
|
||||
} else {
|
||||
this.printRecord(value);
|
||||
}
|
||||
printRecordObject(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,4 +452,56 @@ public final class CSVPrinter implements Flushable, Closeable {
|
|||
}
|
||||
printRecords(resultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints all the objects in the given {@link Stream} handling nested collections/arrays as records.
|
||||
*
|
||||
* <p>
|
||||
* If the given Stream only contains simple objects, this method will print a single record like
|
||||
* {@link #printRecord(Iterable)}. If the given Stream contains nested collections/arrays those nested elements
|
||||
* will each be printed as records using {@link #printRecord(Object...)}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Given the following data structure:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* List<String[]> data = new ArrayList<>();
|
||||
* data.add(new String[]{ "A", "B", "C" });
|
||||
* data.add(new String[]{ "1", "2", "3" });
|
||||
* data.add(new String[]{ "A1", "B2", "C3" });
|
||||
* Stream<String[]> stream = data.stream();
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Calling this method will print:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* A, B, C
|
||||
* 1, 2, 3
|
||||
* A1, B2, C3
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @param values
|
||||
* the values to print.
|
||||
* @throws IOException
|
||||
* If an I/O error occurs
|
||||
* @since 1.10.0
|
||||
*/
|
||||
@SuppressWarnings("unused") // rethrow() throws IOException
|
||||
public void printRecords(final Stream<?> values) throws IOException {
|
||||
values.forEachOrdered(t -> {
|
||||
try {
|
||||
printRecordObject(t);
|
||||
} catch (IOException e) {
|
||||
throw rethrow(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
|
@ -588,6 +589,15 @@ public class CSVPrinterTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcelPrintAllStreamOfArrays() throws IOException {
|
||||
final StringWriter sw = new StringWriter();
|
||||
try (final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.EXCEL)) {
|
||||
printer.printRecords(Stream.of(new String[][] { { "r1c1", "r1c2" }, { "r2c1", "r2c2" } }));
|
||||
assertEquals("r1c1,r1c2" + recordSeparator + "r2c1,r2c2" + recordSeparator, sw.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcelPrinter1() throws IOException {
|
||||
final StringWriter sw = new StringWriter();
|
||||
|
@ -1456,6 +1466,28 @@ public class CSVPrinterTest {
|
|||
assertEquals(content, sw.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintRecordStream() throws IOException {
|
||||
final String code = "a1,b1\n" // 1)
|
||||
+ "a2,b2\n" // 2)
|
||||
+ "a3,b3\n" // 3)
|
||||
+ "a4,b4\n"// 4)
|
||||
;
|
||||
final String[][] res = {{"a1", "b1"}, {"a2", "b2"}, {"a3", "b3"}, {"a4", "b4"}};
|
||||
final CSVFormat format = CSVFormat.DEFAULT;
|
||||
final StringWriter sw = new StringWriter();
|
||||
try (final CSVPrinter printer = format.print(sw); final CSVParser parser = CSVParser.parse(code, format)) {
|
||||
for (final CSVRecord record : parser) {
|
||||
printer.printRecord(record.stream());
|
||||
}
|
||||
}
|
||||
try (final CSVParser parser = CSVParser.parse(sw.toString(), format)) {
|
||||
final List<CSVRecord> records = parser.getRecords();
|
||||
assertFalse(records.isEmpty());
|
||||
Utils.compare("Fail", res, records);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrintRecordsWithCSVRecord() throws IOException {
|
||||
final String[] values = {"A", "B", "C"};
|
||||
|
|
Loading…
Reference in New Issue