Crear archivo excel en Java

   Una de las cosas que debemos tener en cuenta para una aplicación es buscar la compatibilidad entre sistemas, y algo que utiliza mucho el usuario son los libros y hojas de cálculo (excel), es por eso que explicare de forma breve como crear un archivo directo desde una clase específica.

   Lo primero que debemos hacer es cargar la librería "POI" brindada por Apache, pues es quien se encargará de hacer todo el trabajo de una forma simple y sin complicaciones. Una vez hecho esto debemos importar las librerías necesarias a nuestro proyecto:
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
   Ahora el libro sobre el cual trabajaremos, le indicamos el nombre al archivo y declaramos las hojas que tendrá dicho libro:
Workbook libro = new HSSFWorkbook();
FileOutputStream archivo = new FileOutputStream("nombre_del_archivo.xls");
Sheet hoja1 = libro.createSheet("Hoja1");
Sheet hoja2 = libro.createSheet("Hoja2");
Sheet hoja3 = libro.createSheet("Hoja3");
/*
.
.
.
Podemos crear N cantidad de hojas*/
Sheet hojaN = libro.createSheet("HojaN");
   Con esto ya solo nos queda rellenar las filas y columnas de nuestro libro:
//Primero la cantidad de filas
for (int x = 0; x < 10; x++) {
  Row fila = hojaN.createRow((short)x);

  //Dentro del ciclo rellenamos las celdas para dicha hoja
  for (int i = 0; i < 10; i++) {
    Cell celda = fila.createCell((short)i);

    //Con esto indicamos el contenido de cada celda
    celda.setCellValue("El texto de la celda");
  }

}
   Por último guardamos y cerramos el archivo para evitar posibles errores:
libro.write(archivo);
archivo.close();
   Y ahora el ejemplo de como debería quedar todo:
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class excel {
  public static void main(String[] args) throws IOException {
    Workbook libro = new HSSFWorkbook();
    FileOutputStream archivo = new FileOutputStream("ejemplo.xls");
    Sheet hoja = libro.createSheet("Libro de pruebas");
    for (int x = 0; x < 20; x++) {
      Row fila = hoja.createRow((short)x);
      for (int i = 0; i < 5; i++) {
        Cell celda = fila.createCell((short)i);
        celda.setCellValue("Hola Mundo (Carlitox en la Web)");
      }
    } libro.write(archivo);
    archivo.close();
  }
}
   Esto es lo básico, sin embargo la librería tiene miles de posibilidades, para más información puedes consultar la documentación, que por cierto esta bien detallada: Busy Developers' Guide to HSSF and XSSF Features


18 Comentarios

Escribir Comentario
Anónimo
AUTOR
17 de agosto de 2013, 14:43 delete

Gracias, buen ejemplo

Responder
avatar
Anónimo
AUTOR
11 de septiembre de 2013, 17:15 delete

Buen Día
Carlos ud me puede colaborar con una inquietud que se me presenta en estos momentos?. Dicha inquietud radica en que estoy exportando desde un JTABLE a excel y el actualmente me funciona pero no he podido exportar tambien los nombres de las columnas que aparecen en el JTable, es decir si en el JTable aparece nombres, apellidos, no se han podido exportar ud me puede indicar como hacerlo?. Muchas Gracias

Responder
avatar
11 de septiembre de 2013, 22:41 delete

Ok, dejame darte una idea.... El primer ciclo define las filas, y el segundo ciclo define las celdas para esas filas, entonces lo que debes hacer es iniciar el ciclo en la fila donde deseas comenzar a escribir, los datos para dichas celdas, por ejemplo....

Si voy a colocar de primero el encabezado (títulos de columnas), luego dejaras una línea en blanco y seguirás con el resto, entonces el ciclo debe comenzar en 2, ya que la línea 0 sera para estos títulos, entonces, antes del ciclo:

Row fila = hoja.createRow(0);

// Título 1
Cell celda = fila.createCell(0);
celda.setCellValue("Col A");

//Título 2
Cell celda = fila.createCell(0);
celda.setCellValue("Col B");

Te recomiendo que hagas un ciclo "for" obteniendo los títulos y así tendrás algo mas dinámico... Saludos!!

Responder
avatar
Anónimo
AUTOR
12 de septiembre de 2013, 14:19 delete Este comentario ha sido eliminado por un administrador del blog.
avatar
12 de septiembre de 2013, 17:04 delete

He eliminado la entrada ya que me has colocado un código extremadamente largo, y no le has hecho el "parse"..... No publiques el código completo, solo lo que creas conveniente.... Saludos!!

Responder
avatar
Anónimo
AUTOR
12 de septiembre de 2013, 17:59 delete

Ok, te cuento que no manejo el mismo codigo que manejas, por eso fue que te lo envíe con el fin de que validaras si era factible encontrar una linea donde pudiese congeniar con la que pusiste en el blog. pero si no se puede mostrar ese codigo que no es muy sustancial en el programa solo exportar una tabla con un nombre cualquiera desde un boton cualquiera. De todas maneras muchas gracias por tu gran aporte

Responder
avatar
Anónimo
AUTOR
12 de septiembre de 2013, 18:07 delete

Si fuese de la forma como lo expones en que parte de este podría ir?

public Exporter(File file, List tabla, List nom_files) throws Exception{
this.file = file;
this.tabla = tabla;
this.nom_files = nom_files;
if (nom_files.size()!=tabla.size()){
throw new Exception("Error");
}
}

