viernes, 15 de junio de 2012

En esta ocasión veremos cómo manejar archivos CSV en Java, para lo cual usaremos una de las diversas librerías gratuitas que se encuentran disponibles en la web. Escogí la librería javacsv porque me pareció la mas práctica y sencilla. Puedes descargar la librería con la documentación completa desde aquí. Luego, para usarla, solo tienes que adicionar a tu proyecto Java el archivo javacsv.jar.

Importar datos a una lista desde un archivo CSV


Primero crearemos una clase llamada Usuario con la siguiente estructura:

package dominio;

public class Usuario {

    private String codigo;
    private String nombres;
    private String apellidos;
    private String correo;

    public Usuario(String codigo, String nombres, String apellidos, String correo) {
        setCodigo(codigo);
        setNombres(nombres);
        setApellidos(apellidos);
        setCorreo(correo);
    }

    public String getCodigo() {
        return codigo;
    }

    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    public String getNombres() {
        return nombres;
    }

    public void setNombres(String nombres) {
        this.nombres = nombres;
    }

    public String getApellidos() {
        return apellidos;
    }

    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }

    public String getCorreo() {
        return correo;
    }

    public void setCorreo(String correo) {
        this.correo = correo;
    }
}

Luego crearemos un archivo CSV llamado usuarios_import.csv con la siguiente estructura:

Codigo, Nombres, Apellidos, Correo
2001, Jorge Luis, Garcia Sifuentes, jlgarcias@gmail.com
2002, Miguel Jose, Guevara Martinez, mguevara@yahoo.com
2003, Juan Carlos, Mendoza Cruz, jcmendoza@hotmail.com

Luego crearemos una clase que lea el archivo CSV y lo importe a nuestra lista de usuarios, tal como muestra el siguiente código:

package csv.ejemplos;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.csvreader.CsvReader;

import dominio.Usuario;

public class EjemploCsvImportacion {

