3ENGINE

Programación y otros cachivaches

Etiqueta: programacion

Página 2/21

Tecnologia

Cómo deshabilitar la tecla enter en una página web


De modo predeterminado el envio de un formulario se puede ejecutar con un botón submit asociado al formulario o pulsando enter.

deshabilitar la tecla enter en una página web

Para desactivar el envio del formulario mediante la tecla enter con javascript + jquery:

$(function () {
    $("form").keypress(function (e) {
        var key;
        if (window.event)
            key = window.event.keyCode; //IE
        else
            key = e.which; //firefox     
        return (key != 13);
    });
});

Este código asigna el evento keypress al formulario. Si queremos el mismo comportamiento para toda la página entonces tenemos que sustituir $(«form») por $(«body») u otro selector jquery que se adapte a tus necesidades.




Tecnologia

Cómo generar archivos Excel en C# con Open XML


Office Open XML es un formato de archivo abierto y estándar cuyas extensiones más comunes son .docx, .xlsx y .pptx. Principalmente contiene datos en XML comprimidos en un .zip. .NET dispone de librerias capaces de trabajar con este formato y de esta manera prescindir de instalar Office y sus temidas Microsoft.Office.Interop.

Generar archivos Excel en C# con Open XML

Para la demo es necesario instalar el paquete DocumentFormat.OpenXml:

generar archivos Excel en C# con Open XML

O desde la consola de Nuget:

Install-Package DocumentFormat.OpenXml 

El código es el siguiente:

 
namespace SaveExcelApp
{
    public static class SaveExcel
    {
        
        public static void BuildExcel(DataTable dataTable, string ExcelPath)        
        {
            using (SpreadsheetDocument myWorkbook = 
                SpreadsheetDocument.Create(ExcelPath, 
                SpreadsheetDocumentType.Workbook))
            {
                // workbook Part
                WorkbookPart workbookPart = myWorkbook.AddWorkbookPart();
                var worksheetPart = workbookPart.AddNewPart();
                string relId = workbookPart.GetIdOfPart(worksheetPart);

                // file Version
                var fileVersion = new FileVersion { ApplicationName = "Microsoft Office Excel" };

                // sheets               
                var sheets = new Sheets();
                var sheet = new Sheet { Name = dataTable.TableName, SheetId = 1, Id = relId };
                sheets.Append(sheet);

                // data
                SheetData sheetData = new SheetData(CreateSheetData(dataTable));

                // add the parts to the workbook and save
                var workbook = new Workbook();
                workbook.Append(fileVersion);
                workbook.Append(sheets);
                var worksheet = new Worksheet();
                worksheet.Append(sheetData);
                worksheetPart.Worksheet = worksheet;
                worksheetPart.Worksheet.Save();
                myWorkbook.WorkbookPart.Workbook = workbook;
                myWorkbook.WorkbookPart.Workbook.Save();
                myWorkbook.Close();
            }
        }

        private static List CreateSheetData(DataTable dataTable)
        {
            List elements = new List();

            // row header
            var rowHeader = new Row();
            Cell[] cellsHeader = new Cell[dataTable.Columns.Count];
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                cellsHeader[i] = new Cell();
                cellsHeader[i].DataType = CellValues.String;
                cellsHeader[i].CellValue = new CellValue(dataTable.Columns[i].ColumnName);
            }
            rowHeader.Append(cellsHeader);
            elements.Add(rowHeader); 
            
           // rows data
           foreach (DataRow rowDataTable in dataTable.Rows)
           {     
                var row = new Row();
                Cell[] cells = new Cell[dataTable.Columns.Count];

                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    cells[i] = new Cell();
                    cells[i].DataType = CellValues.String;
                    cells[i].CellValue = new CellValue((string)rowDataTable[i]);
                }
                row.Append(cells); 
                elements.Add(row);            
            }                      
            return elements;
        }
    }
}

Para mi demo los datos que deseo guardar en el archivo Excel los tengo en un DataTable. Al método BuildExcel se le pasa el DataTable con los datos y la ruta completa del archivo Excel a generar. El método CreateSheetData se encarga de leer los datos del DataTable y generar las celdas. El nombre de la hoja Excel se obtiene del nombre de la tabla.

Se trata de un código sencillo pero que puede servir como punto de partida.

Y ahora una pequeña demo:

var demoTable = new DataTable("mi demo");
demoTable.Columns.Add("name");
demoTable.Columns.Add("surname");
demoTable.Columns.Add("favorite color");
demoTable.Rows.Add(new Object[] { "David", "Miro", "blue" });
demoTable.Rows.Add(new Object[] { "Pablo", "Iglesias", "yellow" });
demoTable.Rows.Add(new Object[] { "Ratoncito", "Perez", "green" });
SaveExcel.BuildExcel(demoTable, "demo.xlsx");

