Introducción: ¿por qué "sin Office" y qué hay dentro?
\n\nSi alguna vez ha buscado cómo generar un archivo Excel en C#, seguramente se ha topado con la pregunta icónica en Stack Overflow con decenas de miles de visitas. Y el principal dolor allí es la frase "without installing Microsoft Office". ¿Por qué? Porque arrastrar objetos COM, depender de la versión de Excel en el servidor y encontrarse con errores como "Retrieving the COM class factory for component... failed" es un camino al infierno para cualquier desarrollador.
\n\nPero entonces, ¿cómo se crean archivos .XLSX y .XLS? La respuesta está en cómo está estructurado el propio formato. El Excel moderno (desde 2007) es simplemente un archivo ZIP con archivos XML dentro. Sí, no oyó mal: tome cualquier .xlsx, cámbiele el nombre a .zip, ábralo y verá las carpetas xl, _rels, docProps y un montón de documentos XML. Cada hoja, cada celda, cada estilo es un XML cuidadosamente estructurado. Y el antiguo formato .XLS es un formato binario (BIFF), pero también existen soluciones de código abierto para él.
En este artículo, miraremos bajo el capó de este proceso: analizaremos las bibliotecas populares, escribiremos código real y entenderemos qué sucede realmente cuando llamamos a Save(). ¡Allá vamos!
1. Los tres pilares de C# para trabajar con Excel sin Office
\n\nHoy en día, hay tres contendientes principales que resuelven el problema "de fábrica". Cada uno trabaja directamente con el formato, sin pasar por Office instalado.
\n\n1.1. EPPlus (licencia LGPL / Propietaria)
\nLa biblioteca más popular para .NET. Originalmente era gratuita, pero desde la versión 5.0 pasó a una licencia paga para uso comercial. Sin embargo, para fines educativos y proyectos pequeños todavía se puede usar (la versión 4.5.3.3 es la última gratuita). EPPlus solo funciona con .XLSX.
\n\nCómo funciona bajo el capó: EPPlus usa System.IO.Packaging (el mismo archivo ZIP) y genera archivos XML de acuerdo con la especificación Office Open XML (OOXML). Puede crear estilos, fórmulas, gráficos: todo lo que ve en Excel.
1.2. ClosedXML
\nGratuita, de código abierto (licencia MIT). También funciona solo con .XLSX. Se distingue por una API muy amigable que recuerda a trabajar con el propio Excel: trabaja con Workbook, Worksheet, Cell. Bajo el capó, es el mismo Open XML, pero ClosedXML se encarga de toda la rutina de crear la estructura XML.
1.3. NPOI
\nPuerto de la famosa biblioteca Java Apache POI. La principal ventaja es que puede trabajar tanto con .XLSX (a través de XSSFWorkbook) como con el antiguo .XLS (a través de HSSFWorkbook). Gratuito, de código abierto (Apache 2.0). Ideal si necesita soporte para formatos heredados.
\n\nBajo el capó para .XLS: NPOI escribe directamente datos binarios en formato BIFF8. Esto es más complejo que XML, pero no requiere compresión.
\n\n2. Escribimos código: creamos un archivo Excel de tres maneras
\n\nVamos a crear un informe simple con encabezados y datos. A continuación, ejemplos para cada biblioteca.
\n\n2.1. Ejemplo con ClosedXML (el más sencillo)
\n\nusing ClosedXML.Excel;\n\n// Creamos el libro\nusing (var workbook = new XLWorkbook())\n{\n // Agregamos una hoja\n var worksheet = workbook.Worksheets.Add("Informe");\n\n // Encabezados\n worksheet.Cell(1, 1).Value = "Nombre";\n worksheet.Cell(1, 2).Value = "Edad";\n worksheet.Cell(1, 3).Value = "Ciudad";\n\n // Datos\n worksheet.Cell(2, 1).Value = "Ana";\n worksheet.Cell(2, 2).Value = 28;\n worksheet.Cell(2, 3).Value = "Madrid";\n\n worksheet.Cell(3, 1).Value = "Iván";\n worksheet.Cell(3, 2).Value = 35;\n worksheet.Cell(3, 3).Value = "San Petersburgo";\n\n // Estilo para los encabezados\n var headerRange = worksheet.Range("A1:C1");\n headerRange.Style.Font.Bold = true;\n headerRange.Style.Fill.BackgroundColor = XLColor.LightGray;\n\n // Autoajuste del ancho de columnas\n worksheet.Columns().AdjustToC