diff --git a/Excel.vb b/Excel.vb
new file mode 100644
index 0000000..62fe939
--- /dev/null
+++ b/Excel.vb
@@ -0,0 +1,38 @@
+Imports System.IO
+
+Public Class Excel
+ Public Shared Sub IEnumerableAExcel(Of t)(Datos As IEnumerable(Of t), Fichero As String)
+ Dim wb As New ClosedXML.Excel.XLWorkbook
+ Dim dt = Extensiones.IEnumerableExtensions.CopyToDataTable(Of t)(Datos)
+ wb.AddWorksheet(dt)
+ wb.SaveAs(Fichero)
+ End Sub
+
+ Public Shared Sub IEnumerableAExcel(Of t)(Datos As List(Of t), Fichero As String)
+ Dim wb As New ClosedXML.Excel.XLWorkbook
+ Dim dt = Extensiones.IEnumerableExtensions.CopyToDataTable(Of t)(Datos)
+ wb.AddWorksheet(dt)
+ wb.SaveAs(Fichero)
+ End Sub
+ Public Shared Function IEnumerableAExcel(Of t)(Datos As List(Of t)) As Byte()
+ Dim wb As New ClosedXML.Excel.XLWorkbook
+ Dim dt = Extensiones.IEnumerableExtensions.CopyToDataTable(Of t)(Datos)
+ wb.AddWorksheet(dt)
+ Dim ms As New MemoryStream
+ wb.SaveAs(ms)
+ ms.Position = 0
+ Return ms.ToArray
+ End Function
+ Public Shared Function ListaIEnumerableAExcel(Of t)(Datos As List(Of List(Of t)), NombreTablas As List(Of String)) As Byte()
+ Dim wb As New ClosedXML.Excel.XLWorkbook
+ For i = 0 To Datos.Count - 1
+ Dim tabla = Datos(i)
+ Dim dt = Extensiones.IEnumerableExtensions.CopyToDataTable(Of t)(tabla)
+ wb.AddWorksheet(dt, NombreTablas(i))
+ Next
+ Dim ms As New MemoryStream
+ wb.SaveAs(ms)
+ ms.Position = 0
+ Return ms.ToArray
+ End Function
+End Class
diff --git a/tsNotificacionesClient.vb b/tsNotificacionesClient.vb
new file mode 100644
index 0000000..ea3b4d3
--- /dev/null
+++ b/tsNotificacionesClient.vb
@@ -0,0 +1,89 @@
+Imports System.Configuration
+Imports System.Net
+Imports System.Net.Http
+Imports System.Net.Http.Headers
+Imports System.Net.Http.Json
+
+Public Class TsNotificacionesClient
+
+ Private ReadOnly _http As HttpClient
+ Private ReadOnly _idAplicacion As Integer
+
+ Public Sub New(baseUrl As String, idAplicacion As Integer, apiKey As String)
+ _idAplicacion = idAplicacion
+ ServicePointManager.ServerCertificateValidationCallback = Function(s, c, ch, e) True
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11
+ _http = New HttpClient() With {.BaseAddress = New Uri(baseUrl)}
+ _http.DefaultRequestHeaders.Add("X-Api-Key", apiKey)
+ End Sub
+
+ Public Shared Async Function RegistrarAsync(titulo As String, descripcion As String, TipoNotificacion As TipoNotificacionEnum, Optional Fichero As Byte() = Nothing) As Task
+ Try
+ ServicePointManager.ServerCertificateValidationCallback = Function(s, c, ch, e) True
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 Or SecurityProtocolType.Tls11
+ Dim baseUrl = ConfigurationManager.AppSettings("TsNotificaciones:ApiUrl")
+ Dim idAplicacion = Integer.Parse(ConfigurationManager.AppSettings("TsNotificaciones:IdAplicacion"))
+ Dim apiKey = ConfigurationManager.AppSettings("TsNotificaciones:ApiKey")
+ Dim http = New HttpClient() With {.BaseAddress = New Uri(baseUrl)}
+ Dim NombreServidor = ConfigurationManager.AppSettings("TsNotificaciones:ApiKey")
+ If NombreServidor = "" Then NombreServidor = System.Environment.MachineName
+ 'Dim json As String = String.Format(
+ ' "{{""idAplicacion"":{0},""nombreServidor"":""{1}"",""ipServidor"":""{2}""," &
+ ' """titulo"":""{3}"",""stacktrace"":""{4}"",""nivelSeveridad"":{5}}}",
+ ' idAplicacion, EscaparJson(Environment.MachineName), ObtenerIp(),
+ ' EscaparJson(titulo), EscaparJson(descripcion), CInt(TipoNotificacion))
+
+ 'Await http.PostAsync("/api/alertas/registrar",
+ ' New StringContent(json, Encoding.UTF8, "application/json"))
+
+ Dim Tipo = CInt(TipoNotificacion)
+ Dim request = New HttpRequestMessage(HttpMethod.Post, "/api/alertas/registrar")
+ request.Headers.Add("X-Api-Key", apiKey)
+ request.Content = JsonContent.Create(New With {idAplicacion, NombreServidor, ObtenerIp(), titulo, descripcion, Tipo})
+ Dim response = Await http.SendAsync(request)
+ Dim body As System.Text.Json.JsonElement = Await response.Content.ReadFromJsonAsync(Of System.Text.Json.JsonElement)()
+ Dim id = body.GetProperty("id").GetInt32()
+ If Fichero IsNot Nothing Then
+ Await SubirFichero(http, apiKey, id, Fichero)
+ End If
+ Catch ex As Exception
+ Throw New Exception(ex.Message, ex)
+ End Try
+ End Function
+
+ Private Shared Async Function SubirFichero(ByVal http As HttpClient, ByVal apiKey As String, ByVal alertaId As Integer, ByVal datos As Byte()) As Task
+ Try
+ Dim fileContent = New ByteArrayContent(datos)
+ fileContent.Headers.ContentType = New MediaTypeHeaderValue("image/png")
+ Dim multipart = New MultipartFormDataContent()
+ multipart.Add(fileContent, "archivo", "Imagen.png")
+ Dim request = New HttpRequestMessage(HttpMethod.Post, $"/api/alertas/{alertaId}/archivo")
+ request.Headers.Add("X-Api-Key", apiKey)
+ request.Content = multipart
+ Dim response = Await http.SendAsync(request)
+ Dim ok As Boolean = response.IsSuccessStatusCode
+ If Not ok Then Throw New Exception($"Subida fallida ({response.StatusCode}): {Await response.Content.ReadAsStringAsync()}")
+ Catch httpEx As Exception
+ Throw New Exception
+ End Try
+ End Function
+
+
+
+ Private Shared Function ObtenerIp() As String
+ For Each addr In Dns.GetHostAddresses(Dns.GetHostName())
+ If addr.AddressFamily = Sockets.AddressFamily.InterNetwork Then Return addr.ToString()
+ Next
+ Return "127.0.0.1"
+ End Function
+
+ 'Private Shared Function EscaparJson(s As String) As String
+ ' Return s.Replace("\", "\\").Replace("""", "\""").Replace(vbCr, "\r").Replace(vbLf, "\n")
+ 'End Function
+ Public Enum TipoNotificacionEnum
+ INFO = 0
+ ADVERTENCIA = 1
+ [ERROR] = 2
+ CRÍTICO = 3
+ End Enum
+End Class
\ No newline at end of file
diff --git a/tsUtilidades.vbproj b/tsUtilidades.vbproj
index 021ced5..1e6bafd 100644
--- a/tsUtilidades.vbproj
+++ b/tsUtilidades.vbproj
@@ -16,11 +16,13 @@
net8.0
tsUtilidades
net8.0, libreria
- 1.1.6
+ 1.1.8
Manuel
Tecnosis S.A
Utilidades Varias
+ - 2026-04-09 1.1.8 Se añade la clase tsNotificacionesClient
+ - 2026-04-09 1.1.7 Se añade la clase Excel
- 2026-03-05 1.1.6 Correccion rutina EjeMySqlHex
- 2025-10-05 1.1.5 Nueva funcion EjecutarScript
- 2025-09-05 1.1.4 No se eliminan los caracteres especiales ni se mayusculiza en ValidarDocumentoIdentidad
@@ -49,6 +51,7 @@
+