Introducción a OpenCSV

1. Introducción

Este artículo rápido presenta OpenCSV 4, una biblioteca fantástica para escribir, leer, serializar, deserializar y / o analizar archivos .csv . A continuación, veremos varios ejemplos que demuestran cómo configurar y usar OpenCSV 4 para sus esfuerzos.

2. Configuración

A continuación se explica cómo agregar OpenCSV a su proyecto mediante una dependencia pom.xml :

 com.opencsv opencsv 4.1  

Los .jars para OpenCSV se pueden encontrar en el sitio oficial o mediante una búsqueda rápida en Maven Repository.

Nuestro archivo .csv será realmente simple, lo mantendremos en dos columnas y cuatro filas:

colA, ColB A, B C, D G, G G, F

3. Bean o no Bean

Después de agregar OpenCSV a su pom.xml , podemos implementar métodos de manejo de CSV de dos maneras convenientes:

  1. utilizando los prácticos objetos CSVReader y CSVWriter (para operaciones más simples) o
  2. usando CsvToBean para convertir archivos .csv en beans (que se implementan como objetos antiguos java anotados ).

Nos quedaremos con ejemplos sincrónicos (o de bloqueo ) para este artículo para que podamos centrarnos en lo básico.

Recuerde, un método sincrónico evitará que el código circundante o posterior se ejecute hasta que esté listo. Cualquier entorno de producción probablemente utilizará métodos asincrónicos o ( sin bloqueo ) que permitirán que otros procesos o métodos se completen mientras finaliza el método asincrónico .

Nos sumergiremos en ejemplos asincrónicos para OpenCSV en un artículo futuro.

3.1. El CSVReader

CSVReader : a través de los métodos readAll () y readNext () proporcionados . Echemos un vistazo a cómo usar readAll () sincrónicamente:

public List readAll(Reader reader) throws Exception { CSVReader csvReader = new CSVReader(reader); List list = new ArrayList(); list = csvReader.readAll(); reader.close(); csvReader.close(); return list; }

Entonces podemos llamar a ese método pasando un BufferedReader :

public String readAllExample() throws Exception { Reader reader = Files.newBufferedReader(Paths.get( ClassLoader.getSystemResource("csv/twoColumn.csv").toURI())); return CsvReaderExamples.readAll(reader).toString(); }

De manera similar, podemos abstraer readNext () que lee un .csv proporcionado línea por línea:

public List oneByOne(Reader reader) throws Exception { List list = new ArrayList(); CSVReader csvReader = new CSVReader(reader); String[] line; while ((line = csvReader.readNext()) != null) { list.add(line); } reader.close(); csvReader.close(); return list; }

Y podemos llamar a ese método aquí pasando un BufferReader:

public String oneByOneExample() throws Exception { Reader reader = Files.newBufferedReader(Paths.get( ClassLoader.getSystemResource("csv/twoColumn.csv").toURI())); return CsvReaderExamples.oneByOne(reader).toString(); } 

Para mayor flexibilidad y opciones de configuración, alternativamente puede usar CSVReaderBuilder :

CSVParser parser = new CSVParserBuilder() .withSeparator(',') .withIgnoreQuotations(true) .build(); CSVReader csvReader = new CSVReaderBuilder(reader) .withSkipLines(0) .withCSVParser(parser) .build();

CSVReaderBuilder permite omitir los encabezados de columna y establecer reglas de análisis a través de CSVParserBuilder .

Con CSVParserBuilder , podemos elegir un separador de columna personalizado, ignorar o manejar las comillas, indicar cómo manejaremos los campos nulos y cómo interpretar los caracteres de escape. Para obtener más información sobre estos ajustes de configuración, consulte los documentos de especificaciones oficiales.

Como siempre, recuerde cerrar todos sus lectores para evitar pérdidas de memoria.

3.2. El CSVWriter

CSVWriter también proporciona la capacidad de escribir en un archivo .csv de una vez o línea por línea.

Echemos un vistazo a cómo escribir en un .csv línea por línea:

public String csvWriterOneByOne(List stringArray, Path path) throws Exception { CSVWriter writer = new CSVWriter(new FileWriter(path.toString())); for (String[] array : stringArray) { writer.writeNext(array); } writer.close(); return Helpers.readFile(path); } 

Ahora, especifiquemos dónde queremos guardar ese archivo y llamemos al método que acabamos de escribir:

public String csvWriterOneByOne() throws Exception{ Path path = Paths.get( ClassLoader.getSystemResource("csv/writtenOneByOne.csv").toURI()); return CsvWriterExamples.csvWriterOneByOne(Helpers.fourColumnCsvString(), path); }

