Professional Documents
Culture Documents
Capítulo 1
Un Excel vacía
Ahora voy a crear una Excel, con un libro y una hoja, con
ambas librerías.
INTEROP
1
2 using System.IO;
3 using OfficeOpenXml;
4
5 namespace GenbetaDevExcel
{
6
public class ExcelConEPPlus
7 {
8 public ExcelPackage CreaNuevaExcelConEPPlus()
9 {
10 ExcelPackage excel = new ExcelPackage(new FileInfo(@"C:\Users\Juan\De
excel.Workbook.Worksheets.Add("NombreHoja");
11 excel.Save();
12
13 return excel;
14 }
15 }
16 }
17
Lo primero que he observado al hacer este ejemplo es que la
sintaxis de Interop es más completa pero más compleja.
Siendo necesario cerrar explícitamente el fichero después de su
creación, y aumentando la complejidad en el caso de que quiera
darle un nombre inicial a la hoja que obliga (ambas dos librerías)
añadir al libro de trabajo.
1
2
3 using System;
4 using Microsoft.VisualStudio.TestTools.UnitTesting;
5
namespace GenbetaDevExcel
6 {
7 [TestClass]
8 public class CreaExcelTest
9 {
10 [TestMethod]
public void CreaNuevaExcel_con_Interop()
11 {
12 var constructor = new ExcelConInterop();
13
14 var excel = constructor.CreaNuevaExcelConInterop();
15
16 Assert.IsNotNull(excel);
}
17
18 [TestMethod]
19 public void CreaNuevaExcel_con_EPPlus()
20 {
21 var constructor = new ExcelConEPPlus();
22
23 var excel = constructor.CreaNuevaExcelConEPPlus();
24
Assert.IsNotNull(excel);
25 }
26 }
27 }
28
29
En la realidad casi nunca se trabaja con documentos Excel
nuevos, más bien lo que se hace es comprobar con la
librería System.IO si el fichero existe; abriéndolo, en la mayoría de
los casos, o creándolo si así fuera necesario.
Con este código he completado los tres primeros puntos del índice
de ejemplos que voy a realizar en esta mini serie. En el siguiente
capítulo voy a seleccionar y grabar datos en celdas de la Excel y, si
no se alarga en demasía, introducir formulas.
EPPlus, o como tratar en C# con Excel en OpenXML y no morir con Interop.
Capitulo II
?
1
2 using System.IO;
3
4 namespace GenbetaDevExcel
5 {
6 public class Utilidades
{
7 public static void BorraFichero(string path)
8 {
9 if (! string.IsNullOrWhiteSpace(path))
10 {
if (File.Exists(path))
11 { File.Delete(path); }
12 }
13 }
14 }
15 }
16
Lo siguiente que hago es desacoplar el método de guardar, para
que sea el test quien decida cuando lanzarlo y dar por acabado el
flujo de operaciones. Fíjate que en Interop, invoco el
BorraFichero() justo antes de salvar, en cambio en EPPlus no.
INTEROP
1
2 public bool GuardaExcel(Excel.Application excel)
3 {
4 try
{
5 var fichero = @"C:\Users\Juan\Desktop\ExcelInterop.xlsx";
6 Utilidades.BorraFichero(fichero);
7
8 string workbookPath = fichero;
9
10 excel.Workbooks[1].SaveAs(workbookPath);
11 excel.Workbooks[1].Close();
12
return true;
13 }
14 catch (System.Exception)
15 { return false; }
16 }
17
EPPlus
1
2 public bool GuardaExcel(ExcelPackage excel)
{
3 try
4 {
5 excel.Save();
6 return true;
7 }
catch (System.Exception)
8 { return false; }
9 }
10
Habiendo sacado el proceso de guardar, y añadiendo el borrado
al inicio del código de EPPlus, los métodos de Abrir la Excel han
quedado así.
INTEROP
1
2 public ExcelPackage CreaNuevaExcelConEPPlus()
{
3 string fichero = @"C:\Users\Juan\Desktop\ExcelEPPlus.xlsx";
4 Utilidades.BorraFichero(fichero);
5
6 ExcelPackage excel = new ExcelPackage(new FileInfo(fichero));
7 excel.Workbook.Worksheets.Add("hoja1");
excel.Workbook.Worksheets.Add("hoja2");
8
9 return excel;
10 }
11
Una curiosidad es el orden en que se insertan las nuevas hojas en
el libro de trabajo. En EPPlus las va añadiendo a la última posición
con el nombre que le he introducido, en cambio en Interop se
añaden siempre en la segunda posición a partir del inicio, y le
pone el nombre (en español) hojaXXXX, donde XXXX es un
número autoincremental.
1
public Excel.Application EscribeEnRangoDeCeldas(Excel.Application excel)
2 {
3 Excel.Worksheet hojaActual = excel.Workbooks[1].Worksheets[1];
4 hojaActual.Cells.get_Range("A1").Value2 = "Esto funciona!";
5
6 var rangoDeCeldas = hojaActual.Cells.get_Range("$C$1:$C$3");
7 rangoDeCeldas = hojaActual.Cells.get_Range("C1:C3");
8
return excel;
9 }
10
EPPlus
1
public ExcelPackage EscribeEnRangoDeCeldas(ExcelPackage excel)
2
{
3 var hojaActual = excel.Workbook.Worksheets["hoja1"];
4 hojaActual = excel.Workbook.Worksheets[1];
5
6 hojaActual.Cells["A1"].Value = "Esto funciona!";
7 var rangoDeCeldas = hojaActual.Cells["C1:C3"];
rangoDeCeldas = hojaActual.Cells["$C$1:$C$3"];
8
9 return excel;
10 }
11
Para comprobar que el funcionamiento es correcto, he realizado
dos test que lanzan la creación de la Excel, realizan el método de
escribir y salvan.
INTEROP
?
[TestMethod]
1
public void EscribeEnRangoDeCeldas_con_Interop()
2 {
3 var constructor = new ExcelConInterop();
4 var excel = constructor.CreaNuevaExcelConInterop();
5
6 constructor.EscribeEnRangoDeCeldas(excel);
constructor.GuardaExcel(excel);
7
8 Assert.IsNotNull(excel);
9 }
10
11
EPPlus
1
2 [TestMethod]
public void EscribeEnRangoDeCeldas_con_EPPlus()
3 {
4 var constructor = new ExcelConEPPlus();
5 var excel = constructor.CreaNuevaExcelConEPPlus();
6
7 constructor.EscribeEnRangoDeCeldas(excel);
constructor.GuardaExcel(excel);
8
9 Assert.IsNotNull(excel);
10 }
11
Para no darle complejidad al código la forma de comprobar que
ha escrito correctamente es abrir la Excel y revisar que sea así.
Introduciendo fórmulas
¿Qué sería de Excel si no fuera por las fórmulas? Sin duda no
tendría sentido una hoja de cálculo sin poder introducir
definiciones de operaciones. Así voy a introducir dos valores en
dos celdas, y en una tercera inserto la formula que suma ambos
valores.
Aquí ambas sintaxis son muy parecidas, siempre un poco más fea
la de Interop. En cambio la obligación de tener un Excel completo
instalado en la máquina donde se ejecuta el código – el mayor
inconveniente de esta forma de trabajar, y más con servidores
cloud en PaaS – es que permite hacer cosas que EPPlus no.
INTEROP
1
public Excel.Application SumaDosCeldas(Excel.Application excel)
2 {
3 Excel.Worksheet hojaActual = (Excel.Worksheet) excel.Workbooks[1].Worksheets
4
5 hojaActual.Cells.get_Range("A5").Value2 = "150";
6 hojaActual.Cells.get_Range("B5").Value2 = "100";
7 hojaActual.Cells.get_Range("A10").Formula = "=SUM(A5:B5)";
8
return excel;
9 }
10
EPPlus
1
public ExcelPackage SumaDosCeldas(ExcelPackage excel)
2
{
3 var hojaActual = excel.Workbook.Worksheets["hoja1"];
4 hojaActual = excel.Workbook.Worksheets[1];
5
6 hojaActual.Cells["A5"].Value = 150;
7 hojaActual.Cells["B5"].Value = 100;
hojaActual.Cells["A10"].Formula = "=SUM(A5:B5)";
8
9 return excel;
10 }
11
La principal, para mi gusto, es que como EPPlus no incorpora un
motor de cálculo, no puedo recuperar el valor del resultado de
una celda que contiene una fórmula. Cosa que con Interop sí que
puedo.
INTEROP
1
2 [TestMethod]
public void SumaDosCeldas_con_Interop()
3
{
4 //** Interop deja recuperar el valor del resultado de la formula
5 //** EEPlus, no.
6 var constructor = new ExcelConInterop();
7 var excel = constructor.CreaNuevaExcelConInterop();
constructor.SumaDosCeldas(excel);
8 constructor.GuardaExcel(excel);
9
10 Assert.IsNotNull(excel);
11 }
12
EPPlus
1
2 [TestMethod]
public void SumaDosCeldas_con_EPPlus()
3 {
4 var constructor = new ExcelConEPPlus();
5 var excel = constructor.CreaNuevaExcelConEPPlus();
6 constructor.SumaDosCeldas(excel);
constructor.GuardaExcel(excel);
7
8 Assert.IsNotNull(excel);
9 }
10
Y para comprobar que la suma está bien y que resulta en 250, lo
que hago es abrir los ficheros.
Ahora dejo para el siguiente capítulo, y posiblemente final, algo
un poco más avanzado y que es el introducir una imagen y una
gráfica en la hoja.