Y el archivo generado:

generar archivos Excel en C# con Open XML

Enlace a la demo: SaveExcel.zip




Tecnologia

Cómo crear un servicio Windows .NET autoinstalable


Cuando llega la hora de instalar un servicio Windows en .NET, en mucho sitios recomiendan instalar el servicio mediante una utilidad de la línea de comandos llamada installutil.exe

Comandos básicos para instalar y desinstalar un servicio con installutil.exe:

installutil.exe miservicio.exe
installutil.exe /u miservicio.exe

Una vez instalado podéis arrancar y parar el servicio mediante la utilidad net.exe:

net start miservicio.exe
net stop miservicio.exe

Crear un servicio Windows .NET autoinstalable

El problema de installutil.exe es que sólo la encontraras si instalas Visual Studio en el ordenador donde necesitas instalar el servicio. Una solución es crear un proyecto de InstallShield para crear un autoinstalable. Pero yo os cuento una manera mas sencilla de conseguir esto y ahorraros el sufrimiento de utilizar InstallShield 🙂

Antes de nada, el código incluye una directiva DEBUG que permite debugar el servicio como si se tratara de una aplicación de consola. Esto lo expliqué en Debug desde VS.NET de un servicio Windows.

Por último, recomiendo añadir un ProjectInstaller.cs a vuestro servicio tal como explica este enlace en el paso 5. Añadirlo nos permitirá entre otras cosas especificar el tipo de cuenta, el nombre y la descripción del servicio, el modo de arranque, etc.

Código de ejemplo:

using System.ServiceProcess;
using System.Configuration.Install;
using System.Reflection;
using System;
using System.Threading;

namespace MyService
{
    static class Program
    {
        /// 
        /// Punto de entrada principal para la aplicación.
        /// 
        static void Main(string[] args)
        {
            #if (!DEBUG)    
                if (System.Environment.UserInteractive)
                {
                    string parameter = string.Concat(args);
                    switch (parameter)
                    {
                        case "-i":
                        case "-install":
                            try
                            {
                                ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
                            }
                            catch
                            {
                            }
                            break;
                        case "-u":
                        case "-uninstall":
                            try
                            {
                                ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
                            }
                            catch
                            {
                            }
                            break;
                    }
                }
                else
                {
                    ServiceBase[] ServicesToRun;
                    ServicesToRun = new ServiceBase[] 
                    { 
                        new ServiceWatcher()
                    };
                    ServiceBase.Run(ServicesToRun);
                }

            #else
                // debug mode
                ServiceWatcher service = new ServiceWatcher();
                service.Init();
                Thread.Sleep(Timeout.Infinite);
            #endif
        }
    }
}

Básicamente la idea es que se puede tener un servicio autocontenido para instalar y desinstalar utilizando ManagedInstallerClass como se muestra el ejemplo.

De modo que si compilas el servicio en modo RELEASE para instalar el servicio:

miservicio.exe -install

y para desisntalarlo:

miservicio.exe -uninstall



Tecnologia

Cómo crear un mapa con Leaflet y GeoJSON


Leaflet es una libreria de JavaScript de código abierto que permite construir aplicaciones de mapas web. Soporta HTML5, CSS3 y la mayoría de las plataformas móviles y de escritorio. Existen otras librerías, como OpenLayers o la API de Google Maps, pero Leaflet tiene la ventaja de ser muy compacta (carga rápido) y no requiere de conocimientos profundos de GIS.

leafleft

GeoJSON se encuentra dentro del grupo de los formatos de intercambio de datos geoespaciales mas extendidos. GeoJSON se basa en JSON. Permite la codificación de colecciones de estructuras de datos geográficos. Un objeto GeoJSON puede representar una geometría, una característica, o una colección de características. GeoJSON soporta los siguientes objetos geométricos: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, GeometryCollection, Feature, FeatureCollection.

geojson

Obtener los datos GeoJSON para la demo

Podemos crear nuestro propio geojson mediante la herramienta online geojson.io, pero para nuestra demo obtendremos los datos de ejemplo de algunos de los lugares que siguiendo la inicitiva Open Data, ofrecen datos públicos de forma libre para todo el mundo, sin restricciones de derechos de autor, de patentes o de otros mecanismos de control. Por ejemplo, descargamos los municipios de la isla de La Palma. Lo abrimos:

