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

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

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

6 pensamientos en “Generación de ficheros «Excel» (xlsx) con ClosedXML

    1. JorTurFer Autor

      Buenas Jose, gracias por tu comentario,

      Puedes proteger y desproteger utilizando si conoces la contraseña:
      ObjetoLibro.Unprotect(string Contraseña);
      ObjetoLibro.Protect(string Contraseña);
      ObjetoHoja.Unprotect(string Contraseña);
      ObjetoHoja.Protect(string Contraseña);

      Como ves, puedes proteger y desproteger a nivel de libro completo o a nivel de hoja, como mejor te venga.
      Te dejo un enlace al ejemplo de la documentación oficial, pero si tienes déjame un mensaje en la sección de «Contacto» explicándome la duda y lo miramos bien.

  1. Javier Caldevilla

    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!

    1. JorTurFer Autor

      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.

  2. Sebastian camacho muñoz

    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?

    1. JorTurFer Autor

      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?

Deja un comentario