Ejemplo sencillo de como crear un Excel o CSV en Java con Apache POI y OpenCSV

Escrito por el , actualizado el .
blog-stack java planeta-codigo programacion
Comentarios

Los archivos Excel y separados por comas o CSV son muy utilizados como formato para intercambiar datos entre aplicaciones o como formato para exportar cantidades grandes de datos de una aplicación. Por su utilidad es probable que tarde o temprano surja en una aplicación la necesidad de crear archivos o exportar datos a estos formatos. Con la librería Apache POI se pueden crear Excel desde Java y con la librería OpenCSV exportar datos a archivos CSV con el formato correcto.

Java

La librería Apache POI nos permite acceder y crear documentos del producto ofimático Microsoft Office utilizando el lenguaje de programación Java y otros del ecosistema de la JVM. Los archivos que podemos crear y leer son documentos Word, Excel y Powerpoint.

En casi todas las aplicaciones hay necesidad de exportar los datos que maneja la aplicación a algún tipo de documento, un formato muy utilizado es el PDF sobre todo si el documento está destinado a imprimirse pero que no es el más adecuado si requiere modificaciones posteriores o contiene datos numéricos con cálculos. El formato de Excel también es muy utilizado por sus posibilidades para agrupar los datos, agregar, filtrar, hacer cálculos con funciones matemáticas, financieras o de otro tipo. Aunque si es posible es mejor utilizar un formato de documento abierto para no quitarle libertad al usuario para elegir el software que prefiera, el programa ofimático Microsoft Office sigue estando muy extendido con lo que puede que no tengamos otro remedio que utilizar como formato para exportar los datos uno propietario. En este artículo comentaré como crear un documento excel sencillo usando la librería Apache POI y el lenguaje Java.

Para trabajar con archivos xls de Excel debemos usar las clases HSSFWorkbook, HSSFSheet, HSSFRow, HSSFCell ofrecidas en la API de Apache PIO. Para crear el excel se crea una instancia de HSSFWorkbook, una o varias hojas que se corresponden con las instancias de HSSFSheet y en cada hoja se pueden acceder a las filas y celdas con createRow en la hoja y con createCell en la fila. Con el método setCellValue establecemos el valor de la celda, este método está sobrecargado y podemos establecer valores boolean, Calendar, Date, double, RichTextString o String. Hay otros métodos para cambiar los estilos de la celda con setCellStyle, setHyperlink para insertar un enlace o setCellFormula para crear una fórmula que realice algún cálculo con los datos de las celdas.

El siguiente ejemplo crea documento excel con varios datos, aplicando estilos a las cabeceras y una fórmula con el total de los precios de una lista de productos, al final escribe el excel en un archivo. En el archivo de construcción, en este caso de Gradle, debemos incluir la dependencia de la librería de Apache POI.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package io.github.picodotdev.blogbitix.holamundoapachepoi;

...

public class Main {

    private static List<Object> DATA;

    static {
        DATA = Arrays.asList(new Object[] {
            new Object[] { "PlayStation 4 (PS4) - Consola 500GB", new BigDecimal("340.95"), "https://www.amazon.es/PlayStation-4-PS4-Consola-500GB/dp/B013U9CW8A" },
            new Object[] { "Raspberry Pi 3 Modelo B (1,2 GHz Quad-core ARM Cortex-A53, 1GB RAM, USB 2.0)", new BigDecimal("41.95"), "https://www.amazon.es/Raspberry-Modelo-GHz-Quad-core-Cortex-A53/dp/B01CD5VC92/" },
            new Object[] { "Gigabyte Brix - Barebón (Intel, Core i5, 2,6 GHz, 6, 35 cm (2.5\"), Serial ATA III, SO-DIMM) Negro ", new BigDecimal("421.36"), "https://www.amazon.es/Gigabyte-Brix-Bareb%C3%B3n-Serial-SO-DIMM/dp/B00HFCTUPM/" }
        });
    }

    public static void main(String[] args) throws Exception {
        writeExcel();
        readExcel();

        writeCsv();
        readCsv();
    }

