Saltar al pie de página
COMPARACIONES DE PRODUCTOS

IronPDF vs iTextSharp: Lectura de archivos PDF en C

IronPDF ofrece una moderna API de C# para leer archivos PDF con una sintaxis más sencilla que iTextSharp. Admite la extracción de texto, el análisis de imágenes y el acceso a datos de formularios. iTextSharp requiere licencia AGPL para uso comercial, lo que convierte a IronPDF en la opción preferida para aplicaciones empresariales.

PDF (Formato de Documento Portátil) es un formato de archivo ampliamente utilizado para compartir documentos de manera consistente y segura. La lectura y manipulación de dichos archivos en C# es común en diversas aplicaciones, como sistemas de gestión de documentos y herramientas de informes. Este artículo compara dos bibliotecas populares para leer archivos PDF en C#: IronPDF e iTextSharp (la última biblioteca .NET, iText).

IronPDF es una biblioteca C# completa de Iron Software que ofrece amplias funciones para trabajar con archivos PDF. Le permite crear, editar y manipular documentos PDF sin problemas. IronPDF es conocido por su simplicidad y facilidad de uso, lo que lo convierte en una excelente opción para integrar rápidamente la funcionalidad PDF en sus aplicaciones. La biblioteca utiliza un motor de renderizado Chrome, lo que garantiza una representación precisa y compatibilidad con estándares web modernos.

iTextSharp es otra biblioteca popular para trabajar con archivos PDF en C#. Se ha utilizado ampliamente en la industria durante muchos años. Sin embargo, es fundamental comprender que la licencia de iTextSharp cambió a AGPL (Licencia Pública General Affero), lo que tiene implicaciones significativas para las aplicaciones comerciales. Según AGPL, si su aplicación utiliza iTextSharp, debe poner todo el código fuente de la aplicación a disposición de los usuarios, un requisito a menudo incompatible con el desarrollo de software propietario. Este cambio de licencia ha llevado a muchas empresas a buscar alternativas como IronPDF, que ofrece licencias comerciales.

¿Cómo leo archivos PDF usando IronPDF vs iTextSharp en C#?

  1. Crea un nuevo proyecto de C# en Visual Studio para comparar IronPDF vs. iTextSharp para leer archivos PDF.
  2. Instale las bibliotecas IronPDF e iTextSharp en su proyecto a través del Administrador de paquetes NuGet.
  3. Lea archivos PDF utilizando la API intuitiva de IronPDF para la extracción de texto.
  4. Lea archivos PDF utilizando el modelo de objetos más complejo de iTextSharp.

¿Cuáles son los requisitos previos para este tutorial?

  1. Visual Studio: Asegúrate de tener instalado Visual Studio o cualquier otro entorno de desarrollo de C#. IronPDF es compatible con entornos Windows, Linux y macOS.
  2. Administrador de paquetes NuGet: asegúrese de poder usar NuGet para administrar paquetes en su proyecto para una instalación avanzada.

¿Cómo configuro el entorno de desarrollo?

Comienza configurando una aplicación de consola de C#. Abre Visual Studio y selecciona Crear un nuevo proyecto. Selecciona el tipo de aplicación de consola. Para aplicaciones de producción, considere revisar nuestras guías sobre implementación de Azure o implementación de AWS si está planeando el procesamiento de PDF basado en la nube.

Proporcione el nombre de su proyecto como se muestra a continuación. Siguiendo las convenciones de nomenclatura de .NET, utilice PascalCase para el nombre de su proyecto para mantener la coherencia con los estándares empresariales.

Seleccione la versión .NET requerida para su proyecto. IronPDF es compatible con .NET Framework, .NET Core y .NET 5+, lo que proporciona flexibilidad tanto para aplicaciones antiguas como modernas.

Una vez hecho esto, Visual Studio generará un nuevo proyecto con la estructura necesaria para comparar las capacidades de lectura de PDF.

¿Cómo instalo las bibliotecas IronPDF y iTextSharp?

¿Qué administrador de paquetes debo utilizar para iTextSharp?

