CSV API para Java [cerrado]


164

¿Alguien puede recomendar una API simple que me permita usar leer un archivo de entrada CSV, hacer algunas transformaciones simples y luego escribirlo?

Un google rápido ha encontrado http://flatpack.sourceforge.net/ que parece prometedor.

Solo quería comprobar qué están usando los demás antes de acoplarme a esta API.


Utilice el intercambio de la pila de recomendaciones de software del sitio hermano cuando solicite sugerencias en una biblioteca de software. Tiene varios éxitos para Java y CSV .
Basil Bourque

Respuestas:


32

Apache Commons CSV

Echa un vistazo a Apache Common CSV .

Esta biblioteca lee y escribe varias variaciones de CSV , incluido el estándar RFC 4180 . También lee / escribe archivos delimitados por tabuladores .

  • Sobresalir
  • InformixUnload
  • InformixUnloadCsv
  • MySQL
  • Oráculo
  • PostgreSQLCsv
  • PostgreSQLText
  • RFC4180
  • TDF

Utilicé el CSV común de espacio aislado durante bastante tiempo y nunca tuve un problema. Realmente espero que lo promocionen y lo saquen de la caja de arena.
Alex Marshall

3
@ bmatthews68 el enlace sandbox está desactivado - parece que se ha movido a apache commons propiamente dicho (también
edité


83

He usado OpenCSV en el pasado.

import au.com.bytecode.opencsv.CSVReader;

String fileName = "data.csv";
CSVReader reader = nuevo CSVReader (nuevo FileReader (fileName));

// si la primera línea es el encabezado Cadena [] encabezado = reader.readNext ();
// iterar sobre reader.readNext hasta que devuelva nulo Cadena [] línea = reader.readNext ();

Había algunas otras opciones en las respuestas a otra pregunta .


Desafortunadamente, la última descarga de OpenCSV (v2.2 al momento del comentario) no se compila, y no proporcionan un binario preconstruido.
opiato

9
El paquete que descargué de SourceForge tenía un binario en la carpeta de implementación.
Mike Sickler 01 de

8
Si está utilizando Maven, tenga en cuenta que el código de dependencia en el sitio web oficial contiene la declaración de versión "2.0" que tiene algunos errores, pero hay una versión actualizada 2.3 en los repositorios.
broundee

esta lib no escribe el archivo en un hilo separado, ¿no?
Ewoks

3
de acuerdo con github.com/uniVocity/csv-parsers-comparison en promedio 73% más lento que uniVocity ..
Ewoks

32

Actualización: El código en esta respuesta es para Super CSV 1.52. Se pueden encontrar ejemplos de códigos actualizados para Super CSV 2.4.0 en el sitio web del proyecto: http://super-csv.github.io/super-csv/index.html


El proyecto SuperCSV admite directamente el análisis y la manipulación estructurada de las celdas CSV. En http://super-csv.github.io/super-csv/examples_reading.html encontrará, por ejemplo,

dado una clase

public class UserBean {
    String username, password, street, town;
    int zip;

    public String getPassword() { return password; }
    public String getStreet() { return street; }
    public String getTown() { return town; }
    public String getUsername() { return username; }
    public int getZip() { return zip; }
    public void setPassword(String password) { this.password = password; }
    public void setStreet(String street) { this.street = street; }
    public void setTown(String town) { this.town = town; }
    public void setUsername(String username) { this.username = username; }
    public void setZip(int zip) { this.zip = zip; }
}

y que tiene un archivo CSV con un encabezado. Asumamos el siguiente contenido

username, password,   date,        zip,  town
Klaus,    qwexyKiks,  17/1/2007,   1111, New York
Oufu,     bobilop,    10/10/2007,  4555, New York

Luego puede crear una instancia de UserBean y llenarla con valores de la segunda línea del archivo con el siguiente código

class ReadingObjects {
  public static void main(String[] args) throws Exception{
    ICsvBeanReader inFile = new CsvBeanReader(new FileReader("foo.csv"), CsvPreference.EXCEL_PREFERENCE);
    try {
      final String[] header = inFile.getCSVHeader(true);
      UserBean user;
      while( (user = inFile.read(UserBean.class, header, processors)) != null) {
        System.out.println(user.getZip());
      }
    } finally {
      inFile.close();
    }
  }
}

utilizando la siguiente "especificación de manipulación"

final CellProcessor[] processors = new CellProcessor[] {
    new Unique(new StrMinMax(5, 20)),
    new StrMinMax(8, 35),
    new ParseDate("dd/MM/yyyy"),
    new Optional(new ParseInt()),
    null
};

1
Su código no se compilaría, así que envié algunas correcciones. Además, ParseDate () no funciona correctamente, así que lo reemplacé para leer una cadena. Se puede analizar más tarde.

1
Gran limitación: SuperCSV no es seguro para subprocesos, voy a buscar a Jackson, aunque puede tener más funciones limitadas
ZiglioUK

SuperCsv tampoco permite usar multimapas. Sería bueno verlo funcionar con MultiMaps.
Sid

19

Leer la descripción del formato CSV me hace sentir que usar una biblioteca de terceros sería menos dolor de cabeza que escribirlo yo mismo:

Wikipedia enumera 10 o algo conocidas bibliotecas:

Comparé las bibliotecas enumeradas usando algún tipo de lista de verificación. OpenCSV resultó ser un ganador para mí (YMMV) con los siguientes resultados:

+ maven

+ maven - release version   // had some cryptic issues at _Hudson_ with snapshot references => prefer to be on a safe side

+ code examples

+ open source   // as in "can hack myself if needed"

+ understandable javadoc   // as opposed to eg javadocs of _genjava gj-csv_

+ compact API   // YAGNI (note *flatpack* seems to have much richer API than OpenCSV)

- reference to specification used   // I really like it when people can explain what they're doing

- reference to _RFC 4180_ support   // would qualify as simplest form of specification to me

- releases changelog   // absence is quite a pity, given how simple it'd be to get with maven-changes-plugin   // _flatpack_, for comparison, has quite helpful changelog

+ bug tracking

+ active   // as in "can submit a bug and expect a fixed release soon"

+ positive feedback   // Recommended By 51 users at sourceforge (as of now)

8

Usamos JavaCSV , funciona bastante bien


3
El único problema con esta biblioteca es que no le permitirá generar archivos CSV con terminadores de línea de Windows ( \r\n) cuando no se ejecuta en Windows. El autor no ha brindado apoyo durante años. Tuve que bifurcarlo para permitir esa característica faltante: JavaCSV 2.2
Mosty Mostacho

6

Para la última aplicación empresarial en la que trabajé que necesitaba manejar una cantidad notable de CSV, hace un par de meses, usé SuperCSV en sourceforge y lo encontré simple, robusto y sin problemas.


+1 para SuperCSV, pero tiene algunos errores desagradables que aún no se han solucionado, los errores nuevos no se manejan actualmente y la última versión tiene casi dos años. Pero estamos usando una versión parcheada / modificada en producción sin ningún problema.
MRalwasser

2
@MRalwasser Super CSV 2.0.0-beta-1 ha sido lanzado recientemente. Incluye muchas correcciones de errores y nuevas características (incluido el soporte de Maven y una nueva extensión de Dozer para mapear propiedades anidadas y matrices / Colecciones)
James Bassett

1
@ Hound-Dog Gracias por la actualización, ya me di cuenta de la nueva versión beta y me alegra ver el proyecto vivo, aunque la frecuencia de las confirmaciones todavía me teme un poco (casi todas las confirmaciones solo en unos días). Pero voy a echar un vistazo. ¿Hay una fecha estimada de lanzamiento de la versión 2.0 final?
MRalwasser

2
@MRalwasser Soy el único desarrollador en este momento y tengo trabajo a tiempo completo, así que tiendo a trabajar en esto cada vez que obtengo un fin de semana gratuito, de ahí las confirmaciones esporádicas :) Casi 1000 descargas SF de la versión beta ahora, y sin errores, así que en camino a un lanzamiento final a principios del próximo mes. Si tiene alguna idea para futuras funciones, háganoslo saber.
James Bassett

