Ejemplo del excel a cargar.
-------------------------------------------------------------------------------
.aspx que contiene control de carga y el boton cargar.
-------------------------------------------------------------------------------
<%@ Page Title="Carga Contratos Cuotas" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="CargaContratosCuotas.aspx.cs" Inherits="LeaseOperWeb.Paginas.AdmContratos.AdmCtos.CargaContratosCuotas" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<link href="../../../css/style-css.css" rel="stylesheet" type="text/css" />
<%--<link href="../../../Style/Site2.css" rel="stylesheet" type="text/css" />--%>
<script src="../../../Scripts/JSValidadores.js" type="text/javascript"></script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="HeaderContent" runat="server">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td valign="top" id="td-descrip">
<!-------------------------------titulo y miga de pan-------------------------->
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td> </td>
</tr>
<tr>
<td class="td-titulos">
Carga Contratos / Cuotas
</td>
</tr>
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="40"> </td>
<td class="lin-borde"> </td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="mig">
Administración de Contratos / Carga Contratos / Cuotas
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top"> </td>
</tr>
<tr>
<td valign="top">
<!---------------------------------Formulario de carga-------------------------------->
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10"> </td>
<td>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="borde">
<tr>
<td>
<div class="modul">
<div class="modul_top">
<div class="modul_top_right">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="9"></td>
<td class="modul_fd">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="modul_fd_tit">
CARGA CONTRATOS / CUOTAS
</td>
</tr>
</table>
</td>
<td width="9"></td>
</tr>
</table>
</div>
</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="modul_bordes">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="caja-datos">
<tr>
<td width="10"></td>
<td height="10"></td>
<td></td>
</tr>
<tr>
<td width="10" rowspan="3"></td>
<td align="center">
<asp:RadioButtonList ID="rbCargaOpciones" runat="server" RepeatDirection="Horizontal">
<asp:ListItem Text="Carga Contratos" Value="Contratos" Selected="True"></asp:ListItem>
<asp:ListItem Text="Carga Cuotas" Value="Cuotas"></asp:ListItem>
</asp:RadioButtonList>
<br />
<!-- Control de carga de archivo Excel -->
<asp:FileUpload ID="fuExcel" runat="server" AllowMultiple="false" />
<asp:Label ID="lblFileTypeError" runat="server" Text="Solo se permiten archivos .xlsx" ForeColor="Red" Visible="false"></asp:Label>
<br />
<asp:Button ID="btnCargar" runat="server" Text="Cargar Excel" OnClick="btnCargar_Click" CssClass="btn_excel" />
</td>
<td width="10" rowspan="3"></td>
</tr>
<tr>
<td height="10" align="center">
<asp:Label ID="lblResultado" runat="server" Text=""></asp:Label>
</td>
</tr>
<tr>
<td height="10" align="right"> </td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<div class="modul_bottom">
<div class="modul_bottom_right">
<div class="modul_borde-bottom"></div>
</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td width="10"> </td>
</tr>
</table>
</td>
</tr>
<tr>
<td valign="top"> </td>
</tr>
<tr>
<td valign="top"> </td>
</tr>
<tr>
<td valign="top"></td>
</tr>
</table>
</asp:Content>
-------------------------------------------------------------------------------
.cs que contiene la carga, y validacion de solo archivos xlsx.
-------------------------------------------------------------------------------
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using LeaOperBussinesLayer.BussinesComponents.AdminContract.AdmCtos;
using LeaOperBussinesLayer.BussinesEntities.AdminContract.AdmCtos;
using LeaseOperWeb.Negocio.Comun;
namespace LeaseOperWeb.Paginas.AdmContratos.AdmCtos
{
public partial class CargaContratosCuotas : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var usuario = (UserSessionObjectBc)Session["UserSessionObjectBc"];
if (usuario == null)
{
lblResultado.ForeColor = Color.Red;
lblResultado.Text = "Se ha perdido la Sesión, ingrese nuevamente al sistema";
}
}
}
protected void btnCargar_Click(object sender, EventArgs e)
{
if (rbCargaOpciones.SelectedValue == "Cuotas")
{
CargaCuotas();
}
else
{
CargaContratos();
}
}
private void CargaContratos()
{
lblResultado.Text = "throw new NotImplementedException();";
}
protected void CargaCuotas()
{
// Recuperamos el objeto de sesión del usuario actual
var usuario = (UserSessionObjectBc)Session["UserSessionObjectBc"];
// Verificamos si el archivo de Excel ha sido cargado
if (fuExcel.HasFile)
{
// Obtenemos la extensión del archivo y lo convertimos a minúsculas
string fileExtension = Path.GetExtension(fuExcel.FileName).ToLower();
// Verificamos que la extensión sea .xlsx (formato de Excel válido)
if (fileExtension == ".xlsx")
{
try
{
// Abrimos el archivo Excel usando ExcelPackage
using (var package = new ExcelPackage(fuExcel.PostedFile.InputStream))
{
List<CargaCuotas> cuotas = new List<CargaCuotas>(); // Lista para almacenar las cuotas cargadas
bool errorEncontrado = false; // Bandera para detectar errores
string mensajeError = string.Empty; // Mensaje de error
bool encabezadosProcesados = false; // Bandera para verificar si se encontraron encabezados
// Iteramos sobre cada hoja del archivo Excel
foreach (var worksheet in package.Workbook.Worksheets)
{
// Verificamos si la hoja tiene datos
if (worksheet.Dimension != null)
{
int rowCount = worksheet.Dimension.End.Row; // Número total de filas en la hoja
int colCount = worksheet.Dimension.End.Column; // Número total de columnas en la hoja
int headerRow = 1; // Fila de encabezado por defecto
bool encabezadosEncontrados = false; // Bandera para detectar si se encontraron los encabezados
// Iteramos por cada fila buscando los encabezados
for (int row = 1; row <= rowCount; row++)
{
// Verificamos que los encabezados coincidan con los nombres esperados
if (worksheet.Cells[row, 1].Text.Trim() == "Numero Operación" &&
worksheet.Cells[row, 2].Text.Trim() == "Nº Rentas" &&
worksheet.Cells[row, 3].Text.Trim() == "Mes" &&
worksheet.Cells[row, 4].Text.Trim() == "Amort" &&
worksheet.Cells[row, 5].Text.Trim() == "I" &&
worksheet.Cells[row, 6].Text.Trim() == "Valor Cuota" &&
worksheet.Cells[row, 7].Text.Trim() == "Saldo Insoluto")
{
headerRow = row; // Guardamos la fila de los encabezados
encabezadosEncontrados = true; // Indicamos que los encabezados fueron encontrados
break; // Salimos del bucle una vez encontrados los encabezados
}
}
// Si no se encontraron encabezados, pasamos a la siguiente hoja
if (!encabezadosEncontrados)
{
continue;
}
encabezadosProcesados = true; // Marcamos que al menos una hoja tenía encabezados válidos
// Iteramos sobre las filas después de los encabezados para procesar los datos
for (int row = headerRow + 1; row <= rowCount; row++)
{
try
{
// Creamos una nueva instancia de CargaCuotas
CargaCuotas cuota = new CargaCuotas();
// Convertimos y asignamos los valores de las celdas a las propiedades de cuota
cuota.NumeroOperacion = string.IsNullOrEmpty(worksheet.Cells[row, 1].Text) ? (decimal?)null : Convert.ToDecimal(worksheet.Cells[row, 1].Text);
cuota.NumeroRentas = string.IsNullOrEmpty(worksheet.Cells[row, 2].Text) ? (int?)null : Convert.ToInt32(worksheet.Cells[row, 2].Text);
cuota.Mes = string.IsNullOrEmpty(worksheet.Cells[row, 3].Text) ? (DateTime?)null : Convert.ToDateTime(worksheet.Cells[row, 3].Text);
cuota.Amort = string.IsNullOrEmpty(worksheet.Cells[row, 4].Text) ? (decimal?)null : ParseDecimal(ConvertirComaADecimal(worksheet.Cells[row, 4].Text));
cuota.Interes = string.IsNullOrEmpty(worksheet.Cells[row, 5].Text) ? (decimal?)null : ParseDecimal(ConvertirComaADecimal(worksheet.Cells[row, 5].Text));
cuota.ValorCuota = string.IsNullOrEmpty(worksheet.Cells[row, 6].Text) ? (decimal?)null : ParseDecimal(ConvertirComaADecimal(worksheet.Cells[row, 6].Text));
cuota.SaldoInsoluto = string.IsNullOrEmpty(worksheet.Cells[row, 7].Text) ? (decimal?)null : ParseDecimal(ConvertirComaADecimal(worksheet.Cells[row, 7].Text));
// Asignamos datos adicionales sobre la carga
cuota.NombreExcel = fuExcel.FileName; // Nombre del archivo cargado
cuota.NombreHoja = worksheet.Name; // Nombre de la hoja actual
cuota.UsuarioCarga = usuario.CodPersonal; // Usuario que está cargando los datos
cuota.Estado = true; // Estado de la cuota (puede ser usado para controlar si es válida)
// Agregamos la cuota a la lista
cuotas.Add(cuota);
}
catch (FormatException ex) // Captura errores de formato
{
mensajeError = $"Error en la hoja '{worksheet.Name}', fila {row}. Datos inválidos: {ex.Message}.";
errorEncontrado = true; // Marcamos que hubo un error
break; // Salimos del bucle al encontrar el error
}
catch (Exception ex) // Captura otros errores
{
mensajeError = $"Error inesperado en la hoja '{worksheet.Name}', fila {row}: {ex.Message}.";
errorEncontrado = true; // Marcamos que hubo un error
break; // Salimos del bucle al encontrar el error
}
}
// Si hubo un error, salimos del bucle que procesa las hojas
if (errorEncontrado)
{
break;
}
}
}
// Si se encontró un error, mostramos el mensaje de error
if (errorEncontrado)
{
lblFileTypeError.Text = mensajeError;
lblFileTypeError.Visible = true;
}
// Si no se procesaron encabezados, mostramos un mensaje de advertencia
else if (!encabezadosProcesados)
{
lblFileTypeError.Text = "No se encontraron encabezados válidos en ninguna hoja del archivo.";
lblFileTypeError.Visible = true;
}
// Si se procesaron correctamente las cuotas, las insertamos en la base de datos
else if (cuotas.Count > 0)
{
try
{
// Insertamos las cuotas en la base de datos
CargaContratosCuotasBc bc = new CargaContratosCuotasBc();
var idCarga = Guid.NewGuid(); // Generamos un ID único para la carga
bc.InsertarCuotas(cuotas, idCarga); // Insertamos las cuotas
lblFileTypeError.Text = "Datos insertados correctamente.";
lblFileTypeError.Visible = true;
}
catch (Exception ex) // Captura errores al insertar en la base de datos
{
lblFileTypeError.Text = "Error al insertar los datos en la base de datos: " + ex.Message;
lblFileTypeError.Visible = true;
}
}
// Si no se encontraron datos válidos, mostramos un mensaje de advertencia
else
{
lblFileTypeError.Text = "No se encontraron datos válidos en el archivo.";
lblFileTypeError.Visible = true;
}
}
}
catch (Exception ex) // Captura errores generales al procesar el archivo
{
lblFileTypeError.Text = "Error al procesar el archivo: " + ex.Message;
lblFileTypeError.Visible = true;
}
}
else
{
// Mostramos un mensaje si el archivo no es de tipo .xlsx
lblFileTypeError.Text = "Solo se permiten archivos .xlsx";
lblFileTypeError.Visible = true;
}
}
}
private string ConvertirComaADecimal(string texto)
{
if (string.IsNullOrEmpty(texto))
return texto;
texto = texto.Replace(".", "");
return texto.Replace(",", ".");
}
private decimal ParseDecimal(string value)
{
// Limpia cualquier espacio en blanco
value = value.Trim();
// Si el valor contiene solo "-", lo tomamos como 0
if (value == "-")
{
return 0.00M;
}
// Reemplaza la coma por un punto decimal si existe
value = value.Replace(",", ".");
// Verifica si es un número válido con formato decimal
if (decimal.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal result))
{
return result;
}
throw new FormatException($"El valor '{value}' no se pudo convertir a decimal.");
}
}
}
-------------------------------------------------------------------------------
.cs capa de negocio que contiene el ciclo de carga
-------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LeaOperBussinesLayer.BussinesEntities.AdminContract.AdmCtos;
using LeaOperBussinesLayer.DataAcessComponent.AdminContract.AdmCtos;
namespace LeaOperBussinesLayer.BussinesComponents.AdminContract.AdmCtos
{
public class CargaContratosCuotasBc
{
public void InsertarCuotas(List<CargaCuotas> cuotas, Guid idCarga )
{
CargaContratosCuotasDac dac = new CargaContratosCuotasDac();
foreach (var cuota in cuotas)
{
dac.InsertarCuota(cuota, idCarga);
}
}
}
}
-------------------------------------------------------------------------------
.cs capa de datos
-------------------------------------------------------------------------------
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using LeaOperBussinesLayer.BussinesEntities.AdminContract.AdmCtos;
public class CargaContratosCuotasDac
{
public void InsertarCuota(CargaCuotas cuota, Guid idCarga)
{
string query = @"INSERT INTO carga_cuotas_temp
(id_carga, numero_operacion, numero_rentas, mes, amort, i, valor_cuota, saldo_insoluto, nombre_excel, nombre_hoja, usuario_carga, estado)
VALUES
(@idCarga,@NumeroOperacion, @NumeroRentas, @Mes, @Amort, @Interes, @ValorCuota, @SaldoInsoluto, @NombreExcel, @NombreHoja, @UsuarioCarga, @Estado)";
string connectionString = ConfigurationManager.ConnectionStrings["LeaseOper"].ConnectionString;
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("@idCarga", idCarga);
command.Parameters.Add("@NumeroOperacion", SqlDbType.Decimal).Value = (object)cuota.NumeroOperacion ?? DBNull.Value;
command.Parameters.Add("@NumeroRentas", SqlDbType.Int).Value = (object)cuota.NumeroRentas ?? DBNull.Value;
command.Parameters.Add("@Mes", SqlDbType.DateTime).Value = (object)cuota.Mes ?? DBNull.Value;
command.Parameters.Add("@Amort", SqlDbType.Decimal).Value = (object)cuota.Amort ?? DBNull.Value;
command.Parameters.Add("@Interes", SqlDbType.Decimal).Value = (object)cuota.Interes ?? DBNull.Value;
command.Parameters.Add("@ValorCuota", SqlDbType.Decimal).Value = (object)cuota.ValorCuota ?? DBNull.Value;
command.Parameters.Add("@SaldoInsoluto", SqlDbType.Decimal).Value = (object)cuota.SaldoInsoluto ?? DBNull.Value;
command.Parameters.Add("@NombreExcel", SqlDbType.VarChar, 1000).Value = (object)cuota.NombreExcel ?? DBNull.Value;
command.Parameters.Add("@NombreHoja", SqlDbType.VarChar, 1000).Value = (object)cuota.NombreHoja ?? DBNull.Value;
command.Parameters.Add("@UsuarioCarga", SqlDbType.Int).Value = (object)cuota.UsuarioCarga ?? DBNull.Value;
command.Parameters.Add("@Estado", SqlDbType.Bit).Value = (object)cuota.Estado ?? DBNull.Value;
connection.Open();
command.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
throw new ApplicationException("Error al insertar la cuota en la base de datos", ex);
}
}
}
-------------------------------------------------------------------------------
.cs Clase Carga Cuotas
-------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LeaOperBussinesLayer.BussinesEntities.AdminContract.AdmCtos
{
public class CargaCuotas
{
public decimal? NumeroOperacion { get; set; }
public int? NumeroRentas { get; set; }
public DateTime? Mes { get; set; }
public decimal? Amort { get; set; }
public decimal? Interes { get; set; }
public decimal? ValorCuota { get; set; }
public decimal? SaldoInsoluto { get; set; }
public string NombreExcel { get; set; }
public string NombreHoja { get; set; }
public int UsuarioCarga { get; set; }
public bool Estado { get; set; }
}
}
-------------------------------------------------------------------------------
.SQL Creación de tabla
-------------------------------------------------------------------------------
USE [leaseoper]
GO
/****** Object: Table [dbo].[carga_cuotas_temp] Script Date: 11/09/2024 17:26:33 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[carga_cuotas_temp]') AND type IN (N'U'))
DROP TABLE [dbo].[carga_cuotas_temp]
GO
/****** Object: Table [dbo].[carga_cuotas_temp] Script Date: 11/09/2024 17:26:33 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[carga_cuotas_temp](
[id_carga] [UNIQUEIDENTIFIER] NOT NULL,
[numero_operacion] [NUMERIC](20, 0) NULL,
[numero_rentas] [INT] NULL,
[mes] [DATETIME] NULL,
[amort] [NUMERIC](20, 4) NULL,
[i] [NUMERIC](20, 4) NULL,
[valor_cuota] [NUMERIC](20, 4) NULL,
[saldo_insoluto] [NUMERIC](20, 4) NULL,
[nombre_excel] [VARCHAR](1000) NULL,
[nombre_hoja] [VARCHAR](1000) NULL,
[usuario_carga] [INT] NULL,
[fecha_carga] [DATETIME] NULL,
[estado] [BIT] NULL)
ALTER TABLE [dbo].[carga_cuotas_temp] ADD DEFAULT (GETDATE()) FOR [fecha_carga]
GO
CREATE NONCLUSTERED INDEX IX_carga_cuotas_temp_id_carga ON [dbo].[carga_cuotas_temp] ([id_carga])
CREATE NONCLUSTERED INDEX IX_carga_cuotas_temp_numero_operacion ON [dbo].[carga_cuotas_temp] ([numero_operacion])
CREATE NONCLUSTERED INDEX IX_carga_cuotas_temp_usuario_carga ON [dbo].[carga_cuotas_temp] ([usuario_carga])