Puede instalar iTextSharp desde el Administrador de paquetes NuGet para iText. La última versión está disponible como un paquete iText. Tenga en cuenta el número de descargas relativamente menor en comparación con IronPDF, lo que refleja las preocupaciones de licencia que muchos desarrolladores tienen con AGPL.

O desde el Administrador de paquetes de Visual Studio como se muestra a continuación. Busca iText en el Administrador de paquetes y haz clic en Instalar. Tenga en cuenta que aceptar la licencia AGPL tiene implicaciones legales para la distribución de su proyecto.

¿Cómo instalo IronPDF a través de NuGet?

Puede instalar IronPDF desde el Administrador de paquetes NuGet para IronPDF como se muestra a continuación. Observe el número de descargas significativamente mayor (8,3 millones), lo que indica una adopción más amplia en aplicaciones comerciales.

O desde el Administrador de paquetes de Visual Studio como se muestra a continuación. Busque IronPDF: C# PDF Library en el Administrador de paquetes y haga clic en Instalar. El proceso de instalación es sencillo e incluye todas las dependencias necesarias para la representación de Chrome.

¿Cómo leo texto de archivos PDF usando IronPDF?

Agregue el siguiente código a su archivo Program.cs y proporcione un documento PDF de muestra con el contenido especificado. IronPDF se destaca en la extracción de texto de archivos PDF complejos, incluidos aquellos con múltiples columnas, fuentes incrustadas y varias codificaciones.

using IronPdf;

// Begin the comparison of IronPDF and iTextSharp for reading PDFs in C#
Console.WriteLine("Comparison of IronPDF And iTextSharp Read PDF Files in C#");

// Read PDF using IronPDF
ReadUsingIronPDF.Read();

public class ReadUsingIronPDF
{
    public static void Read()
    {
        // Specify the path to the PDF document
        string filename = "C:\\code\\articles\\ITextSharp\\ITextSharpIronPdfDemo\\Example.pdf";

        // Create a PDF Reader instance to read the PDF
        // IronPDF automatically handles various PDF versions and encryption
        var pdfReader = PdfDocument.FromFile(filename);

        // Extract all text from the PDF - maintains formatting and structure
        var allText = pdfReader.ExtractAllText();
        Console.WriteLine("------------------Text From PDF-----------------");
        Console.WriteLine(allText);
        Console.WriteLine("------------------Text From PDF-----------------");

        // Extract all images from the PDF - supports various image formats
        var allImages = pdfReader.ExtractAllImages();
        Console.WriteLine("------------------Image Count From PDF-----------------");
        Console.WriteLine($"Total Images = {allImages.Count()}");

        // Save extracted images if needed (production example)
        for (int i = 0; i < allImages.Count(); i++)
        {
            // allImages[i].SaveAs($"image_{i}.png");
        }
        Console.WriteLine("------------------Image Count From PDF-----------------");

        // Iterate through each page to extract text from them
        Console.WriteLine("------------------One Page Text From PDF-----------------");
        var pageCount = pdfReader.PageCount;
        for (int page = 0; page < pageCount; page++)
        {
            string text = pdfReader.ExtractTextFromPage(page);
            Console.WriteLine($"Page {page + 1} content:");
            Console.WriteLine(text);
        }

        // Additional IronPDF capabilities for production use
        // Extract form data
        var form = pdfReader.Form;
        if (form != null)
        {
            foreach (var field in form.Fields)
            {
                Console.WriteLine($"Form Field: {field.Name} = {field.Value}");
            }
        }

        // Access metadata
        Console.WriteLine($"Author: {pdfReader.MetaData.Author}");
        Console.WriteLine($"Title: {pdfReader.MetaData.Title}");
        Console.WriteLine($"Created: {pdfReader.MetaData.CreationDate}");
    }
}
using IronPdf;

// Begin the comparison of IronPDF and iTextSharp for reading PDFs in C#
Console.WriteLine("Comparison of IronPDF And iTextSharp Read PDF Files in C#");

// Read PDF using IronPDF
ReadUsingIronPDF.Read();