public boolean export(){
//boolean f =false;
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
WritableWorkbook w = Workbook.createWorkbook(out);

for (int index = 0; index < tabla.size(); index++){
JTable table = tabla.get(index);
WritableSheet s = w.createSheet(nom_files.get(index), 0);


for(int i = 0; i <table.getColumnCount() ; i++) {

for(int j = 0; j <table.getRowCount(); j++) {
Object object = table.getValueAt(j, i);
s.addCell (new Label (i, j, String.valueOf(object) ) );
}
}
}
w.write();
w.close();
out.close();
return true;
}
catch (IOException | WriteException e){
return false;
}
}

Responder
avatar
13 de septiembre de 2013, 10:08 delete

Ok, fíjate en los ciclos que tienes, uno es de filas y otro columnas, entonces tienes esto:

s.addCell (new Label (i, j, String.valueOf(object) ) );

entonces para colocar el encabezado (digamos en el bloque A1):

s.addCell (new Label (0, 0, "Mi Titulo" ) );

Con lo que el "for" ya no comienza en 0, sino que en 1 y debe ser a el "rowCount + 1".... Espero se entienda, prueba y coméntame como te fue....

Responder
avatar
Unknown
AUTOR
13 de septiembre de 2013, 17:18 delete

Carlos muchas gracias por tu orientación, me fue de gran ayuda te envío el codigo modificado por si alguien más desea tenerlo.

for(int i = 0; i <table.getColumnCount() ; i++) {
s.addCell (new Label (0, 0,"columna1" ) );
s.addCell (new Label (1, 0,"columna2" ) );
s.addCell (new Label (2, 0,"columna3" ) );
s.addCell (new Label (3, 0,"columna4" ) );
for(int j = 1; j <table.getRowCount(); j++) {
Object object = table.getValueAt(j, i);
s.addCell (new Label (i, j, String.valueOf(object) ) );
}
}

Responder
avatar
14 de septiembre de 2013, 22:27 delete

Me alegra que te sea de utilidad, cualquier otra inquietud no dudes en comentar.... Saludos!!

Responder
avatar
Unknown
AUTOR
25 de septiembre de 2013, 15:03 delete

Carlos me puedes colaborar con otra duda???
En estos momentos estoy diseñando un JFreeChart el cual emplea applicationframe pero cuando le doy en la x de la ventana para cerrar solo la ventana, me cierra la aplicación. Me puedes indicar como hacer para que solo cierre la ventana del gráfico??
Gracias.

Responder
avatar
Anónimo
AUTOR
27 de septiembre de 2013, 23:24 delete

oye amigo cuales la libreria que tenemos que bajar??
es la

poi-bin-3.9-20121203.tar.gz ( 16MB, signed)

poi-bin-3.9-20121203.zip ( 23MB, signed)

Source Distribution

poi-src-3.9-20121203.tar.gz ( 48MB, signed)

poi-src-3.9-20121203.zip ( 58MB, signed)

Responder
avatar
30 de octubre de 2013, 6:02 delete

Simplemente carga el listener o evento para "Default Close Operation" (Operación de Cierre por Defecto), y le colocas lo siguiente: MiJFrame.setDefaultCloseOperation(JFrame.LA_FUNCION)...

Donde la función puede ser "HIDE_ON_CLOSE" (lo oculta) o "DISPOSE_ON_CLOSE" (lo cierra), ambas entre los paréntesis sin comillas...

Si vas a ocultarlo para luego mostrarlo, entonces debes restaurar su estado y refrescar de la siguiente forma:

MiJFrame.getMainFrame().setVisible(true);
MiJFrame.getMainFrame().setState(Frame.NORMAL);

Responder
avatar
30 de octubre de 2013, 6:05 delete

La bin es la que necesitamos, la SRC son los fuentes en caso de que queramos desarrollar extras o necesitar ciertas funciones especiales de la librería, en todo repositorio siempre tendras los BIN (normales o necesarios) y los SRC (archivos fuente)....

Responder
avatar
Anónimo
AUTOR
11 de enero de 2014, 4:23 delete

hola queria saber si es posible crear varias hojas (no libros) de forma dinamica??

Responder
avatar
15 de enero de 2014, 18:26 delete

Recuerda que excel es un libro de hojas de cálculo que trabaja mediante filas y columnas creando celdas.... No veo la necesidad de un salto de página, si buscas algún reporte puedes probar con iReport, de cualquier si quieres un salto de página en el mismo libro, tendrás que calcular la cantidad de filas e insertarlas hasta lograr el salto... Saludos!!

Responder
avatar
Unknown
AUTOR
11 de mayo de 2021, 7:41 delete

Gracias por vuestra atención, tengo un problema al crear la hoja excel los datos numericos me los pasa como String, y necesito que pasen como double ya que son necesarios para fórmulas, gracias

Responder
avatar
7 de junio de 2021, 19:45 delete

Hola, por favor publica tu código para darte una mano, saludos!

Responder
avatar

Lamentablemente hay muchos usuarios en la red que han llegado al blog para escribir obscenidades, así que la moderación se hace necesaria. Recuerda utilizar un lenguaje correcto y espera a que sea aprobado.

Si necesitas publicar código haz click en "Conversión" para hacerlo legible.
ConversiónConversión