    private static void writeExcel() throws Exception {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();
        workbook.setSheetName(0, "Hoja excel");

        String[] headers = new String[]{
                "Producto",
                "Precio",
                "Enlace"
        };

        CellStyle headerStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBold(true);
        headerStyle.setFont(font);

        CellStyle style = workbook.createCellStyle();
        style.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        HSSFRow headerRow = sheet.createRow(0);
        for (int i = 0; i < headers.length; ++i) {
            String header = headers[i];
            HSSFCell cell = headerRow.createCell(i);
            cell.setCellStyle(headerStyle);
            cell.setCellValue(header);
        }

        for (int i = 0; i < DATA.size(); ++i) {
            HSSFRow dataRow = sheet.createRow(i + 1);

            Object[] d = (Object[]) DATA.get(i);
            String product = (String) d[0];
            BigDecimal price = (BigDecimal) d[1];
            String link = (String) d[2];

            dataRow.createCell(0).setCellValue(product);
            dataRow.createCell(1).setCellValue(price.doubleValue());
            dataRow.createCell(2).setCellValue(link);
        }

        HSSFRow dataRow = sheet.createRow(1 + DATA.size());
        HSSFCell total = dataRow.createCell(1);
        total.setCellType(CellType.FORMULA);
        total.setCellStyle(style);
        total.setCellFormula(String.format("SUM(B2:B%d)", 1 + DATA.size()));

        FileOutputStream file = new FileOutputStream("data.xls");
        workbook.write(file);
        file.close();
    }

    ...
}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'io.github.picodotdev.blogbitix.holamundoapachepoi.Main'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.poi:poi:4.0.0'
    compile 'com.opencsv:opencsv:4.3'

    ...
}

LibreOffice tiene la capacidad de abrir documentos excel, en la siguiente imagen se ve el documento abierto con LibreOffice Calc creado en el ejemplo.

Excel generado con Apache POI abierto con LibreOffice

Otro formato de datos muy utilizado es el de columnas separadas por comas o CSV. Con la librería OpenCSV se pueden escribir archivos bien formados en este formato teniendo en cuenta el caracter separador de las columnas y el entrecomillado de los datos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package io.github.picodotdev.blogbitix.holamundoapachepoi;

...

public class Main {

    private static List<Object> DATA;

    static {
        DATA = Arrays.asList(new Object[] {
            new Object[] { "PlayStation 4 (PS4) - Consola 500GB", new BigDecimal("340.95"), "https://www.amazon.es/PlayStation-4-PS4-Consola-500GB/dp/B013U9CW8A" },
            new Object[] { "Raspberry Pi 3 Modelo B (1,2 GHz Quad-core ARM Cortex-A53, 1GB RAM, USB 2.0)", new BigDecimal("41.95"), "https://www.amazon.es/Raspberry-Modelo-GHz-Quad-core-Cortex-A53/dp/B01CD5VC92/" },
            new Object[] { "Gigabyte Brix - Barebón (Intel, Core i5, 2,6 GHz, 6, 35 cm (2.5\"), Serial ATA III, SO-DIMM) Negro ", new BigDecimal("421.36"), "https://www.amazon.es/Gigabyte-Brix-Bareb%C3%B3n-Serial-SO-DIMM/dp/B00HFCTUPM/" }
        });
    }

    public static void main(String[] args) throws Exception {
        writeExcel();
        readExcel();

        writeCsv();
        readCsv();
    }

    ...

    private static void writeCsv() throws Exception {
        CSVWriter writer = new CSVWriter(new FileWriter("data.csv"));

        System.out.println();
        DATA.forEach(row -> {
            Object[] d = (Object[]) row;
            String product = (String) d[0];
            BigDecimal price = (BigDecimal) d[1];
            String link = (String) d[2];

            String[] line = new String[] { product, price.toString(), link };
            writer.writeNext(line);
        });

        writer.close();
    }

    ...
}

En la guía de iniciación a las características de los documentos HSSF y XSSF hay ejemplos pequeños sobre varias de las funcionalidades más comunes que necesitaremos al generar documentos. Otra funcionalidad relacionada con la escritura en el formato de estos tipos de archivos es la lectura que también es posible con estas mismas librerías, Ejemplo sencillo de cómo leer datos de un archivo Excel o CSV en Java.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew run.