public class ReadUsingIronPDF
{
    public static void Read()
    {
        // Specify the path to the PDF document
        string filename = "C:\\code\\articles\\ITextSharp\\ITextSharpIronPdfDemo\\Example.pdf";

        // Create a PDF Reader instance to read the PDF
        // IronPDF automatically handles various PDF versions and encryption
        var pdfReader = PdfDocument.FromFile(filename);

        // Extract all text from the PDF - maintains formatting and structure
        var allText = pdfReader.ExtractAllText();
        Console.WriteLine("------------------Text From PDF-----------------");
        Console.WriteLine(allText);
        Console.WriteLine("------------------Text From PDF-----------------");

        // Extract all images from the PDF - supports various image formats
        var allImages = pdfReader.ExtractAllImages();
        Console.WriteLine("------------------Image Count From PDF-----------------");
        Console.WriteLine($"Total Images = {allImages.Count()}");

        // Save extracted images if needed (production example)
        for (int i = 0; i < allImages.Count(); i++)
        {
            // allImages[i].SaveAs($"image_{i}.png");
        }
        Console.WriteLine("------------------Image Count From PDF-----------------");

        // Iterate through each page to extract text from them
        Console.WriteLine("------------------One Page Text From PDF-----------------");
        var pageCount = pdfReader.PageCount;
        for (int page = 0; page < pageCount; page++)
        {
            string text = pdfReader.ExtractTextFromPage(page);
            Console.WriteLine($"Page {page + 1} content:");
            Console.WriteLine(text);
        }

        // Additional IronPDF capabilities for production use
        // Extract form data
        var form = pdfReader.Form;
        if (form != null)
        {
            foreach (var field in form.Fields)
            {
                Console.WriteLine($"Form Field: {field.Name} = {field.Value}");
            }
        }

        // Access metadata
        Console.WriteLine($"Author: {pdfReader.MetaData.Author}");
        Console.WriteLine($"Title: {pdfReader.MetaData.Title}");
        Console.WriteLine($"Created: {pdfReader.MetaData.CreationDate}");
    }
}
$vbLabelText   $csharpLabel

¿Qué hace el código IronPDF?

  1. Cree un documento de Word: inicialmente, cree un documento de Word con el contenido de texto deseado y guárdelo como un documento PDF llamado Example.pdf .
  2. Instancia PDFReader: el código crea un objeto PdfDocument utilizando la ruta del archivo PDF para extraer texto e imágenes.
  3. Extraer texto e imágenes: el método ExtractAllText se utiliza para capturar todo el texto del documento, mientras que ExtractAllImages extrae imágenes.
  4. Extraer texto por página: el texto de cada página se extrae utilizando el método ExtractTextFromPage .

¿Qué resultado debo esperar de IronPDF?

¿Cómo leo texto de archivos PDF usando iTextSharp?

Ahora, para comparar la extracción de texto de iTextSharp, agregue el siguiente código al mismo archivo Program.cs. Para simplificar, no hemos separado las clases en archivos diferentes. Observe cómo iTextSharp requiere un código más complejo para operaciones básicas.

using IronPdf;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas.Parser.Listener;
using iText.Kernel.Pdf.Canvas.Parser;
using iText.Kernel.Pdf.Xobject;

// Begin the comparison of IronPDF and iTextSharp for reading PDFs in C#
Console.WriteLine("Comparison of IronPDF And iTextSharp Read PDF Files in C#");

// Call method to read PDF using iTextSharp library
ReadUsingITextSharp.Read();

public class ReadUsingITextSharp
{
    public static void Read()
    {
        // Specify the path to the PDF document
        string pdfFile = "C:\\code\\articles\\ITextSharp\\ITextSharpIronPdfDemo\\Example.pdf";

        // Create a PDF Reader instance - more verbose than IronPDF
        PdfReader pdfReader = new PdfReader(pdfFile);

        // Initialize a new PDF Document - additional step required
        iText.Kernel.Pdf.PdfDocument pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader);

        // Extract text from all pages - more complex than IronPDF
        Console.WriteLine("------------------Text From PDF (iTextSharp)-----------------");
        for (int page = 1; page <= pdfDocument.GetNumberOfPages(); page++)
        {
            // Use a text extraction strategy to extract plain text from the PDF
            LocationTextExtractionStrategy strategy = new LocationTextExtractionStrategy();
            string pdfText = PdfTextExtractor.GetTextFromPage(pdfDocument.GetPage(page), strategy);
            Console.WriteLine($"Page {page} content:");
            Console.WriteLine(pdfText);
        }

