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
- Crear la hoja de calculo en memoria como
workbook - llenar el contenido de
workbook- obtener el modelo de la tabla como
internalModel - obtener número de filas desde
internalModel - obtener número de columnas desde
internalModel - Crear hoja como
sheet - crear encabezado en
sheet - crear resto del contenido en
sheet
- obtener el modelo de la tabla como
- 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