Generación de ficheros «Excel» (xlsx) con ClosedXML

Tiempo de lectura: 4 minutos

closedxml

Después de llevar tiempo pensando en empezar a crear un blog, la semana pasada un compañero me pidió ayuda en un proyecto en el que necesitaban generar un excel en un servidor, el cual se enviaría al cliente, pero el servidor podía o no tener excel…

-Para para!! ¿y tu quien eres?
-Tienes razón, no me he presentado…

Antes de nada, me voy a presentar, yo soy Jorge, un apasionado de las tecnologías de Microsoft, en especial .Net y Net Core. Trabajo como ingeniero de software en una empresa especializada en soluciones industriales, y es este bagaje el que me lleva querer compartir esas cosillas que he ido aprendiendo.

Bueno, volviendo a la materia… Un compañero me pidió ayuda para generar un fichero «excel» sin necesidad de tener MS Excel, esto es algo que parece poco coherente, pero son muchas las situaciones en las que se necesita generar un documento de acceso público para programas que no necesariamente tenemos en nuestro servidor, ya sea por incompatibilidad o por ser propietarios. En este caso concreto, existe un SDK para poder hacer este trabajo, OpenXML. El principal problema de este SDK, es su pronunciada curva de aprendizaje, que hace que no sea rentable utilizarlo para usos puntuales…

Y ahí es donde entran implementaciones más ligeras como SpreadSheetLight o ClosedXML, siendo este ultimo del que vamos a utilizar hoy. Pero basta ya de hablar, y vamos a la carga!!

En primer lugar, crearemos un proyecto de consola de .Net Framweork:

Imagen planitllas

Lo siguiente que tenemos que hacer es añadir el paguete ClosedXML a traves de nuget. Esto se puede hacer a través de la «Consola de Administrador de Paquetes» con el comando:

«Install-Package ClosedXML -Version 0.93.1»

Otra opción, es utilizar el administrador que integra VS:

Teniendo ya instalado el paquete, en el propio program.cs, añadiremos el código básico del ejemplo de GitHub:

 
using ClosedXML.Excel;

namespace PostClosedXML
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var workbook = new XLWorkbook())
      {
        var worksheet = workbook.Worksheets.Add("Sample Sheet");
        worksheet.Cell("A1").Value = "Hello World!";
        worksheet.Cell("A2").FormulaA1 = "=MID(A1, 7, 5)";
        workbook.SaveAs("HelloWorld.xlsx");
      }
    }
  }
}

Esto, generará un excel llamado «HelloWorld» junto al ejecutable de la aplicación, pero obviamente, esto es un ejemplo básico en el que se ven las bondades que tiene… Es posible cargar archivos .xlsx que ya existan, pasando la ruta en el constructor y así editarlo, por ejemplo,vamos a modificar el caso anterior para cargar un excel y añadir otra pestaña llamada FixedBuffer, que contenga el lo mismo pero en mayúsculas:

 
using ClosedXML.Excel;
using System.Linq;

namespace PostClosedXML
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var workbook = new XLWorkbook("HelloWorld.xlsx"))
      {
        //Buscamos con LinQ la hohja que nos interesa copiar
        var SampleSheet = workbook.Worksheets.Where(x => x.Name == "Sample Sheet").First();
        //Añadimos una hoja nuevo
        var worksheet = workbook.Worksheets.Add("FixedBuffer");
        //Copiamos los valores
        worksheet.Cell("A1").Value = SampleSheet.Cell("A1").GetString().ToUpper();
        worksheet.Cell("A2").FormulaA1 = SampleSheet.Cell("A2").FormulaA1;
        //Guardamos el libro
        workbook.Save();
      }
    }
  }
}

Como se ve en el ejemplo anterior, podemos utilizar LinQ para movernos entre las hojas y celdas, lo cual nos facilita mucho el trabajo de acceder a zonas concretas de nuestro documento.

En futuros post, ampliaré la información sobre ClosedXML para dar estilo a celdas, generar tablas y demás.

Solo una cosa más… En este ejemplo, hemos utilizado .Net Framework, pero si echamos un vistazo rápido al repositorio de GitHub o a NuGet…

Sorpresa!!! Es compatible con .Net Standard!!!! 