        // Extract images - significantly more complex than IronPDF
        Console.WriteLine("------------------Images From PDF (iTextSharp)-----------------");
        int imageCount = 0;
        for (int pageNum = 1; pageNum <= pdfDocument.GetNumberOfPages(); pageNum++)
        {
            var page = pdfDocument.GetPage(pageNum);
            var resources = page.GetResources();
            var xobjects = resources.GetResource(PdfName.XObject);

            if (xobjects != null)
            {
                foreach (var key in xobjects.KeySet())
                {
                    var xobject = xobjects.GetAsStream(key);
                    if (xobject != null)
                    {
                        var pdfObject = xobjects.Get(key);
                        if (pdfObject.IsStream())
                        {
                            var stream = (PdfStream)pdfObject;
                            var subtype = stream.GetAsName(PdfName.Subtype);
                            if (PdfName.Image.Equals(subtype))
                            {
                                imageCount++;
                                // Extracting the actual image requires additional complex code
                            }
                        }
                    }
                }
            }
        }
        Console.WriteLine($"Total Images Found: {imageCount}");

        // Close the document - manual resource management required
        pdfDocument.Close();
        pdfReader.Close();
    }
}
using IronPdf;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas.Parser.Listener;
using iText.Kernel.Pdf.Canvas.Parser;
using iText.Kernel.Pdf.Xobject;

// Begin the comparison of IronPDF and iTextSharp for reading PDFs in C#
Console.WriteLine("Comparison of IronPDF And iTextSharp Read PDF Files in C#");

// Call method to read PDF using iTextSharp library
ReadUsingITextSharp.Read();

public class ReadUsingITextSharp
{
    public static void Read()
    {
        // Specify the path to the PDF document
        string pdfFile = "C:\\code\\articles\\ITextSharp\\ITextSharpIronPdfDemo\\Example.pdf";

        // Create a PDF Reader instance - more verbose than IronPDF
        PdfReader pdfReader = new PdfReader(pdfFile);

        // Initialize a new PDF Document - additional step required
        iText.Kernel.Pdf.PdfDocument pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader);

        // Extract text from all pages - more complex than IronPDF
        Console.WriteLine("------------------Text From PDF (iTextSharp)-----------------");
        for (int page = 1; page <= pdfDocument.GetNumberOfPages(); page++)
        {
            // Use a text extraction strategy to extract plain text from the PDF
            LocationTextExtractionStrategy strategy = new LocationTextExtractionStrategy();
            string pdfText = PdfTextExtractor.GetTextFromPage(pdfDocument.GetPage(page), strategy);
            Console.WriteLine($"Page {page} content:");
            Console.WriteLine(pdfText);
        }

        // Extract images - significantly more complex than IronPDF
        Console.WriteLine("------------------Images From PDF (iTextSharp)-----------------");
        int imageCount = 0;
        for (int pageNum = 1; pageNum <= pdfDocument.GetNumberOfPages(); pageNum++)
        {
            var page = pdfDocument.GetPage(pageNum);
            var resources = page.GetResources();
            var xobjects = resources.GetResource(PdfName.XObject);

            if (xobjects != null)
            {
                foreach (var key in xobjects.KeySet())
                {
                    var xobject = xobjects.GetAsStream(key);
                    if (xobject != null)
                    {
                        var pdfObject = xobjects.Get(key);
                        if (pdfObject.IsStream())
                        {
                            var stream = (PdfStream)pdfObject;
                            var subtype = stream.GetAsName(PdfName.Subtype);
                            if (PdfName.Image.Equals(subtype))
                            {
                                imageCount++;
                                // Extracting the actual image requires additional complex code
                            }
                        }
                    }
                }
            }
        }
        Console.WriteLine($"Total Images Found: {imageCount}");

        // Close the document - manual resource management required
        pdfDocument.Close();
        pdfReader.Close();
    }
}
$vbLabelText   $csharpLabel

¿Qué salida produce iTextSharp?

