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-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-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">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>
|
<action type="add" dev="ggregory">Add github/codeql-action.</action>
|
||||||
<!-- UPDATE -->
|
<!-- 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>
|
<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.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints values in a {@link CSVFormat CSV format}.
|
* Prints values in a {@link CSVFormat CSV format}.
|
||||||
|
@ -69,8 +70,21 @@ import java.util.Objects;
|
||||||
*/
|
*/
|
||||||
public final class CSVPrinter implements Flushable, Closeable {
|
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. */
|
/** The place that the values get written. */
|
||||||
private final Appendable appendable;
|
private final Appendable appendable;
|
||||||
|
|
||||||
private final CSVFormat format;
|
private final CSVFormat format;
|
||||||
|
|
||||||
/** True if we just began a new record. */
|
/** 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>
|
* <p>
|
||||||
* The values will be quoted if needed. Quotes and newLine characters will be escaped. This method adds the record
|
* 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>
|
* <p>
|
||||||
* The values will be quoted if needed. Quotes and newLine characters will be escaped. This method adds the record
|
* 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>
|
* <p>
|
||||||
* If the given collection only contains simple objects, this method will print a single record like
|
* The values will be quoted if needed. Quotes and newLine characters will be escaped. This method adds the record
|
||||||
* {@link #printRecord(Iterable)}. If the given collections contains nested collections/arrays those nested elements
|
* 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...)}.
|
* will each be printed as records using {@link #printRecord(Object...)}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
|
@ -293,7 +342,7 @@ public final class CSVPrinter implements Flushable, Closeable {
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>
|
* <code>
|
||||||
* List<String[]> data = ...
|
* List<String[]> data = new ArrayList<>();
|
||||||
* data.add(new String[]{ "A", "B", "C" });
|
* data.add(new String[]{ "A", "B", "C" });
|
||||||
* data.add(new String[]{ "1", "2", "3" });
|
* data.add(new String[]{ "1", "2", "3" });
|
||||||
* data.add(new String[]{ "A1", "B2", "C3" });
|
* 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 {
|
public void printRecords(final Iterable<?> values) throws IOException {
|
||||||
for (final Object value : values) {
|
for (final Object value : values) {
|
||||||
if (value instanceof Object[]) {
|
printRecordObject(value);
|
||||||
this.printRecord((Object[]) value);
|
|
||||||
} else if (value instanceof Iterable) {
|
|
||||||
this.printRecord((Iterable<?>) value);
|
|
||||||
} else {
|
|
||||||
this.printRecord(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,4 +452,56 @@ public final class CSVPrinter implements Flushable, Closeable {
|
||||||
}
|
}
|
||||||
printRecords(resultSet);
|
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.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.output.NullOutputStream;
|
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
|
@Test
|
||||||
public void testExcelPrinter1() throws IOException {
|
public void testExcelPrinter1() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
|
@ -1456,6 +1466,28 @@ public class CSVPrinterTest {
|
||||||
assertEquals(content, sw.toString());
|
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
|
@Test
|
||||||
public void testPrintRecordsWithCSVRecord() throws IOException {
|
public void testPrintRecordsWithCSVRecord() throws IOException {
|
||||||
final String[] values = {"A", "B", "C"};
|
final String[] values = {"A", "B", "C"};
|
||||||
|
|
Loading…
Reference in New Issue