¿Cómo convertir archivo PDF a Docx en C# .Net? – Spire.Pdf vs SautinSoft.PdfFocus

Te muestro como convertir un archivo PDF a un archivo Docx con dos librerías que tienen precio pero hacen su trabajo.

Código del ejemplo:


  class Program
    {
        //ORIGEN PDF
        static string pathPDF = @"C:\AlgunaRuta\archivo.pdf";

        //DESTINOS ARCHIVO DOCX
        static string pathDoc1 = @"C:\AlgunaRuta\archivo-spire.docx";
        static string pathDoc2 = @"C:\AlgunaRuta\archivo-sautin.docx";

        static void Main(string[] args)
        {
            //llamamos para convertir el pdf con spire
            UsandoSpirePdf();

            //llamamos para convertir el pdf con sautinsoft
            UsandoSautin();

        }

        public static void UsandoSpirePdf()
        {

            PdfDocument pdf = new PdfDocument();
            //cargamos el pdf
            pdf.LoadFromFile(pathPDF);

            //guardamos el docx
            pdf.SaveToFile(pathDoc1, FileFormat.DOCX);

            //abrimos el archivo
            System.Diagnostics.Process.Start(pathDoc1);

        }

        public static void UsandoSautin()
        {

            SautinSoft.PdfFocus oPdfFocus = new SautinSoft.PdfFocus();

            //cargamos el pdf
            oPdfFocus.OpenPdf(pathPDF);

            //si se tiene mas de 1 pagina
            if (oPdfFocus.PageCount > 0)
            {
                //asignamos el tipo de documento al que convertiremos
                oPdfFocus.WordOptions.Format = SautinSoft.PdfFocus.CWordOptions.eWordDocument.Docx;

                //guardamos el dox
                int resultado = oPdfFocus.ToWord(pathDoc2);

                if (resultado == 0)
                {
                    //abrimos el documento
                    System.Diagnostics.Process.Start(pathDoc2);
                }
            }
        }
    }

Spire.Pdf: https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html

SautinSoft.PdfFocus: http://www.sautinsoft.com/products/pdf-focus/

¿Como recorrer una tabla con la instrucción while en SQL?

Te muestro cómo es posible recorrer una tabla por medio de una instrucción while en sql.

En el caso de mysql u otro motor solo remplazar top por su equivalente, por ejemplo en mysql: limit 0,1.

Tabla people

Código utilizado:


insert into @tabla(id,name) select id,name from people

declare @count int = (select count(*) from @tabla)

while @count > 0
begin

	declare @name varchar(max) = (select top(1) name from @tabla order by id)
	declare @id int = (select top(1) id from @tabla order by id)

	print 'Hola '+@name

	delete @tabla where id=@id

	set @count = (select count(*) from @tabla)

end 

¿Cómo liberar el espacio en el archivo .ldf de una base de datos en SQL SERVER?

El archivo .ldf de toda base de datos en sql server sirve para llevar un log de toda consulta hecha en la base de datos (todos los insert, update, select, etc etc).

Esto es útil para regresar en un punto en el tiempo y ver la base de datos como se encontraba en ese punto en su estructura y en sus datos.

Pero qué pasa cuando nuestra base de datos pesa ya un tamaño exagerado y queremos liberar el espacio de nuestro servidor. Optamos por realizar una liberación de este archivo (obviamente después de hacer los backups correspondientes).

A continuación te muestro como se debería hacer para una base de datos llamada PATODB:


ALTER DATABASE PATODB SET RECOVERY SIMPLE

GO

/* el 5 es 5 MB, se dejara el log con un tamaño de 5MB*/
DBCC SHRINKFILE (PATODB_Log, 5)

GO

ALTER DATABASE PATODB SET RECOVERY FULL

GO

Y así de simple liberamos el espacio de nuestro archivo .ldf.

Borrar el cache al subir una imagen y mostrarla en el navegador en MVC .Net #Razor

Cuando hacemos un módulo para actualizar una imagen, ya sea el logotipo o una galería, muchas veces tenemos el problema de que sigue saliendo en el navegador la imagen vieja hasta que borramos el cache del navegador.