¿Cuáles son las limitaciones de iTextSharp?

  1. Curva de aprendizaje : curva de aprendizaje más pronunciada, especialmente para principiantes.
  2. Licencia : la licencia AGPL requiere que su aplicación sea de código abierto.
  3. API compleja : las operaciones simples requieren múltiples objetos y gestión manual.
  4. Compatibilidad con HTML limitada : representación HTML mínima en comparación con IronPDF.
  5. Gestión manual de recursos : debe cerrar los recursos explícitamente.

  6. Curva de aprendizaje: iTextSharp tiene una curva de aprendizaje más pronunciada, especialmente para principiantes.
  7. Licencias: el modelo de licencias de iTextSharp puede no ser adecuado para todos los proyectos, especialmente aquellos con limitaciones presupuestarias.

  8. Facilidad de uso : API sencilla que sigue las convenciones .NET.
  9. Representación del documento : la representación con resolución de píxeles perfecta mantiene el formato original.
  10. Licencias comerciales favorables : Licencias transparentes sin restricciones AGPL.
  11. Funciones completas : Soporte integrado para formularios, firmas y anotaciones.
  12. Mejor rendimiento : mejorado para el procesamiento de documentos grandes y de múltiples subprocesos.

  13. Facilidad de uso: IronPDF es conocido por su API sencilla, lo que facilita que los desarrolladores comiencen a usarlo.
  14. Representación de documentos: IronPDF proporciona una representación precisa de documentos PDF, lo que garantiza que el texto extraído sea fiel al original.

Para los equipos que actualmente utilizan iTextSharp, migrar a IronPDF es sencillo. Considera el siguiente ejemplo de código:

// Migration Example: Text Extraction
// iTextSharp (old way)
PdfReader reader = new PdfReader(filename);
PdfDocument doc = new PdfDocument(reader);
string text = PdfTextExtractor.GetTextFromPage(doc.GetPage(1));
doc.Close();

// IronPDF (new way)
var pdf = PdfDocument.FromFile(filename);
string text = pdf.ExtractTextFromPage(0); // 0-based indexing

// Migration Example: Form Field Reading
// iTextSharp (complex)
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDocument, false);
IDictionary<string, PdfFormField> fields = form.GetFormFields();
foreach (var field in fields)
{
    string value = field.Value.GetValueAsString();
}

// IronPDF (simple)
var form = pdf.Form;
foreach (var field in form.Fields)
{
    string value = field.Value;
}
// Migration Example: Text Extraction
// iTextSharp (old way)
PdfReader reader = new PdfReader(filename);
PdfDocument doc = new PdfDocument(reader);
string text = PdfTextExtractor.GetTextFromPage(doc.GetPage(1));
doc.Close();

// IronPDF (new way)
var pdf = PdfDocument.FromFile(filename);
string text = pdf.ExtractTextFromPage(0); // 0-based indexing

// Migration Example: Form Field Reading
// iTextSharp (complex)
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDocument, false);
IDictionary<string, PdfFormField> fields = form.GetFormFields();
foreach (var field in fields)
{
    string value = field.Value.GetValueAsString();
}

// IronPDF (simple)
var form = pdf.Form;
foreach (var field in form.Fields)
{
    string value = field.Value;
}
$vbLabelText   $csharpLabel

¿Cómo se compara la precisión de la extracción de texto?

IronPDF se destaca en el manejo de archivos PDF complejos que desafían a otras bibliotecas:

  • Documentos escaneados : mejor flujo de texto al procesar archivos PDF con OCR
  • Diseños de varias columnas : Manejo superior de diseños estilo periódico
  • Archivos cifrados : manejo automático de archivos PDF protegidos con contraseña
  • Compatibilidad con Unicode : compatibilidad total con UTF-8 e idiomas internacionales
  • Fuentes incrustadas : extracción precisa independientemente de la incrustación de fuentes

¿Cómo configuro la licencia para IronPDF?

Inserte su clave de licencia de IronPDF en el archivo appsettings.json . Para implementaciones de producción, considere usar variables de entorno para una gestión segura de claves.

{
  "IronPdf.LicenseKey": "your license key",
  "IronPdf.LoggingMode": "Custom",
  "IronPdf.ChromeGpuMode": "Disabled"
}