{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [{
"type": "Feature",
"properties": {
"OBJECTID": 1,
"SUPERFICIE": 135741394.267612,
"PERIMETRO": 66918.002370,
"ID": 1,
"MUNICIPIO": "EL PASO",
"CODIGO": 38027,
[...]
},
"geometry": {
"type": "Polygon",
"coordinates": [[
[-17.884219, 28.616156], 
[-17.884263, 28.616166], 
[-17.884306, 28.616177],
[...]

«crs» indica el sistema de coordenadas de referencia utilizado. Usa WGS 84 como sistema de coordenadas, que es ampliamente utilizado por Google Maps, OpenStreetMaps, etc. «features» es una colección de características. Cada característica se compone de una colección de propiedades y una geometría, en este caso, un polígono.

Opcionalmente, para validar el GeoJson podemos utilizar por ejemplo geojsonlint. Esta herramienta online carga los datos en un mapa y valida que sean correctos.

Cómo crear un mapa con Leafleft y GeoJSON

Visualizar el contenido en un mapa con Leaflet

La manera mas sencilla de que Leaflet reconozca nuestros datos es convertirlos a código javascript. Aprovechando que JSON es compatible con javascript, esto es tan sencillo como editar el fichero, hacer que los datos GeoJSON estén asociados a una variable municipios y guardar el fichero con extensión .js:

var municipios = {
"type": "FeatureCollection",
[...]

El código es el siguiente, mas abajo comento el código:

<!DOCTYPE html>
<html>
<head>
<title>Municipios de La Palma</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script src="demo.js" type="text/javascript"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script>
var map = L.map('map').setView([28.68, -17.85], 10);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
   maxZoom: 18,
   attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, '+
   '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, '+
   'Imagery © <a href="http://cloudmade.com">CloudMade</a>',
   id: 'mapbox.light'
}).addTo(map);

function onEachFeature(feature, layer) {
  if (feature.properties && feature.properties.MUNICIPIO) {
     var popupContent = "<p>Municipio: " + feature.properties.MUNICIPIO + "</p>";
     layer.bindPopup(popupContent);
  };
};

function style(feature) {
   return {
     weight: 2,
     opacity: 1,
     color: 'white',
     dashArray: '3',
     fillOpacity: 0.7,
     fillColor: '#FEB24C'
   };
};

L.geoJson(municipios, {
   style: style,
   onEachFeature: onEachFeature
}).addTo(map);

</script>
</body>
</html>

  • Línea 11: aquí referenciamos al geojson con los municipios.
  • Línea 14: map es la clase principal de Leafleft. Indicamos las coordenadas iniciales y el nivel de zoom por defecto.
  • Línea 16: añadimos una capa (layer) con el mapa. En este caso usamos las imágenes (tiles) de OpenStreetMap (OSM). Además especificamos el nivel máximo de zoom. Existen otros servidores de mapas de OSM, hay una lista de ellos en la Wiki de OSM o utiliza un comparador de mapas como map compare service de bbbike.org
  • Línea 24: función que muestra un popup con el nombre del municipio.
  • Línea 31: función con el estilo de cada uno de los features de la capa GeoJSON.
  • Línea 42: aquí creamos una capa de tipo GeoJSON, donde le pasamos la variable con los datos, le indicamos el estilo y le pasamos la función a llamar cuando el ratón haga click en una feature.

Y así quedaría el resultado:

Cómo crear un mapa con Leaflet y GeoJSON

Leer directamente GeoJSON con jQuery

En el anterior ejemplo hemos convertido el GeoJSON en código javascript. Pero dependiendo de nuestras necesidades, a veces esto no es posible y necesitaremos leer directamente el fichero en formato GeoJSON. Para hacer esto haremos uso de jQuery. El código es el siguiente, mas abajo comento el código:

<!DOCTYPE html>
<html>
<head>
<title>Municipios de La Palma</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
var map = L.map('map').setView([28.68, -17.85], 10);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
   maxZoom: 18,
   attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, '+
   '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, '+
   'Imagery © <a href="http://cloudmade.com">CloudMade</a>',
   id: 'mapbox.light'
}).addTo(map);

function onEachFeature(feature, layer) {
  if (feature.properties && feature.properties.MUNICIPIO) {
     var popupContent = "<p>Municipio: " + feature.properties.MUNICIPIO + "</p>";
     layer.bindPopup(popupContent);
  };
};

function style(feature) {
   return {
     weight: 2,
     opacity: 1,
     color: 'white',
     dashArray: '3',
     fillOpacity: 0.7,
     fillColor: '#FEB24C'
   };
};

$.getJSON("demo.json", function(data){
   L.geoJson(data, {
      style: style,
      onEachFeature: onEachFeature
   }).addTo(map);
});

</script>
</body>
</html>

  • Línea 12: aquí referenciamos a la libreria jQuery.
  • Línea 42: esta función lee el GeoJson, y despues, como el ejemplo anterior, creamos una capa de tipo GeoJSON, donde le pasamos la variable con los datos, le indicamos el estilo y le pasamos la función a llamar cuando el ratón haga click en una feature.