Lamentablemente los usuarios no saben que es el cache y esperan ver su imagen nueva, al seguir viendo la imagen vieja, el usuario piensa que no se ha subido con éxito la nueva imagen.

En el caso de Mvc .Net esto re se resuelve con un truco, e igual puede resolverse con su equivalencia en cualquier otro lenguaje de programación.

Para esto vamos a hacer uso de la funcionalidad Random, funcionalidad que existe en todo lenguaje de programación y basta con hacerlo de la siguiente manera, en el caso de MVC .Net lo haremos en razor (en la vista):


@{
    //creamos el objeto random y asignamos a una variable string
    Random r = new Random();
    string a = r.Next().ToString();
}

<img src='http://unsitio.com/unaimagen.jpg?a=@a'>

Al poner una variable con un valor nuevo al final de nuestra url de la imagen, obligamos al navegador a volver a cargarla y no utilizar la que tiene en cache.

Un truco viejo, pero que pocos conocen.

¿Cómo enviar un objeto json en una solicitud Get o Post en C# .Net?

Ahora que estamos en la era de los webservice todos tenemos la necesidad de saber la forma de enviar datos por medio de Get o Post. En C# la forma de hacer una solicitud a un servicio o a un api es muy sencilla y en el siguiente ejemplo te muestro como hacerlo por medio de una clase que yo hice.

La clase siguiente está preparada para enviar cualquier tipo de objeto ya que recibe el tipo de objeto que se enviara y lo serializa en json.

Recuerda que si el objeto tiene referencias circulares, la siguiente clase no funcionara.

Clase:


public class RequestHdeleon

  //esta clase nos sirve para tener control del resultado regresado por la solicitud
  public class Reply
    {
        public Reply()
        {
            this.success = 0;
            message = "";
        }

        public int success { get; set; }
        public object data { get; set; }
        public String menssage { get; set; }

    }

  public Reply Send<T>(string url,T objectRequest, string method="POST"){

            try {
		Reply oReply= new Reply();                

                JavaScriptSerializer js = new JavaScriptSerializer();

		//serializamos el objeto
                string json = Newtonsoft.Json.JsonConvert.SerializeObject(objectRequest);

                //peticion
                WebRequest request = WebRequest.Create(url_callback);
                //headers
                request.Method = method;
                request.PreAuthenticate = true;
                request.ContentType = "application/json;charset=utf-8'";
                request.Timeout = 10000; //esto es opcional

                using (var streamWriter = new StreamWriter(request.GetRequestStream()))
                {
                    streamWriter.Write(json);
                    streamWriter.Flush();
                }

                var httpResponse = (HttpWebResponse)request.GetResponse();
                using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                {
                    result = streamReader.ReadToEnd();
                }
                oReply.success = 1;
                //y aquí va nuestra respuesta, la cual es lo que nos regrese el sitio solicitado
                oReply.data = result;
            }catch(Exception e){

                oReply.result = 0;
		//en caso de error lo manejamos en el mensaje
                oReply.menssage = e.Message;

            }

            return oReply;
        }
}

Ejemplo de como utilizarla:


public class UnaClase(){
   public string algo{get;set;}
}

//creamos la clase para enviar los parametros
UnaClase oUnObjeto= new UnaClase();
oUnObjeto.algo="pato feliz";

//Creamos el objeto para solicitud
RequestHdeleon oRequest= new RequestHdeleon();

//primer parametro url
//segundo parametro el objeto
//tercer parametro el metodo: POST, GET, PUT, DELETE
RequestHdeleon.Reply oReply=oRequest.Send<UnaClase>("http://somesite.com/api/somecontroller/",oUnObjeto,"POST");

¿Cómo enviar un valor en ViewBag por RedirectToAction en C# MVC .Net?

Algunas veces tenemos la necesidad de llamar un método por medio de otro, y para ello hacemos uso de RedirectToAction.

RedirectToAction nos sirve para redirigir al usuario a otro controlador o a otro método dependiendo de la lógica de negocio, pero aparte, a veces necesitamos recibir en nuestro elemento destino algún valor para mostrarle al usuario o para realizar alguna validación. Para ello lo primero que se nos viene a la mente es por medio de ViewBag.