Para recibir una licencia de prueba, proporcione su correo electrónico en nuestra página de licencias. IronPDF ofrece opciones de licencia flexibles que incluyen licencias de desarrollo, prueba y producción.## ¿Qué biblioteca debo elegir para mi proyecto?

La elección entre IronPDF y iTextSharp depende de las necesidades específicas de su proyecto. Para aplicaciones empresariales que requieren licencias comerciales , IronPDF es la opción preferida debido a la licencia AGPL restrictiva de iTextSharp. Si necesita una biblioteca sencilla y fácil de usar para operaciones PDF comunes, IronPDF ofrece una experiencia de desarrollador superior con su API intuitiva.

Tenga en cuenta estos factores al tomar su decisión:

Requisitos de licencia : AGPL vs. licencias comerciales favorables

IronPDF está diseñado para integrar sin problemas la generación de PDF en su aplicación, manejando de manera eficiente la conversión de documentos formateados a PDF. Este enfoque proporciona claros beneficios cuando necesita convertir formularios web , páginas HTML locales y otro contenido web a PDF mediante .NET . Su aplicación puede descargar , enviar por correo electrónico o almacenar documentos en la nube cómodamente. Ya sea que necesite producir facturas , cotizaciones , informes , contratos u otros documentos profesionales , las capacidades de generación de PDF de IronPDF lo cubrirán. La biblioteca también admite funciones avanzadas como compresión de PDF , linealización para visualización web rápida y compatibilidad con PDF/A para archivo a largo plazo. Mejore su aplicación con las capacidades de generación de PDF intuitivas y eficientes de IronPDF.

Por favor notaiText e iTextSharp son marcas registradas de sus respectivos propietarios. Este sitio no está afiliado, avalado ni patrocinado por iText o iTextSharp. Todos los nombres de productos, logotipos y marcas son propiedad de sus respectivos dueños. Las comparaciones son sólo para fines informativos y reflejan información disponible públicamente al momento de escribir.

Preguntas Frecuentes

¿Cómo puedo leer archivos PDF en C#?

Puedes leer archivos PDF utilizando la biblioteca IronPDF creando una instancia de PdfDocument y usando métodos como ExtractAllText y ExtractAllImages para extraer contenido del PDF.

¿Qué debo considerar al elegir una biblioteca PDF para C#?

Considera factores como facilidad de uso, licenciamiento, curva de aprendizaje y requisitos específicos del proyecto al elegir entre bibliotecas como IronPDF e iTextSharp para manipulación de PDF en C#.

¿Cómo puedo instalar una biblioteca PDF en mi proyecto C#?

Puedes instalar IronPDF a través del Gestor de Paquetes NuGet en Visual Studio buscando 'IronPDF: C# PDF Library' y haciendo clic en el botón 'Instalar'.

¿Cuáles son las ventajas de usar IronPDF para la manipulación de PDF?

IronPDF ofrece facilidad de uso, una API sencilla y una representación precisa de documentos, lo que lo hace ideal para desarrolladores que necesitan integrar rápidamente funcionalidades PDF en sus aplicaciones.

¿Existe una diferencia en la complejidad de usar IronPDF e iTextSharp?

Sí, IronPDF es conocido por su simplicidad, mientras que iTextSharp ofrece más flexibilidad y extensibilidad, lo que puede implicar una curva de aprendizaje más pronunciada.

¿Puede IronPDF convertir contenido HTML a PDF?

Sí, IronPDF puede convertir sin problemas contenido HTML, como formularios web y páginas, en documentos PDF, facilitando tareas como descargar y enviar PDFs por correo electrónico.

¿Cuáles son algunas limitaciones de usar iTextSharp para tareas PDF?

iTextSharp puede presentar una curva de aprendizaje más pronunciada y su modelo de licenciamiento podría no ajustarse a todos los presupuestos de los proyectos, especialmente si buscas una solución sencilla.

¿Cómo mejora IronPDF la funcionalidad de la aplicación?

IronPDF permite la integración de generación y manipulación de PDFs en aplicaciones, permitiendo la conversión de contenido web a PDFs y el manejo de documentos profesionales como facturas e informes.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más