1
SuperCSV no es seguro para subprocesos en esta etapa, eso hace que no sea realmente robusto en mi opinión
ZiglioUK

5

Puede usar la aplicación y la descarga de csvreader desde la siguiente ubicación:

http://sourceforge.net/projects/javacsv/files/JavaCsv/JavaCsv%202.1/javacsv2.1.zip/download

o

http://sourceforge.net/projects/javacsv/

Utiliza el siguiente código:

/ ************ For Reading ***************/

import java.io.FileNotFoundException;
import java.io.IOException;

import com.csvreader.CsvReader;

public class CsvReaderExample {

    public static void main(String[] args) {
        try {

            CsvReader products = new CsvReader("products.csv");

            products.readHeaders();

            while (products.readRecord())
            {
                String productID = products.get("ProductID");
                String productName = products.get("ProductName");
                String supplierID = products.get("SupplierID");
                String categoryID = products.get("CategoryID");
                String quantityPerUnit = products.get("QuantityPerUnit");
                String unitPrice = products.get("UnitPrice");
                String unitsInStock = products.get("UnitsInStock");
                String unitsOnOrder = products.get("UnitsOnOrder");
                String reorderLevel = products.get("ReorderLevel");
                String discontinued = products.get("Discontinued");

                // perform program logic here
                System.out.println(productID + ":" + productName);
            }

            products.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

Escribir / anexar al archivo CSV

Código:

/************* For Writing ***************************/

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.csvreader.CsvWriter;

public class CsvWriterAppendExample {

    public static void main(String[] args) {

        String outputFile = "users.csv";

        // before we open the file check to see if it already exists
        boolean alreadyExists = new File(outputFile).exists();

        try {
            // use FileWriter constructor that specifies open for appending
            CsvWriter csvOutput = new CsvWriter(new FileWriter(outputFile, true), ',');

            // if the file didn't already exist then we need to write out the header line
            if (!alreadyExists)
            {
                csvOutput.write("id");
                csvOutput.write("name");
                csvOutput.endRecord();
            }
            // else assume that the file already has the correct header line

            // write out a few records
            csvOutput.write("1");
            csvOutput.write("Bruce");
            csvOutput.endRecord();

            csvOutput.write("2");
            csvOutput.write("John");
            csvOutput.endRecord();

            csvOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}


2

El formato CSV suena bastante fácil para StringTokenizer pero puede volverse más complicado. Aquí en Alemania se usa un punto y coma como delimitador y las celdas que contienen delimitadores necesitan escapar. No lo manejarás tan fácilmente con StringTokenizer.

Yo iría por http://sourceforge.net/projects/javacsv


0

Si tiene la intención de leer CSV de Excel, entonces hay algunos casos interesantes de esquina. No puedo recordarlos a todos, pero el csv de apache commons no era capaz de manejarlo correctamente (con, por ejemplo, URL).

Asegúrese de probar la salida de Excel con comillas, comas y barras en todo el lugar.


La biblioteca CSV de Apache Commons ofrece una variante específica para Microsoft Excel . No sé si eso ahora maneja los problemas que mencionas o no.
Basil Bourque
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.