diff --git a/Business/Business.csproj b/Business/Business.csproj
index 40e6bc94..454fbe09 100644
--- a/Business/Business.csproj
+++ b/Business/Business.csproj
@@ -56,6 +56,9 @@
false
+
+ ..\packages\EPPlus.4.5.3.3\lib\net40\EPPlus.dll
+
False
..\Referencias\Iesi.Collections.dll
diff --git a/Business/Utility.cs b/Business/Utility.cs
index 3baec8ae..5518d367 100644
--- a/Business/Utility.cs
+++ b/Business/Utility.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Security.Cryptography;
using System.Configuration;
using System.Xml.Serialization;
@@ -14,6 +14,9 @@
//using Sql.Data
using System.Security.Cryptography;
+using OfficeOpenXml;
+using System.Drawing;
+using OfficeOpenXml.Style;
namespace Business
{
@@ -599,7 +602,7 @@ public DataTable getDataSet(String strSql, bool conColu)
}
return ds2.Tables[0];
}
- #region " Otros Mtodos "
+ #region " Otros Métodos "
public bool EsNumerico(string val)
{
@@ -681,12 +684,12 @@ public int VerificaPermisos(ArrayList lista, string m_Objeto)
}
- /// con
- //private const string ConSignos = "u";
+ /// con ñ
+ //private const string ConSignos = "áàäéèëíìïóòöúùuñÁÀÄÉÈËÍÌÏÓÒÖÚÙÜçÇ";
//private const string SinSignos = "aaaeeeiiiooouuunAAAEEEIIIOOOUUUcC";
- /// sin
- private const string ConSignos = "uDZ";
+ /// sin ñ
+ private const string ConSignos = "áàäéèëíìïóòöúùuÁÀÄÉÈËÍÌÏÓÒÖÚÙÜçDZ";
private const string SinSignos = "aaaeeeiiiooouuuAAAEEEIIIOOOUUUcCn";
@@ -712,11 +715,11 @@ public bool bisiesto(int anno)
bool resultado;
//Comprobamos la regla general.
//Si anno es divisible por 4, es decir, si el
- //resto de la divisin entre 4 es 0...
+ //resto de la división entre 4 es 0...
if (anno % 4 == 0)
{
//Si es divisible por 4, ahora toca comprobar
- //la excepcin
+ //la excepción
if (
(anno % 100 == 0) && //Si es divisible por 100
(anno % 400 != 0) //y no por 400
@@ -726,7 +729,7 @@ public bool bisiesto(int anno)
}
else
{
- resultado = true; //No cumple la excepcin.
+ resultado = true; //No cumple la excepción.
//Lo dejamos como bisiesto por ser divisible por 4
}
}
@@ -792,11 +795,11 @@ public string DiferenciaFechas(DateTime dn, DateTime fechaProtocolo)
{ ///calculo de fechas teniendo el cuenta los dias de los meses
DateTime da = fechaProtocolo; // DateTime.Now;
- int anos = da.Year - dn.Year; // calculamos aos
+ int anos = da.Year - dn.Year; // calculamos años
int meses = da.Month - dn.Month; // calculamos meses
- int dias = da.Day - dn.Day; // calculamos das
+ int dias = da.Day - dn.Day; // calculamos días
- //ajuste de posible negativo en $das
+ //ajuste de posible negativo en $días
if (dias < 0)
{
//--$meses;
@@ -872,6 +875,377 @@ public void CargarRadioButton(RadioButtonList buttons, String strSql, String Cam
+ #endregion
+
+ #region Excel
+
+ public static void ExportDataTableToXlsx(DataTable dataTable, string filename)
+ {
+ //Version final 29/4/26
+ // ⚠️ Si usas EPPlus v5.x o superior, descomenta esta línea:
+ // OfficeOpenXml.ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
+
+ if (dataTable.Rows.Count > 0)
+ {
+
+ HttpResponse response = HttpContext.Current.Response;
+
+ // Color finalBackColor = ColorTranslator.FromHtml("#2b3e4c"); //azul-neuquen
+ // Color fontColor = Color.White
+ using (ExcelPackage package = new ExcelPackage())
+ {
+ // Crear una nueva hoja de trabajo
+ ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(filename);
+
+ // Cargar la DataTable en la hoja de trabajo. 'true' incluye los encabezados.
+ worksheet.Cells["A1"].LoadFromDataTable(dataTable, true);
+
+ int colCount = dataTable.Columns.Count;
+
+ // --- ENCABEZADOS ---
+ for (int c = 0; c < colCount; c++)
+ {
+ worksheet.Cells[1, c + 1].Value = dataTable.Columns[c].ColumnName;
+ }
+
+ // --- DATOS ---
+ int filaExcel = 2;
+
+ foreach (DataRow row in dataTable.Rows)
+ {
+ for (int c = 0; c < colCount; c++)
+ {
+ object valor = row[c];
+ int colExcel = c + 1;
+
+ // Null o DBNull
+ if (valor == null || valor == DBNull.Value)
+ {
+ worksheet.Cells[filaExcel, colExcel].Value = "";
+ continue;
+ }
+
+ // Detectar fechas
+ if (valor != null && valor.GetType() == typeof(DateTime))
+ {
+ DateTime dt = (DateTime)valor;
+ worksheet.Cells[filaExcel, colExcel].Value = dt;
+ worksheet.Cells[filaExcel, colExcel].Style.Numberformat.Format = "dd/MM/yyyy";
+ continue;
+ }
+
+ // Detectar números por TryParse
+ double numero;
+ string texto = valor.ToString().Trim();
+
+ System.Globalization.CultureInfo cultura;
+
+ // Si tiene coma, usar cultura con coma decimal
+ if (texto.Contains(","))
+ {
+ cultura = System.Globalization.CultureInfo.GetCultureInfo("es-ES");
+ }
+ else
+ {
+ // Si tiene punto, usar cultura con punto decimal
+ cultura = System.Globalization.CultureInfo.InvariantCulture;
+ }
+
+ bool esNumero = double.TryParse(
+ texto,
+ System.Globalization.NumberStyles.Any,
+ cultura,
+ out numero
+ );
+
+ if (esNumero)
+ {
+ worksheet.Cells[filaExcel, colExcel].Value = numero;
+ }
+ else
+ {
+ worksheet.Cells[filaExcel, colExcel].Value = texto;
+ }
+
+ //formato de numero segun cantidad de decimales
+ string separador = texto.Contains(",") ? "," : ".";
+
+ int decimales = 0;
+
+ if (texto.Contains(separador))
+ {
+ decimales = texto.Split(separador[0])[1].Length;
+ }
+
+ string formato = "0";
+
+ if (decimales > 0)
+ {
+ formato += "." + new string('0', decimales);
+ }
+
+ worksheet.Cells[filaExcel, colExcel].Style.Numberformat.Format = formato;
+ }
+
+ filaExcel++;
+ }
+
+
+ // --- APLICAR ESTILO AL ENCABEZADO ---
+ int rowCount = dataTable.Rows.Count;
+ //int colCount = dataTable.Columns.Count;
+
+ // Rango del encabezado: Desde A1 hasta el final de la primera fila
+ using (var range = worksheet.Cells[1, 1, 1, colCount])
+ {
+ ExcelEstilo(range);
+ }
+
+ // Autoajusta las columnas
+ worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
+
+ //Todas las celdas
+ var range2 = worksheet.Cells[1, 1, rowCount+1, colCount]; //row+1 asi cuenta la fila del encabezado.
+ ExcelBordes(range2);
+ // --- CONFIGURAR RESPUESTA HTTP ---
+ response.Clear();
+ response.Buffer = true;
+ response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+
+ string fullFilename = filename.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase) ? filename : filename + ".xlsx";
+ response.AddHeader("Content-Disposition", $"attachment; filename=\"{fullFilename}\"");
+
+ // Escribe el paquete de Excel directamente al flujo de salida
+ package.SaveAs(response.OutputStream);
+
+ response.Flush();
+ response.End();
+ }
+ }
+
+ }
+
+ private static void ExcelEstilo(ExcelRange range, Color? backColor = null, Color? fontColor = null)
+ {
+ Color finalBackColor = backColor ?? Color.Transparent;
+ Color finalFontColor = fontColor ?? Color.Black;
+
+ if (backColor == fontColor)
+ {
+ finalBackColor = Color.Transparent;
+ finalFontColor = Color.Black;
+ }
+ range.Style.Border.BorderAround(ExcelBorderStyle.Thin);
+ range.Style.Font.Bold = true;
+ range.Style.Fill.PatternType = ExcelFillStyle.Solid;
+ range.Style.Fill.BackgroundColor.SetColor(finalBackColor);
+ range.Style.Font.Color.SetColor(finalFontColor);
+ range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
+ }
+
+ private static void ExcelBordes(ExcelRange rango)
+ {
+ rango.Style.Border.Top.Style = ExcelBorderStyle.Thin;
+ rango.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
+ rango.Style.Border.Left.Style = ExcelBorderStyle.Thin;
+ rango.Style.Border.Right.Style = ExcelBorderStyle.Thin;
+ }
+
+ public static void ExportGridViewToExcel(GridView grid, string nombreArchivo)
+ {
+ if(grid.Rows.Count > 0)
+ {
+ using (var package = new ExcelPackage())
+ {
+ var ws = package.Workbook.Worksheets.Add(nombreArchivo);
+
+ int fila = 1;
+ int col = 1;
+
+ // ================================
+ // 1) Escribir encabezados
+ // ================================
+
+ Color encabezadoColor = grid.HeaderStyle.BackColor;
+ Color fontColor = grid.HeaderStyle.ForeColor;
+
+ if (encabezadoColor == fontColor)
+ {
+ encabezadoColor = Color.Transparent;
+ fontColor = Color.Black;
+ }
+ foreach (DataControlField column in grid.Columns)
+ {
+ ws.Cells[fila, col].Value = column.HeaderText;
+ ws.Cells[fila, col].Style.Font.Size = 9;
+ ws.Cells[fila, col].Style.Font.Bold = true;
+ ws.Cells[fila, col].Style.Fill.PatternType = ExcelFillStyle.Solid;
+ ws.Cells[fila, col].Style.Fill.BackgroundColor.SetColor(encabezadoColor);
+ ws.Cells[fila, col].Style.Font.Color.SetColor(fontColor);
+ ws.Cells[fila, col].Style.Border.BorderAround(ExcelBorderStyle.Thin);
+
+ col++;
+ }
+
+ fila++;
+
+ // ================================
+ // 2) Escribir filas
+ // ================================
+ foreach (GridViewRow row in grid.Rows)
+ {
+ col = 1;
+
+ foreach (TableCell cell in row.Cells)
+ {
+ ExcelCompletarFilas(ws, cell, fila, col);
+ col++;
+ }
+
+ fila++;
+ }
+ //Todas las celdas
+ var range2 = ws.Cells[1, 1, grid.Rows.Count + 1, grid.Columns.Count];
+ ExcelBordes(range2);
+ // Autoajustar columnas
+ ws.Cells[1, 1, fila - 1, grid.Columns.Count].AutoFitColumns();
+
+ // ================================
+ // 2.2) Escribir filas del footer
+ // ================================
+
+ GridViewRow filaFooter = grid.FooterRow;
+ col = 1;
+
+ if (tieneValores(filaFooter.Cells))
+ {
+ foreach (TableCell cell in filaFooter.Cells)
+ {
+ ExcelCompletarFilas(ws, cell, fila, col, encabezadoColor, fontColor);
+ ws.Cells[fila, col].Style.Font.Bold = true;
+ ws.Cells[fila, col].Style.Fill.PatternType = ExcelFillStyle.Solid;
+ ws.Cells[fila, col].Style.Fill.BackgroundColor.SetColor(encabezadoColor);
+ ws.Cells[fila, col].Style.Font.Color.SetColor(fontColor);
+ col++;
+ }
+ ExcelBordes(ws.Cells[grid.Rows.Count + 2,1, grid.Rows.Count + 2,col-1 ]);
+ }
+
+ // ================================
+ // 3) Descargar archivo
+ // ================================
+ var response = HttpContext.Current.Response;
+
+ response.Clear();
+ response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+ response.AddHeader("content-disposition", $"attachment; filename={nombreArchivo}.xlsx");
+
+ response.BinaryWrite(package.GetAsByteArray());
+ response.End();
+ }
+ }
+
+ }
+ private static bool tieneValores(TableCellCollection footer)
+ {
+
+ foreach (TableCell cell in footer)
+ {
+ var texto = HttpUtility.HtmlDecode(cell.Text);
+ if (!string.IsNullOrEmpty(texto.Trim()))
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void ExcelCompletarFilas(ExcelWorksheet ws, TableCell cell, int fila, int col, Color? encabezadoColor = null, Color? fontColor = null)
+ {
+
+ // (1) Detectar si es número
+ // Detectar números por TryParse
+ double numero;
+ var texto = cell.Text.ToString().Trim();
+
+ System.Globalization.CultureInfo cultura;
+
+ // Si tiene coma, usar cultura con coma decimal
+ if (texto.Contains(","))
+ {
+ cultura = System.Globalization.CultureInfo.GetCultureInfo("es-ES");
+ }
+ else
+ {
+ // Si tiene punto, usar cultura con punto decimal
+ cultura = System.Globalization.CultureInfo.InvariantCulture;
+ }
+
+ bool esNumero = double.TryParse(
+ texto,
+ System.Globalization.NumberStyles.Any,
+ cultura,
+ out numero
+ );
+
+ if (esNumero)
+ {
+ ws.Cells[fila, col].Value = numero;
+ }
+ else
+ {
+ ws.Cells[fila, col].Value = HttpUtility.HtmlDecode(cell.Text);
+ }
+
+ //formato de numero segun cantidad de decimales
+ string separador = texto.Contains(",") ? "," : ".";
+
+ int decimales = 0;
+
+ if (texto.Contains(separador))
+ {
+ decimales = texto.Split(separador[0])[1].Length;
+ }
+
+ string formato = "0";
+
+ if (decimales > 0)
+ {
+ formato += "." + new string('0', decimales);
+ }
+
+ ws.Cells[fila, col].Style.Numberformat.Format = formato;
+
+ // Aplicar colores si existen
+
+
+ if (cell.BackColor != Color.Empty)
+ {
+ ws.Cells[fila, col].Style.Fill.PatternType = ExcelFillStyle.Solid;
+ ws.Cells[fila, col].Style.Fill.BackgroundColor.SetColor(cell.BackColor);
+ }
+
+ if (cell.ForeColor != Color.Empty)
+ {
+ ws.Cells[fila, col].Style.Font.Color.SetColor(cell.ForeColor);
+ }
+
+ ws.Cells[fila, col].Style.Font.Size = 9;
+
+ }
+
+ public static void GenerarColumnasGrid(GridView grid, DataTable dt)
+ {
+ if(dt.Columns.Count > 0)
+ {
+ DataColumnCollection dc = dt.Columns;
+ foreach(DataColumn column in dc)
+ {
+ BoundField columna = new BoundField();
+ columna.HeaderText = column.ColumnName;
+ grid.Columns.Add(columna);
+ }
+ }
+ }
#endregion
}
}
\ No newline at end of file
diff --git a/Business/packages.config b/Business/packages.config
index 6b05dd43..453e1b88 100644
--- a/Business/packages.config
+++ b/Business/packages.config
@@ -3,6 +3,7 @@
+
diff --git a/ImprimeLocal/ImprimeLocal.csproj b/ImprimeLocal/ImprimeLocal.csproj
index 83ed1e11..da49c845 100644
--- a/ImprimeLocal/ImprimeLocal.csproj
+++ b/ImprimeLocal/ImprimeLocal.csproj
@@ -130,12 +130,6 @@
Designer
-
-
- {4bec40cc-9614-4e0e-8f4a-dc7c933425bc}
- Business
-
-
False
@@ -148,6 +142,12 @@
false
+
+
+ {4bec40cc-9614-4e0e-8f4a-dc7c933425bc}
+ Business
+
+