¿Que quiere decir esto? Pues que podríamos utilizarlo en nuestra aplicación Net Core y ASP Net Core, puediento generar documentos xlsx en nuestro código ejecutado en cualquier plataforma (No solo en Windows)

En el este enlace puedes descargar el código del proyecto

18 comentarios en «Generación de ficheros «Excel» (xlsx) con ClosedXML»

  1. Hola Jorge. Genial la info de arriba, pero me surge una duda: para usar esta librería… ¿es necesario que la máquina tenga instalado el excel? Es decir… ¿tira por detrás de excel o es «autosuficiente» para generar un excel?
    Es porque quiero generar uno pero no me interesa tener instalado el excel en esa máquina ya que para este uso exclusivo no me interesa pagar una licencia.
    ¡Muchas gracias!

    Responder
    • Buenas tardes Javier,
      Gracias por tu comentario! Pues precisamente la ventaja de utilizar estas librerías, es que son implementaciones de OpneXml, por lo tanto no es necesario tener excel para utilizarlas. Desde que en 2007 se cambiara de .doc a .docx, xls a xlsx, etc, lo que se hizo fue cambiar del formato propietario de Microsoft a este que realmente es un xml comprimido. Eso nos permite trabajar sobre los excel sin tener el programa, ya que realmente la librería lo que hace es descomprimir el archivo, editar el xml y vovler a comprimir el archivo.

      Responder
  2. me ha servido de ha mucho muchas gracias, pero tengo una duda… como seria la forma correcta de desplazarme entre celdas con LinQ en un rango especifico ¿o no se puede?

    Responder
    • Buenos días Sebastián,
      Muchas gracias por el comentario, me alegro de que te haya servido.
      No entiendo exactamente a qué te estás refiriendo con desplazarte entre las celdas con Linq. ¿Puedes ponerme un caso?

      Responder
  3. que tal,

    tengo la siguiente situación, en mi equipo local funciona perfectamente, lo que hago inicialmente es crear una copia de mi archivo excel a una ruta dentro de mi proyecto .net, posteriormente tomo ese excel para comenzar a leerlo…posteriormente eh subudo mi proyecto a un servidor (en el cual tengo acceso via remota) y cuando intenta leerlo truena. no se si es la forma en como accedo al archivo, o tengo que especificar una forma de leer la ruta dentro del servidor. ¿has tenido un caso como el mio?. en el using es en donde no entra

    dim savePath = «~/Uploads/»
    dim fileName = «miexcel.xls»
    SAVEPATH +=filename

    Dim filePath As String = HttpContext.Current.Server.MapPath(savePath)

    Using workBook As New XLWorkbook(filePath)

    end using

    gracias
    saludos

    Responder
    • Buenas Oscar,
      La verdad es que tengo bastante oxidado el tema de VB pero yo diría que ese código que pones debería funcionar bien si el fichero que le estas indicando existe.
      Mi duda ahora mismo es si el hecho de que pongas
      SAVEPATH +=filename
      cuando la variable la has definido con
      dim savePath
      puede estar dándote algún problema.
      Tal vez puedas depurar el tema poniendo un log que te diga si el fichero existe verdaderamente y tirar desde la información que te de. El tema es que si en tu máquina funciona y en el server no, tiene pinta de ser algún tema de rutas.

      Si sigues con el problema aun así, escríbeme a través del formulario de contacto y hablamos más en detalle, porque igual me puedes mandar el código para echarle un ojo a ver si veo algo raro.

      Un saludo

      Responder
  4. HoLA Amigo, muy buen aporte, ya puse manos a la obra con esta libreria y me parece rapida y facil de usar, pero me aparecio un problema, que al parecer es poco comun, ya que no encuentro info sobre esto, quizas tu me puedas dar algun consejo.
    Cuando genero el excel lo puedo abrir, leer , modificar, etc. todo sin problemas, pero me pasa que si lo trato de importar en algunos plugins, no me reconoce el archivo correctamente y la unica forma que sea reconocido, es abrir el archivo con excel y guardar ( sin realizar ningun Cambio ) y posterior a eso, los plugins lo recocen sin problema.
    Habias escuchado algo asi ?.

    Muy agradecido.

    Saludos

    Responder
    • Buenas Manuel,
      Siento el retraso en contestar, ando un poco liadillo últimamente 🙁
      Pues la verdad es que no acabo de imaginarme porque puede ser, la especificaciones de OpenXML (el SDK que usa por debajo ClosedXML) dicen que genera un fichero xlsx igual que cualquier otro que pueda generar Excel así que no entiendo porque puede ser.
      Si quieres, mándame un mensaje a través de la sección de contacto, y empezamos a hablar por email, así me puedes enviar tu proyecto para echarle un ojo un poco más en detalle.

      Un saludo

      Responder
  5. tu contenido es estupendo, me a valido de mucho.
    ¿sERÍA POSIBLE CREAR UNA PLANTILLA PARA QUE TODOS LOS EXCELES QUE GENERASEMOS SALIERAN CON EL MISMO FORMATO?COMO UN REPORTE, CON SUS CELDAS AJUSTADAS, QUE EL COLOR DE LA CABECERA FUERA EL MISMO, QUE SIEMPRE APAREZCA UN LOGO EN EL MISMO SITIO, QUE LA TABLA TENGA LOS MISMOS BORDES… nO SE SI ME LLEGO A EXPLICAR (EL EXCEL GENERADOO DESDE CLOSEDXML).
    ¿cÓMO SE PODRÍA HACER?¿POR DONDE EMPEZAR? hE ESTADO MIRANDO DOCUMENTACION EN GITHUB PERO NO LLEGO HACER BIEN LOS EJEMPLOS DE TEMPLATE SIMPLE ¿QUIZAS NO SEA ESO?

    Responder
    • Buenas,
      Me alegro de que te haya sido útil 🙂
      La verdad, siempre que he necesitado hacer algo parecido he creado un excel a mano con el formato que quería y luego lo he ido modificando.
      Leo el template X, hago los cambios que quiero y lo guardo con el nombre Y.
      De todos modos, he visto que closedXML soporta plantillas como tal, echale un ojo porque por lo que veo son muy sencillas de usar 🙂
      Un saludo

      Responder
  6. TU CONTENIDO ES ESTUPENDO, ME A VALIDO DE MUCHO.
    ¿SERÍA POSIBLE CREAR UNA PLANTILLA PARA QUE TODOS LOS EXCELES QUE GENERASEMOS SALIERAN CON EL MISMO FORMATO? COMO UN REPORTE, CON SUS CELDAS AJUSTADAS, QUE EL COLOR DE LA CABECERA FUERA EL MISMO, QUE SIEMPRE APAREZCA UN LOGO EN EL MISMO SITIO, QUE LA TABLA TENGA LOS MISMOS BORDES… NO SE SI ME LLEGO A EXPLICAR (EL EXCEL GENERADOO DESDE CLOSEDXML).
    ¿CÓMO SE PODRÍA HACER?¿POR DONDE EMPEZAR? HE ESTADO MIRANDO DOCUMENTACION EN GITHUB PERO NO LLEGO HACER BIEN LOS EJEMPLOS DE TEMPLATE SIMPLE ¿QUIZAS NO SEA ESO?

    Responder
  7. ACABO DE ENCONTRAR ESTE POST Y ESTA MUY INTERESANTE PORQUE JUSTAMENTE ESTOY GENERANDO UN REPORTE DESDE ASP.NET MVC USANDO CLOSEXML,
    PERO TENO UNA PREGUNTA, QUIERO EXPORTAR A UN FORMATO DE EXCEL QUE SE LLAMA OPENT DOCUMENT (.ODS), Y ME GUSTARIA SABER COMO PUEDO HACERLO YA QYE HE INTENTADO DE VARIAS MANERAS Y EL ARCHIVO NO SE EXPORTA!!

    Responder
    • Hola Edeline,
      Creo que ClosedXML no soporta el formato ODS por lo que no vas a poder utilizarlo 🙁
      Si ese formato es requisito indispensable, vas a tener que ir hacia un modelo basado en otra librería que lo soporte, por ejemplo SpreadsheetLight
      Un saludo

      Responder
  8. Hola! Genial tu publicacion! Estoy haciendola en net 5.0, y al generar el archivo me aparece System.Drawing no soportado en esta plataforma, pero estoy en windows… Alguna idea para solucionar este problema? Muchas gracias!

    Responder

Deja un comentario