lenguajes de programación

JTable a Excel: exportación con poi

Cuando haces aplicaciones swing y les pones tablas muchas veces desearías que trajeran algunas funcionalidades por defecto, aquí te enseño una: exportar tu JTable a Excel.

¿Por qué un JTable?

Si bien lo más común es exportar directamente de la base de datos, muchas veces quieres hacer modificaciones de ultimo momento, o usar una tabla como una especie de plantilla.

Apache poi, será la librería para crear archivos de Microsoft Excel desde java que usaremos debido a su popularidad, para ello agregaremos la dependencia a nuestro pom:

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>5.2.3</version>
</dependency>

Esta versión tiene algunos cambios respecto a las versiones anteriores, pero básicamente se trata de simplificar los nombres de las clases.

Algoritmo

El algoritmo consistirá en

  1. Crear la hoja de calculo en memoria como workbook
  2. llenar el contenido de workbook
    1. obtener el modelo de la tabla como internalModel
    2. obtener número de filas desde internalModel
    3. obtener número de columnas desde internalModel
    4. Crear hoja como sheet
    5. crear encabezado en sheet
    6. crear resto del contenido en sheet
  3. exportar el reporte

Fila de encabezados

private void createHeaderRow(Sheet sheet, int cols, TableModel internalModel) {
        //headers
        Row rowhead = sheet.createRow(0);
        for (int i = 0; i < cols; i++) {
            String columnName = internalModel.getColumnName(i);
            rowhead.createCell(i).setCellValue(columnName);
        }
    }

Resto del contenido

Como ya se usó la fila 0, deberemos de iniciar a partir de la 1, es por ello que aunque nuestro ciclo inicie desde 0, al numero de fila le deberemos de agregar uno para que no sobrescriba la fila de encabezados.

private void createContent(int rows, Sheet sheet, int cols, TableModel internalModel) {
        //content
        for (int i = 0; i < rows; i++) {
            Row nthrow = sheet.createRow(i + 1);
            for (int j = 0; j < cols; j++) {
                System.out.println("(" + i + "," + j + ")");
                Object cellValue = internalModel.getValueAt(i, j);
                Cell cell = nthrow.createCell(j);
                String cellValue1 = cellValue.toString();
                System.out.println("cell(" + i + "," + j + ") = {" + cellValue1 + "}");

                cell.setCellValue(cellValue1);
            }
        }
    }

En caso de que quieras usar algún estilo personalizado, como agregar controles swing o algo similar, recuerda pensar en como quieres que se exporte ese valor, en este caso estamos convirtiendo el valor de la celda a cadena para evitar extender la lógica demasiado, si deseas usar este código con tu JTable con componentes, asegúrate de sobre-escribir el método toString.

Persistir a un archivo

Para persistir, lo más común es usar un FileOutput stream que es un OutputSream, e igual que en versiones anteriores, nuestro workbook o libro de trabajo acepta un OutputStream para encargarse de serializar el objeto configurado previamente por nosotros.

private void exportReport(Workbook workbook) throws HeadlessException {
        OutputStream fileOut;
        try {
            JFileChooser chooser = new JFileChooser();
            chooser.addChoosableFileFilter(new FileNameExtensionFilter("Excel file", "xls"));
            int selection = chooser.showSaveDialog(this);
            if (selection == JFileChooser.APPROVE_OPTION) {
                fileOut = enforceExtension(chooser.getSelectedFile());
                workbook.write(fileOut);
                System.out.println("Excel File has been created successfully.");
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Demo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Demo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Asegurarse que el archivo tenga extensión

A pesar de que al usar un JFileChooser se puede agregar un filtro por extensiones, para guardar la extensión por defecto se ignora si no la especificamos, para asegurarnos que siempre tenga la extensión correcta podemos hacer lo siguiente

private OutputStream enforceExtension(File selectedFile) throws FileNotFoundException {
        String fileName = selectedFile.getAbsolutePath();
        File theFile;
        if (!fileName.endsWith(".xls")) {
            theFile = new File(fileName + ".xls");
        } else {
            theFile = selectedFile;
        }
        return new FileOutputStream(theFile);
    }

Código fuente completo

El código completo de como convertir de JTable a Excel lo puedes hallar en mi repositorio en: https://github.com/javatlacati/JTableToExcel

javatlacati

Entradas recientes

Cursos de Código Facilito

Te comparto aquí mis recomendaciones de cursos de Código Facilito. Codigofacilito.com es una plataforma virtual…

2 meses hace

Cursos de LinkedIn Learning

Te comparto aquí mis recomendaciones de cursos de Linkedin Learning. LinkedIn Learning es una plataforma…

4 meses hace

Mockito: Snippets de código

Estos snippets de código para entrevista acerca de mockito espero te sean de mucha utilidad.…

4 meses hace

Expresiones regulares en Java: analizar un String

En este tutorial aprenderá a usar expresiones regulares en Java de manera práctica para contar…

4 meses hace

Preguntas para entrevista de programación Java full-stack

¿Entrevista de programación Java fullstack? No te preocupes, te tengo un compendio de preguntas de…

5 meses hace

SoftSkills: cursos de Udemy

Te recomiendo algunos cursos de Udemy para mejorar tus softskills y así mejorar en tu…

5 meses hace