Lamentablemente ViewBag no tiene un tiempo de vida más allá del dominio del método, pero podemos apoyarnos de otro diccionario llamado TempData el cual se mantiene en toda la vida de la solicitud HTTP.

A continuación muestro un ejemplo sencillo de cómo quedaría:


public ActionResult Accion1 {
 TempData["mensaje"] = "Un mensaje feliz :)";

 //redirigimos a la Accion2 del mismo controlador
 return RedirectToAction("Action2");

}

public ActionResult Accion2 {

  if(TempData["mensaje"])
     ViewBag.mensaje = TempData["mensaje"].ToString();

  //de esta manera nuestra vista recibiria el ViewBag.mensaje solo cuando TempData no sea null
  return View();
}

¿Cómo obtener una cadena (string) a partir del contenido de un archivo en C# .Net?

En c# es muy fácil obtener una cadena del contenido de un archivo, esto es algo muy útil ya que podemos almacenar información en texto plano en archivos y esta misma obtenerla en cadenas para darle alguna funcionalidad. Por ejemplo un archivo que contenga el cuerpo de un e-mail en .html y así leerlo como string, manipularlo y después enviarlo.

Anexo una clase que tiene un método estático el cual regresa un string a partir de la ruta de un archivo:


 public class Archivo
    {

        public static string GetStringOfFile(string pathFile)
        {
            try
            {
                var contenido = File.ReadAllText(pathFile);

                return contenido;
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }
    }

Y así se utiliza:


string ContenidoArchivo= Archivo.GetStringOfFile("Carpeta/otraCarpeta/AlgunArchivo.html");

Funciona con cualquier extensión: .html, .txt, .xml etc etc.

Código de analizador lexicográfico en Visual Basic 6

Escarbando en mi cajón de códigos escolares me encontré algunas cosas que sería bueno compartirlas.

Comparto mi analizador lexicográfico el cual le servirá a más de uno. El código fuente esta hecho en visual basic 6.0 (no es .Net).

El diagrama de estados es el siguiente (diagrama de transición):

Para descargar el código fuente y el .exe den clic aquí.

¿Cómo obtener todos los parámetros enviados a un controller? C# MVC .Net

Cuando estamos utilizando MVC .Net muchas veces es necesario guardar lo que el usuario está enviando en logs o en la base de datos para poder monitorear errores de usuario final (Ver log sencillo en c# .Net).

De la siguiente forma obtenemos todos los parámetros enviados y ordenados en una variable cadena:


string parametros="";

//recorremos todos los parametros
 foreach (var parameter in Request.Params.AllKeys)
                {
                    parametros += parameter + ": " + Request.Params[parameter]+"\n";
                }

//se ira guardando de la siguiente forma
//parametro1: pato
//parametro2: pato2

¿Cómo crear un archivo pfx en c#? cancelación de factura electrónica SAT cfdi 3.3

Para cancelar una factura electrónica es necesario crear un tercer certificado llamado pfx, este certificado se debe crear por medio de Openssl en conjunto de nuestro archivo Cer y nuestro archivo Key los cuales debemos ya tener si es que estamos timbrando.

Para crear el archivo pfx utilizaremos la clase Process de .Net, esta clase sirve para mandar comandos como si estuviéramos en consola, de esta manera utilizaremos los comandos de Openssl.

Les recuerdo que antes deben instalar Openssl y como está en el siguiente ejemplo debe estar instalado en la unidad c:/openssl-win32.

En caso que se tenga Openssl instalado en otra ruta distinta, solo modifiquen esa parte del código. A continuación la clase mágica:

 public class PFX
    {
        string cer = "";
        string key = "";
        string clavePrivada = "";
        string ArchivoPFX = "";
        string ArchivoKPEM = "";
        string ArchivoCPEM = "";

        public string error = "";
        public string mensajeExito = "";

        ///
<summary>
        ///
        /// </summary>

        /// <param name="cer_">archivo cer a utilizar</param>
        /// <param name="key_">archivo key a utilizar</param>
        /// <param name="clavePrivada_">clave para el archivo pfx</param>
        /// <param name="archivoPfx_">ruta del archivo pfx</param>
        /// <param name="path">ruta para archivos temporales PEM</param>
        public PFX(string cer_, string key_, string clavePrivada_, string archivoPfx_, string pathTemp)
        {
            cer = cer_;
            key = key_;
            clavePrivada = clavePrivada_;

            ArchivoKPEM = pathTemp + "k.pem";
            ArchivoCPEM = pathTemp + "c.pem";
            ArchivoPFX = archivoPfx_;
        }

        public bool creaPFX()
        {
            bool exito = false;

            //validaciones
            if (!File.Exists(cer))
            {
                error = "No existe el archivo cer en el sistema";
                return false;
            }
            if (!File.Exists(key))
            {
                error = "No existe el archivo key en el sistema";
                return false;
            }
            if (clavePrivada.Trim().Equals(""))
            {
                error = "No existe una clave privada aun en el sistema";
                return false;
            }

            //creamos objetos Process
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            System.Diagnostics.Process proc2 = new System.Diagnostics.Process();
            System.Diagnostics.Process proc3 = new System.Diagnostics.Process();
            proc.EnableRaisingEvents = false;
            proc2.EnableRaisingEvents = false;
            proc3.EnableRaisingEvents = false;

            //openssl x509 -inform DER -in certificado.cer -out certificado.pem
            proc.StartInfo.FileName = "openssl";
            proc.StartInfo.Arguments = "x509 -inform DER -in \"" + cer + "\" -out \"" + ArchivoCPEM + "\"";
            proc.StartInfo.WorkingDirectory = @"C:\openssl-win32\bin\";
            proc.Start();
            proc.WaitForExit();

            //openssl pkcs8 -inform DER -in llave.key -passin pass:a0123456789 -out llave.pem
            proc2.StartInfo.FileName = "openssl";
            proc2.StartInfo.Arguments = "pkcs8 -inform DER -in \"" + key + "\" -passin pass:" + clavePrivada + " -out \"" + ArchivoKPEM + "\"";
            proc2.StartInfo.WorkingDirectory = @"C:\openssl-win32\bin\";
            proc2.Start();
            proc2.WaitForExit();

            //openssl pkcs12 -export -out archivopfx.pfx -inkey llave.pem -in certificado.pem -passout pass:clavedesalida
            proc3.StartInfo.FileName = "openssl";
            proc3.StartInfo.Arguments = "pkcs12 -export -out \"" + ArchivoPFX + "\" -inkey \"" + ArchivoKPEM + "\" -in \"" + ArchivoCPEM + "\" -passout pass:" + clavePrivada;
            proc3.StartInfo.WorkingDirectory = @"C:\openssl-win32\bin\";
            proc3.Start();
            proc3.WaitForExit();

            proc.Dispose();
            proc2.Dispose();
            proc3.Dispose();

            //enviamos mensaje exitoso
            if (System.IO.File.Exists(ArchivoPFX))
                mensajeExito = "Se ha creado el archivo PFX ";
            else
            {
                error = "Error al crear el archivo PFX, puede ser que el cer o el key no sean archivos con formato correcto";
                return false;
            }

            //eliminamos los archivos pem
            if (System.IO.File.Exists(ArchivoCPEM)) System.IO.File.Delete(ArchivoCPEM);
            if (System.IO.File.Exists(ArchivoKPEM)) System.IO.File.Delete(ArchivoKPEM);

            exito = true;

            return exito;
        }
    }

Para utilizarla de la siguiente manera:


//yo siempre utilizo la misma clave privada de mi timbrado para encriptar el pfx
//la ruta para archivos temporales solo se utiliza para archivos que serán eliminados al final
oPFX = new PFX("algunaruta/archivocer.cer", "algunaruta/archivokey.key", "algunpassword", "algunacarpeta/miarchivo.pfx", "rutaparacreararchivostemporalesPem/");

if (oPFX.creaPFX())
                    Console.WriteLine("Archivo creado con éxito");
else
                    Console.WriteLine(oPFX.error);