    public static void main(String[] args) {
    
        try {
        
        List<usuario> usuarios = new ArrayList<usuario>();
        
        CsvReader usuarios_import = new CsvReader("test/usuarios_import.csv");
        usuarios_import.readHeaders();
        
        while (usuarios_import.readRecord())
        {
            String codigo = usuarios_import.get(0);
            String nombres = usuarios_import.get(1);
            String apellidos = usuarios_import.get("Apellidos");
            String correo = usuarios_import.get("Correo");
            
            usuarios.add(new Usuario(codigo, nombres, apellidos, correo));    
        }
        
        usuarios_import.close();
        
        for(Usuario us : usuarios){
        
            System.out.println(us.getCodigo() + " : " + us.getNombres() + " " 
            + us.getApellidos() + " - " + us.getCorreo());
        }
        
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Como podemos apreciar estamos creando una lista usuarios, luego hemos instanciado la clase CsvReader, a la cual le pasamos por parámetro la ruta del archivo CSV que queremos importar. En la línea 21 estamos leyendo la cabecera del archivo CSV, si el archivo no tuviera cabecera podríamos omitir esta línea pero al momento de pasarle los valores de los campos ya no indicaríamos el nombre de la columna (como se muestra en las líneas 27 y 28) sino el índice respectivo (como se muestra en las líneas 25 y 26). Luego hacemos uso del while para recorrer el archivo línea por línea e importar su contenido a nuestra lista de usuarios. Finalmente le indicamos que terminamos de trabajar con el archivo CSV usando el método close(). Luego recorremos la lista usuarios con un for para comprobar que se importaron exitosamente los datos de nuestro archivo CSV.

Este sería el resultado por consola:

2001 : Jorge Luis Garcia Sifuentes - jlgarcias@gmail.com
2002 : Miguel Jose Guevara Martinez - mguevara@yahoo.com
2003 : Juan Carlos Mendoza Cruz - jcmendoza@hotmail.com


Exportar datos de una lista a un archivo CSV


Para este caso, crearemos una clase que contenga el siguiente código:

package csv.ejemplos;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.csvreader.CsvWriter;

import dominio.Usuario;

public class EjemploCsvExportacion {

    public static void main(String[] args) {
    
        List<usuario> usuarios = new ArrayList<usuario>();
        
        usuarios.add(new Usuario("1001","Jose","Ramirez Torres","jramirez89@hotmail.com"));
        usuarios.add(new Usuario("1002","Saul","Gaviria Garcia","sgaviria12@gmail.com"));
        usuarios.add(new Usuario("1003","Maria","Torres Mendoza","mtorres12@yahoo.com"));
        
        String outputFile = "test/usuarios_export.csv";
        boolean alreadyExists = new File(outputFile).exists();
        
        if(alreadyExists){
            File ficheroUsuarios = new File(outputFile);
            ficheroUsuarios.delete();
        }        
        
        try {
        
            CsvWriter csvOutput = new CsvWriter(new FileWriter(outputFile, true), ',');
            
            csvOutput.write("Codigo");
            csvOutput.write("Nombres");
            csvOutput.write("Apellidos");
            csvOutput.write("Correo");
            csvOutput.endRecord();
            
            for(Usuario us : usuarios){
                
                csvOutput.write(us.getCodigo());
                csvOutput.write(us.getNombres());
                csvOutput.write(us.getApellidos());
                csvOutput.write(us.getCorreo());
                csvOutput.endRecord();                   
            }
            
            csvOutput.close();
        
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Aqui podemos apreciar que primero estamos creando nuestra lista de usuarios, a la cual le estamos añadiendo 3 usuarios. Luego definimos la ruta del archivo CSV que crearemos y consultamos si el archivo existe. Si ya existe lo eliminamos. Luego instanciamos la clase CsvWriter, a la cual le pasamos por parámetro la ruta de nuestro archivo CSV a generar. Agregamos la cabecera con los nombres de las columnas que vamos a exportar. Luego hacemos uso el for para recorrer cada elemento de la lista usuarios, en cada iteración escribimos la información que deseamos mostrar en el archivo usando el método write() y terminamos cada línea con el método endRecord(). Finalmente, fuera del for, cerramos con el método close().

El archivo CSV generado quedaría de la siguiente manera:

Codigo,Nombres,Apellidos,Correo
1001,Jose,Ramirez Torres,jramirez89@hotmail.com
1002,Saul,Gaviria Garcia,sgaviria12@gmail.com
1003,Maria,Torres Mendoza,mtorres12@yahoo.com


Espero que este blog haya sido de utilidad para ustedes, pueden descargar el ejemplo completo desde aquí.

16 comentarios:

  1. gracias me sirvio mucho tu ejemplo,
    pero ahora mi duda es si quisiera que el archivo csv se fuera modficiando a la hora de cerrar el programa y despues volverlo a abrir? , y asi no se este eliminando, intente varias formas pero me sigue agregando el nobmre de las columnas...

    kevin.s@hotmail.com

    ResponderEliminar
  2. Hola, si quieres que el archivo no se elimine cada vez, entonces intenta quitando la siguiente linea (linea 28 de la clase EjemploCsvExportacion): ficheroUsuarios.delete();

    Y luego para que no te escriba nuevamente la cabecera de las columnas, agregale una condicion para que solo cuando el archivo no tenga ningun registro se ejecuten las siguientes lineas:

    csvOutput.write("Codigo");
    csvOutput.write("Nombres");
    csvOutput.write("Apellidos");
    csvOutput.write("Correo");

    Deberia quedarte algo similar a:

    if(NroRegistros == 0){
    csvOutput.write("Codigo");
    csvOutput.write("Nombres");
    csvOutput.write("Apellidos");
    csvOutput.write("Correo");
    }

    ResponderEliminar
  3. Gracias me a servido mucho tu ayuda y pues si hice lo que me sugeriste
    y funciona , pero por ejemplo

    corro el programa, me registro una vez, escribe en el csv
    pero si vuelvo a registrarme me vuelve a copiar los 2, y asi todos se van vuelven a escribir por el for


    almenos de que me registre una vez, guarde en el csv , dejo de correr el programa, y vuelvo a correr el programa, y alli si va guardando en orden



    no se si me podrias sugerir otra cosa talvz para que a la hora de guardar en el csv e ingresar otro tenga q volver a abrir el archivo para escribir

    ResponderEliminar
  4. Ya lo logre gracias igual, solo se me ocurrio eliminar el contenido de la lista despues de que fuera a escribir, por si a alguien en un futuro le sirve.. con un .removeall

    ResponderEliminar
  5. Ok, chevere, gracias a ti por tu aporte.

    ResponderEliminar
  6. Como hago si tengo que leer varios encabezados?

    ResponderEliminar
  7. Varios encabezados? te refieres a varios archivos? o varios encabezados en un solo archivo? esto no seria recomendable, dependiendo de cual es la necesidad, tal vez necesites evaluar otra opción.

    ResponderEliminar
  8. hola, al momento de recorrer la lista, resulta que en todas las lineas está solo el último dato del archivo .csv. No encuentro por que?

    @Override
    public List detalDesdeCsv(String urlArchivoCsv) {
    // TODO Auto-generated method stub
    List listaPedido = new ArrayList();
    DetallPedCSV detalle = new DetallPedCSV();

    try {

    CsvReader leerPedido = new CsvReader("F:/servidor/archivos/"+urlArchivoCsv);
    leerPedido.setDelimiter(';');
    //leerPedido.readHeaders();

    while (leerPedido.readRecord()) {
    int codPed= Integer.parseInt(leerPedido.get(0));
    int dia = Integer.parseInt(leerPedido.get(1));
    int codArt = Integer.parseInt(leerPedido.get(2));
    int cant = Integer.parseInt(leerPedido.get(4));
    String toc = leerPedido.get(3);
    String estado = leerPedido.get(5);
    detalle.setCodPed(codPed);
    detalle.setDia(dia);
    detalle.setCodArt(codArt);
    detalle.setCant(cant);
    detalle.setToc(toc);
    detalle.setEstado(estado);

    listaPedido.add(detalle);
    //listaPedido.add(new DetallPedCSV(codPed, dia, codArt, toc, cant, estado));
    }

    leerPedido.close();

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

    public static void main(String args[]){
    ServicioBdDistri2Impl servicio = new ServicioBdDistri2Impl();

    for (DetallPedCSV elemento : servicio.detalDesdeCsv("ciclo391.csv")){
    System.out.println(elemento.getCodPed()+" "+elemento.getDia()+" "+elemento.getCodArt());
    }
    }

    ResponderEliminar
  9. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  10. Como hago para eliminar añadir caracteres en blanco en el csv sin que me añada " ?
    Por ejempleo quiero una salida así:
    1001,Jose, ,jramirez89@hotmail.com
    Pero obtengo esto:
    1001,Jose," ",jramirez89@hotmail.com
    Como hago para eliminar esas comillas?

    ResponderEliminar
    Respuestas
    1. Hola Jorge, gracias por escribir.
      Es un poco raro lo que me comentas, no entiendo bien cual seria tu necesidad de añadir un espacio en blanco.
      Lo que usualmente puedes tener seria algo como: 1001,Jose,,jramirez89@hotmail.com. Sin espacios y sin comillas si quieres pasar un campo vacio.
      Depende también con que programa abras el archivo CSV, si lo abres con excel, no verás las comillas que te aparecen cuando lo abres con notepad.

      Eliminar
    2. Yo también estoy en la misma situación. Quiero crear un CSV con campos vacíos pero siempre me añade "". ¿Cómo hago?

      Eliminar
  11. Hola cuando le doy ejecutar me salta lo sigiente...
    java.io.FileNotFoundException: File test/usuarios_import.csv does not exist.
    at com.csvreader.CsvReader.(Unknown Source)
    at com.csvreader.CsvReader.(Unknown Source)
    at com.csvreader.CsvReader.(Unknown Source)
    at csv.ejemplos.EjemploCsvImportacion.main(EjemploCsvImportacion.java:20)
    BUILD SUCCESSFUL (total time: 0 seconds)

    ResponderEliminar
  12. Que debo de hacer ayuda por favor....

    ResponderEliminar
  13. Hola, primero debes crear la carpeta "test" en tu proyecto, luego crea el archivo usuarios_import.csv, segun lo indicado.

    ResponderEliminar