También podemos escribir nuestro .csv de una sola vez pasando una Lista de matrices de cadenas que representan las filas de nuestro .csv . :

public String csvWriterAll(List stringArray, Path path) throws Exception { CSVWriter writer = new CSVWriter(new FileWriter(path.toString())); writer.writeAll(stringArray); writer.close(); return Helpers.readFile(path); }

Y así es como lo llamamos:

public String csvWriterAll() throws Exception { Path path = Paths.get( ClassLoader.getSystemResource("csv/writtenAll.csv").toURI()); return CsvWriterExamples.csvWriterAll(Helpers.fourColumnCsvString(), path); }

¡Eso es!

3.3. Lectura basada en frijoles

OpenCSV puede serializar archivos .csv en esquemas predefinidos y reutilizables implementados como pojo beans de Java anotados . CsvToBean se construye utilizando CsvToBeanBuilder . A partir de OpenCSV 4, CsvToBeanBuilder es la forma recomendada de trabajar con com.opencsv.bean.CsvToBean.

Aquí hay un bean simple que podemos usar para serializar nuestro .csv de dos columnas de la sección 2 .:

public class SimplePositionBean { @CsvBindByPosition(position = 0) private String exampleColOne; @CsvBindByPosition(position = 1) private String exampleColTwo; // getters and setters } 

Cada columna del archivo .csv está asociada con un campo en el bean. Las asignaciones entre los encabezados de columna .csv se pueden realizar utilizando las anotaciones @CsvBindByPosition o @CsvBindByName que especifican una asignación por posición o coincidencia de cadena de encabezado, respectivamente.

Primero, creemos una superclase llamada CsvBean; esto nos permitirá reutilizar y generalizar los métodos que crearemos a continuación:

public class CsvBean { }

Un ejemplo de clase secundaria:

public class NamedColumnBean extends CsvBean { @CsvBindByName(column = "name") private String name; @CsvBindByName private int age; // getters and setters }

Vamos a abstraer una Lista devuelta sincrónicamente usando CsvToBean :

 public List beanBuilderExample(Path path, Class clazz) throws Exception { CsvTransfer csvTransfer = new CsvTransfer(); ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy(); ms.setType(clazz); Reader reader = Files.newBufferedReader(path); CsvToBean cb = new CsvToBeanBuilder(reader) .withType(clazz) .withMappingStrategy(ms) .build(); csvTransfer.setCsvList(cb.parse()); reader.close(); return csvTransfer.getCsvList(); }

We pass in our bean (clazz) and set that as the ColumnPositionMappingStrategy. In doing so, we associate the fields of our beans with the respective columns of our .csv rows.

We can call that here using the SimplePositionBean subclass of the CsvBean we wrote above:

public String simplePositionBeanExample() throws Exception { Path path = Paths.get( ClassLoader.getSystemResource("csv/twoColumn.csv").toURI()); return BeanExamples.beanBuilderExample(path, SimplePositionBean.class).toString(); }

or here using the NamedColumnBean – another subclass of the CsvBean:

public String namedColumnBeanExample() throws Exception { Path path = Paths.get( ClassLoader.getSystemResource("csv/namedColumn.csv").toURI()); return BeanExamples.beanBuilderExample(path, NamedColumnBean.class).toString(); }

3.4. Bean-Based Writing

Lastly, let's take a look at how to use the StatefulBeanToCsv class to write to a .csv file:

public String writeCsvFromBean(Path path) throws Exception { Writer writer = new FileWriter(path.toString()); StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer) .withSeparator(CSVWriter.DEFAULT_SEPARATOR) .build(); List list = new ArrayList(); list.add(new WriteExampleBean("Test1", "sfdsf", "fdfd")); list.add(new WriteExampleBean("Test2", "ipso", "facto")); sbc.write(list); writer.close(); return Helpers.readFile(path); }

Here, we are specifying how we will delimit our data which is supplied as a List of specified CsvBean objects.

Luego podemos llamar a nuestro método writeCsvFromBean () después de pasar la ruta del archivo de salida deseada:

public String writeCsvFromBeanExample() { Path path = Paths.get( ClassLoader.getSystemResource("csv/writtenBean.csv").toURI()); return BeanExamples.writeCsvFromBean(path); }

4. Conclusión

Ahí vamos: ejemplos de código síncrono para OpenCSV usando beans, CSVReader y CSVWriter . Consulte los documentos oficiales aquí.

Como siempre, los ejemplos de código se proporcionan en GitHub.