Conversión de JSON a CSV en Java

1. Introducción

En este breve tutorial, veremos cómo usar Jackson para convertir JSON en CSV y viceversa.

Hay bibliotecas alternativas disponibles, como la clase CDL de org.json, pero aquí solo nos centraremos en la biblioteca Jackson.

Después de ver nuestra estructura de datos de ejemplo, usaremos una combinación de ObjectMapper y CSVMapper para convertir entre JSON y CSV.

2. Dependencias

Agreguemos la dependencia para el formateador de datos Jackson CSV:

 com.fasterxml.jackson.dataformat jackson-dataformat-csv 2.11.1 

Siempre podemos encontrar la versión más reciente de esta dependencia en Maven Central.

También agregaremos la dependencia para el enlace de datos principal de Jackson:

 com.fasterxml.jackson.core jackson-databind 2.11.1 

Nuevamente, podemos encontrar la versión más reciente de esta dependencia en Maven Central.

3. Estructura de datos

Antes de reformatear un documento JSON a CSV, debemos considerar qué tan bien se correlacionará nuestro modelo de datos entre los dos formatos.

Primero, consideremos qué datos admiten los diferentes formatos:

  • Usamos JSON para representar una variedad de estructuras de objetos, incluidas las que contienen matrices y objetos anidados.
  • Usamos CSV para representar datos de una lista de objetos, y cada objeto de la lista aparece en una nueva línea.

Esto significa que si nuestro documento JSON tiene una matriz de objetos, podemos reformatear cada objeto en una nueva línea de nuestro archivo CSV. Entonces, como ejemplo, usemos un documento JSON que contenga la siguiente lista de elementos de un pedido:

[ { "item" : "No. 9 Sprockets", "quantity" : 12, "unitPrice" : 1.23 }, { "item" : "Widget (10mm)", "quantity" : 4, "unitPrice" : 3.45 } ]

Usaremos los nombres de campo del documento JSON como encabezados de columna y lo formatearemos al siguiente archivo CSV:

item,quantity,unitPrice "No. 9 Sprockets",12,1.23 "Widget (10mm)",4,3.45

4. Leer JSON y escribir CSV

Primero, usamos ObjectMapper de Jackson para leer nuestro documento JSON de ejemplo en un árbol de objetos JsonNode :

JsonNode jsonTree = new ObjectMapper().readTree(new File("src/main/resources/orderLines.json"));

A continuación, creemos un CsvSchema . Esto determina los encabezados de columna, los tipos y la secuencia de columnas en el archivo CSV. Para hacer esto, creamos un CsvSchema Builder y configuramos los encabezados de columna para que coincidan con los nombres de campo JSON:

Builder csvSchemaBuilder = CsvSchema.builder(); JsonNode firstObject = jsonTree.elements().next(); firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} ); CsvSchema csvSchema = csvSchemaBuilder.build().withHeader();

Luego, creamos un CsvMapper con nuestro CsvSchema , y finalmente, escribimos el jsonTree en nuestro archivo CSV :

CsvMapper csvMapper = new CsvMapper(); csvMapper.writerFor(JsonNode.class) .with(csvSchema) .writeValue(new File("src/main/resources/orderLines.csv"), jsonTree);

Cuando ejecutamos este código de muestra, nuestro documento JSON de ejemplo se convierte al archivo CSV esperado.

5. Leer CSV y escribir JSON

Ahora, usemos CsvMapper de Jackson para leer nuestro archivo CSV en una Lista de objetos OrderLine . Para hacer esto, primero creamos la clase OrderLine como un POJO simple:

public class OrderLine { private String item; private int quantity; private BigDecimal unitPrice; // Constructors, Getters, Setters and toString }

Usaremos los encabezados de columna en el archivo CSV para definir nuestro CsvSchema . Luego, usamos el CsvMapper para leer los datos del CSV en un MappingIterator de los objetos OrderLine :

CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader(); CsvMapper csvMapper = new CsvMapper(); MappingIterator orderLines = csvMapper.readerFor(OrderLine.class) .with(orderLineSchema) .readValues(new File("src/main/resources/orderLines.csv"));

A continuación, usaremos MappingIterator para obtener una lista de objetos OrderLine . Luego, usamos ObjectMapper de Jackson para escribir la lista como un documento JSON:

new ObjectMapper() .configure(SerializationFeature.INDENT_OUTPUT, true) .writeValue(new File("src/main/resources/orderLinesFromCsv.json"), orderLines.readAll());

Cuando ejecutamos este código de muestra, nuestro archivo CSV de ejemplo se convierte al documento JSON esperado.

6. Configuración del formato de archivo CSV

Usemos algunas de las anotaciones de Jackson para ajustar el formato del archivo CSV. Cambiaremos el encabezado de la columna 'artículo' a 'nombre' , el encabezado de la columna 'cantidad' a 'contar' , eliminaremos la columna 'precio unitario' y haremos que 'contar' sea la primera columna.

Entonces, nuestro archivo CSV esperado se convierte en:

count,name 12,"No. 9 Sprockets" 4,"Widget (10mm)"

Crearemos una nueva clase abstracta para definir el formato requerido para el archivo CSV:

@JsonPropertyOrder({ "count", "name" }) public abstract class OrderLineForCsv { @JsonProperty("name") private String item; @JsonProperty("count") private int quantity; @JsonIgnore private BigDecimal unitPrice; }

Luego, usamos nuestra clase OrderLineForCsv para crear un CsvSchema :

CsvMapper csvMapper = new CsvMapper(); CsvSchema csvSchema = csvMapper .schemaFor(OrderLineForCsv.class) .withHeader(); 

También usamos OrderLineForCsv como Jackson Mixin. Esto le dice a Jackson que use las anotaciones que agregamos a la clase OrderLineForCsv cuando procesa un objeto OrderLine :

csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class); 

Finalmente, usamos un ObjectMapper para leer nuestro documento JSON en una matriz OrderLine , y usamos nuestro csvMapper para escribir esto en un archivo CSV:

OrderLine[] orderLines = new ObjectMapper() .readValue(new File("src/main/resources/orderLines.json"), OrderLine[].class); csvMapper.writerFor(OrderLine[].class) .with(csvSchema) .writeValue(new File("src/main/resources/orderLinesReformated.csv"), orderLines); 

Cuando ejecutamos este código de muestra, nuestro documento JSON de ejemplo se convierte al archivo CSV esperado.

7. Conclusión

En este tutorial rápido, aprendimos cómo leer y escribir archivos CSV usando la biblioteca de formato de datos de Jackson. También analizamos algunas opciones de configuración que nos ayudan a que nuestros datos tengan el aspecto que queremos.

Como siempre, el código se puede encontrar en GitHub.