Cómo convertir HTML a PDF en ASP .NET Core

Chaknith Bin
Chaknith Bin
27 de junio, 2020
Actualizado 28 de enero, 2025
Compartir:
This article was translated from English: Does it need improvement?
Translated
View the article in English

Generador de PDF .NET Core

Crear archivos PDF en .NET Core es una tarea engorrosa. Trabajar con PDF en proyectos ASP.NET MVC, así como convertir vistas MVC, archivos HTML y páginas web en línea a PDF puede ser todo un reto. Este tutorial trabaja con la herramienta IronPDF para abordar estos problemas, proporcionando directrices instructivas para muchas de sus necesidades PDF .NET.

IronPDF también admite la depuración de su HTML con Chrome para PDFs de Pixel Perfect.


Visión general

Después de este tutorial, serás capaz de:

  • Convierte a PDF desde diferentes fuentes como URL, HTML, vistas MVC
  • Utiliza las opciones avanzadas para diferentes configuraciones de salida de PDF
  • Implanta tu proyecto en Linux y Windows
  • Trabajar con funciones de manipulación de documentos PDF
  • Añadir encabezados y pies de página, fusionar archivos, añadir sellos
  • Trabaja con Dockers

    Esta amplia gama de funciones de HTML a PDF de .NET Core le ayudará con toda una serie de necesidades de proyecto.

    Comience con IronPDF

    Comience a usar IronPDF en su proyecto hoy con una prueba gratuita.

    Primer Paso:
    green arrow pointer


Primer paso

1. Instale la biblioteca IronPDF

IronPDF puede instalarse y utilizarse en todos los tipos de proyectos .NET, como aplicaciones Windows, ASP.NET MVC y aplicaciones .NET Core.

Para añadir la librería IronPDF a nuestro proyecto tenemos dos formas, o bien desde el editor de Visual Studio instalar usando NuGet, o bien con una línea de comandos usando el gestor de consola de paquetes.

Instalación con NuGet

Para agregar la biblioteca IronPDF a nuestro proyecto usando NuGet, podemos usar la interfaz visualizada (NuGet Package Manager) o por comando usando Package Manager Console:

1.1.1 Uso del gestor de paquetes NuGet

1- Right click on project name -> Select Manage NuGet Package 1 related to Instalación con NuGet 2- From browser tab -> search for IronPdf -> Install 2 related to Instalación con NuGet 3- Click Ok 3 related to Instalación con NuGet 4- Done! 4 related to Instalación con NuGet

1.1.2 Uso del gestor de la consola de paquetes NuGet

1- From Tools -> NuGet Package Manager -> Package Manager Console 5 related to Instalación con NuGet 2- Run command -> Install-Package IronPdf 6 related to Instalación con NuGet


Tutoriales prácticos

2. Convertir página web a PDF

Ejemplo: Aplicación de consola ConvertUrlToPdf

Siga estos pasos para crear un nuevo proyecto Asp.NET MVC


1- Open Visual Studio 7 related to 2. Convertir página web a PDF 2- Choose Create new project 8 related to 2. Convertir página web a PDF 3- Choose Console App (.NET Core) 9 related to 2. Convertir página web a PDF 4- Give our sample name “ConvertUrlToPdf” and click create 10 related to 2. Convertir página web a PDF 5- Now we have a console application created 11 related to 2. Convertir página web a PDF 6- Add IronPdf => click install 12 related to 2. Convertir página web a PDF 13 related to 2. Convertir página web a PDF

7- Agregue nuestras primeras líneas que renderizan la página principal de Wikipedia a PDF

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-1.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderUrlAsPdf("https://www.wikipedia.org/");
pdf.SaveAs("wiki.pdf");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

8- Run and check created file wiki.pdf 14 related to 2. Convertir página web a PDF


3. Convertir .NET Core HTML a PDF

Sample: ConvertHTMLToPdf Console application

To render HTML to PDF we have two ways:
1- Write HTML into string then render it
2- Write HTML into file and pass it path to IronPDF to render it

Rendering the HTML string sample code will look like this.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-2.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Hello IronPdf</h1>");
pdf.SaveAs("HtmlString.pdf");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Y el PDF resultante se verá así.

15 related to 3. Convertir .NET Core HTML a PDF


4. Convertir vista MVC a PDF

Ejemplo: Aplicación MVC de TicketsApps .NET Core

Pongamos un ejemplo de la vida real. He elegido un sitio de venta de entradas en línea. Abra el sitio, navegue hasta "reservar entrada", rellene la información requerida y, a continuación, descargue su copia en formato PDF.

Vamos a seguir estos pasos:

Crear proyecto

  1. Elija el proyecto "Aplicación web de ASP.NET Core (Modelo-Vista-Controlador)".

    16 related to Crear proyecto
  2. Nombra el proyecto "TicketsApps"

    17 related to Crear proyecto
  3. Usemos .NET 8 con Linux Docker habilitado. Dentro del Dockerfile, cambia de "USER app" a "USER root". Esto garantizará que se conceden suficientes permisos a la biblioteca.

    18 related to Crear proyecto
  4. Ya está listo. 19 related to Crear proyecto

Añadir modelo de cliente

  1. Haga clic con el botón derecho en la carpeta "Modelos" y añada una clase.

    20 related to Añadir modelo de cliente
  2. Nombre el modelo "ClientModel" y haga clic en añadir.

    21 related to Añadir modelo de cliente
  3. Añade los atributos 'name', 'phone' y 'email' a la clase ClientModel. Haz que todos sean obligatorios añadiendo el atributo 'Required' sobre cada uno de ellos como sigue:
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-3.cs
public class ClientModel
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Phone { get; set; }
    [Required]
    public string Email { get; set; }
}
Public Class ClientModel
	<Required>
	Public Property Name() As String
	<Required>
	Public Property Phone() As String
	<Required>
	Public Property Email() As String
End Class
$vbLabelText   $csharpLabel

Añadir servicios al cliente

  1. Crea una carpeta y nómbrala "servicios"

  2. Añade una clase llamada "ClientServices"

  3. Añade un objeto estático de tipo "ClientModel" para utilizarlo como repositorio.

  4. Añade dos funciones: una para guardar clientes en el repositorio, y la segunda para recuperar clientes guardados.
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-4.cs
public class ClientServices
{
    private static ClientModel _clientModel;
    public static void AddClient(ClientModel clientModel)
    {
        _clientModel = clientModel;
    }
    public static ClientModel GetClient()
    {
        return _clientModel;
    }
}
Public Class ClientServices
	Private Shared _clientModel As ClientModel
	Public Shared Sub AddClient(ByVal clientModel As ClientModel)
		_clientModel = clientModel
	End Sub
	Public Shared Function GetClient() As ClientModel
		Return _clientModel
	End Function
End Class
$vbLabelText   $csharpLabel

Diseño de la página de reserva de entradas

  1. Desde el explorador de soluciones, haga clic con el botón derecho en la carpeta "Controladores" y añada un controlador.

    22 related to Diseño de la página de reserva de entradas
  2. Nómbralo "BookTicketController"

    23 related to Diseño de la página de reserva de entradas
  3. Haz clic derecho en la función index (o como la llamamos acción) y elige "Agregar Vista."

    24 related to Diseño de la página de reserva de entradas
  4. Añade una Vista llamada "índice"

    25 related to Diseño de la página de reserva de entradas
  5. Actualice el HTML del siguiente modo
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-5.cs
@model IronPdfMVCHelloWorld.Models.ClientModel
@{
  ViewBag.Title = "Book Ticket";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
  <div class="form-horizontal">
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
      @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
      </div>
    </div>
    <div class="form-group">
      @Html.LabelFor(model => model.Phone, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Phone, "", new { @class = "text-danger" })
      </div>
    </div>
    <div class="form-group">
      @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
      </div>
    </div>
    <div class="form-group">
      <div class="col-md-10 pull-right">
        <button type="submit" value="Save" class="btn btn-sm">
          <i class="fa fa-plus"></i>
          <span>
            Save
          </span>
        </button>
      </div>
    </div>
  </div>
}
model ReadOnly Property () As IronPdfMVCHelloWorld.Models.ClientModel
  ViewBag.Title = "Book Ticket"
End Property
'INSTANT VB TODO TASK: The following line could not be converted:
(Of h2) Index</h2> [using](Html.BeginForm())
If True Then
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'  <div class="form-horizontal"> @Html.ValidationSummary(True, "", New { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Name, htmlAttributes: New { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Name, New { htmlAttributes = New { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", New { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Phone, htmlAttributes: New { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Phone, New { htmlAttributes = New { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Phone, "", New { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Email, htmlAttributes: New { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Email, New { htmlAttributes = New { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Email, "", New { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-10 pull-right"> <button type="submit" value="Save" class="btn btn-sm"> <i class="fa fa-plus"></i> <span> Save </span> </button> </div> </div> </div> }
$vbLabelText   $csharpLabel
  1. Añadir un enlace de navegación que permita a los visitantes de nuestro sitio web navegar hasta nuestra nueva página de reservas. Esto se puede hacer actualizando el diseño en la ruta existente (Views -> Shared -> _Layout.cshtml). Añade el siguiente código:
<li class="nav-item">
    <a
        class="nav-link text-dark"
        asp-area=""
        asp-controller="BookTicket"
        asp-action="Index"
        >Book Ticket</a
    >
</li>
<li class="nav-item">
    <a
        class="nav-link text-dark"
        asp-area=""
        asp-controller="BookTicket"
        asp-action="Index"
        >Book Ticket</a
    >
</li>
HTML
  1. El resultado debería ser el siguiente.

    26 related to Diseño de la página de reserva de entradas
  2. Vaya a la página "Reservar billete". Debería tener este aspecto: 27 related to Diseño de la página de reserva de entradas

Validar y guardar la información de la reserva

  1. Agrega otra acción de índice con el atributo [HttpPost] para informar al motor MVC que esta acción es para enviar datos. Valida el modelo enviado, y si es válido, el código redirigirá al visitante a la página TicketView. Si no es válida, el visitante recibirá mensajes de error de validación en la pantalla.
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-7.cs
[HttpPost]
public ActionResult Index(ClientModel model)
{
    if (ModelState.IsValid)
    {
        ClientServices.AddClient(model);
        return RedirectToAction("TicketView");
    }
  return View(model);
}
<HttpPost>
Public Function Index(ByVal model As ClientModel) As ActionResult
	If ModelState.IsValid Then
		ClientServices.AddClient(model)
		Return RedirectToAction("TicketView")
	End If
  Return View(model)
End Function
$vbLabelText   $csharpLabel

Ejemplo de mensajes de error

28 related to Validar y guardar la información de la reserva
  1. Cree un modelo Ticket en el archivo "Modelos" y añada el código siguiente
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-9.cs
public class TicketModel : ClientModel
{
    public int TicketNumber { get; set; }
    public DateTime TicketDate { get; set; }
}
Public Class TicketModel
	Inherits ClientModel

	Public Property TicketNumber() As Integer
	Public Property TicketDate() As DateTime
End Class
$vbLabelText   $csharpLabel
  1. Añadir TicketView para mostrar nuestro ticket. Esta vista alojará una vista parcial del ticket que se encargará de mostrar el ticket y que se utilizará posteriormente para imprimir el ticket.
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-8.cs
public ActionResult TicketView()
{
    var rand = new Random();
    var client = ClientServices.GetClient();
    var ticket = new TicketModel()
    {
        TicketNumber = rand.Next(100000, 999999),
        TicketDate = DateTime.Now,
        Email = client.Email,
        Name = client.Name,
        Phone = client.Phone
    };

    return View(ticket);
}
Public Function TicketView() As ActionResult
	Dim rand = New Random()
	Dim client = ClientServices.GetClient()
	Dim ticket = New TicketModel() With {
		.TicketNumber = rand.Next(100000, 999999),
		.TicketDate = DateTime.Now,
		.Email = client.Email,
		.Name = client.Name,
		.Phone = client.Phone
	}

	Return View(ticket)
End Function
$vbLabelText   $csharpLabel
  1. Haga clic con el botón derecho en la función TicketView, seleccione "Añadir vista" y nómbrela "TicketView". Añade el siguiente código:
@model TicketsApps.Models.TicketModel @{ ViewData["Title"] = "TicketView"; }
@Html.Partial("_TicketPdf", Model) @using (Html.BeginForm()) { @Html.HiddenFor(c
=> c.Email) @Html.HiddenFor(c => c.Name) @Html.HiddenFor(c => c.Phone)
@Html.HiddenFor(c => c.TicketDate) @Html.HiddenFor(c => c.TicketNumber)

<div class="form-group">
    <div class="col-md-10 pull-right">
        <button type="submit" value="Save" class="btn btn-sm">
            <i class="fa fa-plus"></i>
            <span> Download Pdf </span>
        </button>
    </div>
</div>
}
@model TicketsApps.Models.TicketModel @{ ViewData["Title"] = "TicketView"; }
@Html.Partial("_TicketPdf", Model) @using (Html.BeginForm()) { @Html.HiddenFor(c
=> c.Email) @Html.HiddenFor(c => c.Name) @Html.HiddenFor(c => c.Phone)
@Html.HiddenFor(c => c.TicketDate) @Html.HiddenFor(c => c.TicketNumber)

<div class="form-group">
    <div class="col-md-10 pull-right">
        <button type="submit" value="Save" class="btn btn-sm">
            <i class="fa fa-plus"></i>
            <span> Download Pdf </span>
        </button>
    </div>
</div>
}
HTML
  1. Haga clic con el botón derecho en el archivo BookTicket, añada otra Vista y nómbrela "_TicketPdf" Añada el siguiente código:
@model TicketsApps.Models.TicketModel @{ Layout = null; }
<link href="../css/ticket.css" rel="stylesheet" />
<div class="ticket">
    <div class="stub">
        <div class="top">
            <span class="admit">VIP</span>
            <span class="line"></span>
            <span class="num">
                @Model.TicketNumber
                <span> Ticket</span>
            </span>
        </div>
        <div class="number">1</div>
        <div class="invite">Room Number</div>
    </div>
    <div class="check">
        <div class="big">
            Your <br />
            Ticket
        </div>
        <div class="number">VIP</div>
        <div class="info">
            <section>
                <div class="title">Date</div>
                <div>@Model.TicketDate.ToShortDateString()</div>
            </section>
            <section>
                <div class="title">Issued By</div>
                <div>Admin</div>
            </section>
            <section>
                <div class="title">Invite Number</div>
                <div>@Model.TicketNumber</div>
            </section>
        </div>
    </div>
</div>
@model TicketsApps.Models.TicketModel @{ Layout = null; }
<link href="../css/ticket.css" rel="stylesheet" />
<div class="ticket">
    <div class="stub">
        <div class="top">
            <span class="admit">VIP</span>
            <span class="line"></span>
            <span class="num">
                @Model.TicketNumber
                <span> Ticket</span>
            </span>
        </div>
        <div class="number">1</div>
        <div class="invite">Room Number</div>
    </div>
    <div class="check">
        <div class="big">
            Your <br />
            Ticket
        </div>
        <div class="number">VIP</div>
        <div class="info">
            <section>
                <div class="title">Date</div>
                <div>@Model.TicketDate.ToShortDateString()</div>
            </section>
            <section>
                <div class="title">Issued By</div>
                <div>Admin</div>
            </section>
            <section>
                <div class="title">Invite Number</div>
                <div>@Model.TicketNumber</div>
            </section>
        </div>
    </div>
</div>
HTML
  1. Agrega el siguiente archivo "ticket.css" en el archivo "wwwroot/css".

  2. Añada IronPDF al proyecto y acepte la licencia.

    31 related to Validar y guardar la información de la reserva
  3. Añade el método post TicketView que manejará el botón de descarga.
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-10.cs
[HttpPost]
public ActionResult TicketView(TicketModel model)
{
    IronPdf.Installation.TempFolderPath = $@"{Directory.GetParent}/irontemp/";
    IronPdf.Installation.LinuxAndDockerDependenciesAutoConfig = true;
    var html = this.RenderViewAsync("_TicketPdf", model);
    var renderer = new IronPdf.ChromePdfRenderer();
    using var pdf = renderer.RenderHtmlAsPdf(html.Result, @"wwwroot/css");
    return File(pdf.Stream.ToArray(), "application/pdf");
}
<HttpPost>
Public Function TicketView(ByVal model As TicketModel) As ActionResult
	IronPdf.Installation.TempFolderPath = $"{AddressOf Directory.GetParent}/irontemp/"
	IronPdf.Installation.LinuxAndDockerDependenciesAutoConfig = True
	Dim html = Me.RenderViewAsync("_TicketPdf", model)
	Dim renderer = New IronPdf.ChromePdfRenderer()
	Dim pdf = renderer.RenderHtmlAsPdf(html.Result, "wwwroot/css")
	Return File(pdf.Stream.ToArray(), "application/pdf")
End Function
$vbLabelText   $csharpLabel
  1. Cree un controlador en el archivo "Controller" y nómbrelo "ControllerExtensions". Este controlador convertirá la vista parcial en una cadena. Utilice el código de extensión como se indica a continuación:
:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-11.cs
using System.IO;
using System.Threading.Tasks;

public static class ControllerExtensions
{
    public static async Task<string> RenderViewAsync<TModel>(this Controller controller, string viewName, TModel model, bool partial = false)
    {
        if (string.IsNullOrEmpty(viewName))
        {
            viewName = controller.ControllerContext.ActionDescriptor.ActionName;
        }
        controller.ViewData.Model = model;
        using (var writer = new StringWriter())
        {
            IViewEngine viewEngine = controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
            ViewEngineResult viewResult = viewEngine.FindView(controller.ControllerContext, viewName, !partial);
            if (viewResult.Success == false)
            {
                return $"A view with the name {viewName} could not be found";
            }
            ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, writer, new HtmlHelperOptions());
            await viewResult.View.RenderAsync(viewContext);
            return writer.GetStringBuilder().ToString();
        }
    }
}
Imports System.IO
Imports System.Threading.Tasks

Public Module ControllerExtensions
	<System.Runtime.CompilerServices.Extension> _
	Public Async Function RenderViewAsync(Of TModel)(ByVal controller As Controller, ByVal viewName As String, ByVal model As TModel, Optional ByVal As Boolean = False) As Task(Of String)
		If String.IsNullOrEmpty(viewName) Then
			viewName = controller.ControllerContext.ActionDescriptor.ActionName
		End If
		controller.ViewData.Model = model
		Using writer = New StringWriter()
			Dim viewEngine As IViewEngine = TryCast(controller.HttpContext.RequestServices.GetService(GetType(ICompositeViewEngine)), ICompositeViewEngine)
			Dim viewResult As ViewEngineResult = viewEngine.FindView(controller.ControllerContext, viewName, Not partial)
			If viewResult.Success = False Then
				Return $"A view with the name {viewName} could not be found"
			End If
			Dim viewContext As New ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, writer, New HtmlHelperOptions())
			Await viewResult.View.RenderAsync(viewContext)
			Return writer.GetStringBuilder().ToString()
		End Using
	End Function
End Module
$vbLabelText   $csharpLabel
  1. Ejecute la aplicación y rellene los datos de la entrada, después haga clic en "Guardar". 32 related to Validar y guardar la información de la reserva
  2. View the generated ticket 33 related to Validar y guardar la información de la reserva

Descargar billete PDF

Para descargar el billete en formato PDF, haga clic en "Descargar Pdf". Recibirá un PDF con el billete.

Puede descargar el código completo de esta guía. Viene como un archivo comprimido que puede abrir en Visual Studio. Haga clic aquí para descargar el proyecto.


5. Tabla de opciones de renderizado de PDF de .NET

Tenemos algunas opciones avanzadas que definen las opciones de renderizado del PDF, como el ajuste de los márgenes,

orientación del papel, tamaño del papel, etc.

A continuación encontrará un cuadro que ilustra las distintas opciones.

Class ChromePdfRenderer
Description Used to define PDF print out options, like paper size, DPI, headers and footers
Properties / functions Type Description
CustomCookies Dictionary<string, string> Custom cookies for the HTML render. Cookies do not persist between renders and must be set each time.
PaperFit VirtualPaperLayoutManager A manager for setting up virtual paper layouts, controlling how content will be laid out on PDF "paper" pages. Includes options for Default Chrome Behavior, Zoomed, Responsive CSS3 Layouts, Scale-To-Page & Continuous Feed style PDF page setups.
UseMarginsOnHeaderAndFooter UseMargins Use margin values from the main document when rendering headers and footers.
CreatePdfFormsFromHtml bool Turns all HTML form elements into editable PDF forms. Default value is true.
CssMediaType PdfCssMediaType Enables Media="screen" CSS Styles and StyleSheets. Default value is PdfCssMediaType.Screen.
CustomCssUrl string Allows a custom CSS style-sheet to be applied to HTML before rendering. May be a local file path or a remote URL. Only applicable when rendering HTML to PDF.
EnableJavaScript bool Enables JavaScript and JSON to be executed before the page is rendered. Ideal for printing from Ajax / Angular Applications. Default value is false.
EnableMathematicalLaTex bool Enables rendering of Mathematical LaTeX Elements.
Javascript string A custom JavaScript string to be executed after all HTML has loaded but before PDF rendering.
JavascriptMessageListener StringDelegate A method callback to be invoked whenever a browser JavaScript console message becomes available.
FirstPageNumber int First page number to be used in PDF Headers and Footers. Default value is 1.
TableOfContents TableOfContentsTypes Generates a table of contents at the location in the HTML document where an element is found with id "ironpdf-toc".
GrayScale bool Outputs a black-and-white PDF. Default value is false.
TextHeader ITextHeaderFooter Sets the footer content for every PDF page as text, supporting 'mail-merge' and automatically turning URLs into hyperlinks.
TextFooter
HtmlHeader HtmlHeaderFooter Sets the header content for every PDF page as HTML. Supports 'mail-merge'.
HtmlFooter
InputEncoding Encoding The input character encoding as a string. Default value is Encoding.UTF8.
MarginTop double Top PDF "paper" margin in millimeters. Set to zero for border-less and commercial printing applications. Default value is 25.
MarginRight double Right PDF "paper" margin in millimeters. Set to zero for border-less and commercial printing applications. Default value is 25.
MarginBottom double Bottom PDF "paper" margin in millimeters. Set to zero for border-less and commercial printing applications. Default value is 25.
MarginLeft double Left PDF "paper" margin in millimeters. Set to zero for border-less and commercial printing applications. Default value is 25.
PaperOrientation PdfPaperOrientation The PDF paper orientation, such as Portrait or Landscape. Default value is Portrait.
PaperSize PdfPaperSize Sets the paper size
SetCustomPaperSizeinCentimeters double Sets the paper size in centimeters.
SetCustomPaperSizeInInches Sets the paper size in inches.
SetCustomPaperSizeinMilimeters Sets the paper size in millimeters.
SetCustomPaperSizeinPixelsOrPoints Sets the paper size in screen pixels or printer points.
PrintHtmlBackgrounds Boolean Indicates whether to print background-colors and images from HTML. Default value is true.
RequestContext RequestContexts Request context for this render, determining isolation of certain resources such as cookies.
Timeout Integer Render timeout in seconds. Default value is 60.
Title String PDF Document Name and Title metadata, useful for mail-merge and automatic file naming in the IronPdf MVC and Razor extensions.
ForcePaperSize Boolean Force page sizes to be exactly what is specified via IronPdf.ChromePdfRenderOptions.PaperSize by resizing the page after generating a PDF from HTML. Helps correct small errors in page size when rendering HTML to PDF.
WaitFor WaitFor A wrapper object that holds configuration for wait-for mechanism for users to wait for certain events before rendering. By default, it will wait for nothing.

6. Tabla de opciones de encabezado y pie de página de PDF .NET

Clase

7. Aplicar opciones de impresión PDF (renderizado)

Intentemos configurar nuestras opciones de renderizado de PDF.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-12.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
ChromePdfRenderer renderer = new ChromePdfRenderer();

// Set rendering options
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;

renderer.RenderHtmlFileAsPdf(@"testFile.html").SaveAs("GeneratedFile.pdf");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

8. Aplicaciones .NET Core en Docker

8.1. ¿Qué es Docker?

Docker es un conjunto de productos de plataforma como servicio que utiliza la virtualización a nivel de sistema operativo para ofrecer software en paquetes denominados contenedores. Los contenedores están aislados unos de otros y agrupan su propio software, bibliotecas y archivos de configuración; pueden comunicarse entre sí a través de canales bien definidos.

Puedes aprender más sobre Docker y la aplicación de ASP.NET Core aquí.

Pasaremos a trabajar con Docker, pero si deseas aprender más, hay una excelente introducción a .NET y Docker aquí. y aún más sobre cómo construir contenedores para aplicaciones .NET core.

Empecemos juntos con Docker.

8.2. Instalar Docker

Visite el sitio web de Docker aquí para instalar Docker. 40 related to 8.2. Instalar Docker Haz clic en empezar. 41 related to 8.2. Instalar Docker Haga clic en descargar para Mac y Windows. 42 related to 8.2. Instalar Docker Regístrate gratis e inicia sesión. 43 related to 8.2. Instalar Docker Descargar Docker para Windows. 44 related to 8.2. Instalar Docker Comience a instalar Docker. 45 related to 8.2. Instalar Docker Será necesario reiniciarlo. Después de que su máquina se reinicie, inicie sesión en Docker. 46 related to 8.2. Instalar Docker Ahora puedes ejecutar Docker "hola mundo" abriendo la línea de comandos de Windows o el script PowerShell y escribir:

Docker ejecuta hello-world 47 related to 8.2. Instalar Docker Aquí tienes una lista de las líneas de comandos más importantes para ayudarte:

  • Imágenes Docker => Para listar todas las imágenes disponibles en esta máquina
  • Docker ps => para listar todos los contenedores en ejecución
  • Docker ps -a => para listar todos los contenedores

8.3. Ejecutar en contenedor Linux

38 related to 8.3. Ejecutar en contenedor Linux 39 related to 8.3. Ejecutar en contenedor Linux


9. Trabajar con documentos PDF existentes

9.1. Abrir PDF existente

Como puedes crear un PDF a partir de una URL y HTML (texto o archivo), también puedes trabajar con documentos PDF existentes.

A continuación se muestra un ejemplo para abrir un PDF normal o un PDF cifrado con contraseña

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-13.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
// Open an unencrypted pdf
PdfDocument unencryptedPdf = PdfDocument.FromFile("testFile.pdf");

// Open an encrypted pdf
PdfDocument encryptedPdf = PdfDocument.FromFile("testFile2.pdf", "MyPassword");
IronPdf.License.LicenseKey = "YourLicenseKey"
' Open an unencrypted pdf
Dim unencryptedPdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")

' Open an encrypted pdf
Dim encryptedPdf As PdfDocument = PdfDocument.FromFile("testFile2.pdf", "MyPassword")
$vbLabelText   $csharpLabel

9.2. Fusionar varios PDF

Puedes fusionar varios PDF en uno solo de la siguiente manera:

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-14.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
List<PdfDocument> PDFs = new List<PdfDocument>();
PDFs.Add(PdfDocument.FromFile("1.pdf"));
PDFs.Add(PdfDocument.FromFile("2.pdf"));
PDFs.Add(PdfDocument.FromFile("3.pdf"));
using PdfDocument PDF = PdfDocument.Merge(PDFs);
PDF.SaveAs("mergedFile.pdf");
foreach (PdfDocument pdf in PDFs)
{
    pdf.Dispose();
}
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim PDFs As New List(Of PdfDocument)()
PDFs.Add(PdfDocument.FromFile("1.pdf"))
PDFs.Add(PdfDocument.FromFile("2.pdf"))
PDFs.Add(PdfDocument.FromFile("3.pdf"))
Using PDF As PdfDocument = PdfDocument.Merge(PDFs)
	PDF.SaveAs("mergedFile.pdf")
'INSTANT VB NOTE: The variable pdf was renamed since Visual Basic will not allow local variables with the same name as parameters or other local variables:
	For Each Me.pdf_Conflict As PdfDocument In PDFs
		Me.pdf_Conflict.Dispose()
	Next pdf_Conflict
End Using
$vbLabelText   $csharpLabel

Añada otro PDF al final del PDF actual de la siguiente manera:

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-15.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("1.pdf");
PdfDocument pdf2 = PdfDocument.FromFile("2.pdf");
pdf.AppendPdf(pdf2);
pdf.SaveAs("appendedFile.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("1.pdf")
Dim pdf2 As PdfDocument = PdfDocument.FromFile("2.pdf")
pdf.AppendPdf(pdf2)
pdf.SaveAs("appendedFile.pdf")
$vbLabelText   $csharpLabel

Inserta un PDF en otro PDF empezando por el índice dado:

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-16.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("1.pdf");
PdfDocument pdf2 = PdfDocument.FromFile("2.pdf");
pdf.InsertPdf(pdf2, 0);
pdf.SaveAs("InsertIntoSpecificIndex.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("1.pdf")
Dim pdf2 As PdfDocument = PdfDocument.FromFile("2.pdf")
pdf.InsertPdf(pdf2, 0)
pdf.SaveAs("InsertIntoSpecificIndex.pdf")
$vbLabelText   $csharpLabel

9.3 Añadir encabezados o pies de página

Puede añadir encabezados y pies de página a un PDF existente o cuando renderice el PDF desde HTML o URL.

Hay dos clases que puede utilizar para añadir encabezado o pie de página a un PDF:

  • TextHeaderFooter: añade texto simple en cabecera o pie de página.
  • HtmlHeaderFooter: añadir encabezado o pie de página con contenido HTML enriquecido e imágenes.

    Ahora veamos dos ejemplos de como añadir cabecera/pie a un pdf existente o cuando se renderiza usando estas dos clases.

    9.3.1 Añadir encabezado a un PDF existente

    A continuación, se muestra un ejemplo para cargar un PDF existente, luego agregar un encabezado y pie de página utilizando los métodos AddTextHeaders y AddHtmlFooters.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-17.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("testFile.pdf");
TextHeaderFooter header = new TextHeaderFooter()
{
    CenterText = "Pdf Header",
    LeftText = "{date} {time}",
    RightText = "{page} of {total-pages}",
    DrawDividerLine = true,
    FontSize = 10
};
pdf.AddTextHeaders(header);
pdf.SaveAs("withHeader.pdf");

HtmlHeaderFooter Footer = new HtmlHeaderFooter()
{
    HtmlFragment = "<span style='text-align:right'> page {page} of {totalpages}</span>",
    DrawDividerLine = true,
    MaxHeight = 10 //mm
};
pdf.AddHtmlFooters(Footer);
pdf.SaveAs("withHeaderAndFooters.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")
Dim header As New TextHeaderFooter() With {
	.CenterText = "Pdf Header",
	.LeftText = "{date} {time}",
	.RightText = "{page} of {total-pages}",
	.DrawDividerLine = True,
	.FontSize = 10
}
pdf.AddTextHeaders(header)
pdf.SaveAs("withHeader.pdf")

Dim Footer As New HtmlHeaderFooter() With {
	.HtmlFragment = "<span style='text-align:right'> page {page} of {totalpages}</span>",
	.DrawDividerLine = True,
	.MaxHeight = 10
}
pdf.AddHtmlFooters(Footer)
pdf.SaveAs("withHeaderAndFooters.pdf")
$vbLabelText   $csharpLabel

9.3.2 Añadir encabezado y pie de página a un nuevo PDF

A continuación se muestra un ejemplo para crear un PDF a partir de un archivo HTML y añadirle un encabezado y un pie de página utilizando las opciones de renderizado.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-18.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
    CenterText = "Pdf Header",
    LeftText = "{date} {time}",
    RightText = "{page} of {total-pages}",
    DrawDividerLine = true,
    FontSize = 10
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
    HtmlFragment = "<span style='text-align:right'> page {page} of {totalpages}</span>",
    DrawDividerLine = true,
    MaxHeight = 10
};
PdfDocument pdf = renderer.RenderHtmlFileAsPdf("test.html");
pdf.SaveAs("generatedFile.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
	.CenterText = "Pdf Header",
	.LeftText = "{date} {time}",
	.RightText = "{page} of {total-pages}",
	.DrawDividerLine = True,
	.FontSize = 10
}

renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter() With {
	.HtmlFragment = "<span style='text-align:right'> page {page} of {totalpages}</span>",
	.DrawDividerLine = True,
	.MaxHeight = 10
}
Dim pdf As PdfDocument = renderer.RenderHtmlFileAsPdf("test.html")
pdf.SaveAs("generatedFile.pdf")
$vbLabelText   $csharpLabel

10. Añadir contraseña PDF y seguridad

Puede proteger su PDF con una contraseña y editar la configuración de seguridad del archivo, como impedir la copia y la impresión.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-19.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("testFile.pdf");

// Edit file metadata
pdf.MetaData.Author = "john smith";
pdf.MetaData.Keywords = "SEO, Friendly";
pdf.MetaData.ModifiedDate = DateTime.Now;

// Edit file security settings
// The following code makes a PDF read only and will disallow copy & paste and printing
pdf.SecuritySettings.RemovePasswordsAndEncryption();
pdf.SecuritySettings.MakePdfDocumentReadOnly("secret-key"); //secret-key is a owner password
pdf.SecuritySettings.AllowUserAnnotations = false;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserFormData = false;
pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights;

// Change or set the document ecrpytion password
pdf.Password = "123";
pdf.SaveAs("secured.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")

' Edit file metadata
pdf.MetaData.Author = "john smith"
pdf.MetaData.Keywords = "SEO, Friendly"
pdf.MetaData.ModifiedDate = DateTime.Now

' Edit file security settings
' The following code makes a PDF read only and will disallow copy & paste and printing
pdf.SecuritySettings.RemovePasswordsAndEncryption()
pdf.SecuritySettings.MakePdfDocumentReadOnly("secret-key") 'secret-key is a owner password
pdf.SecuritySettings.AllowUserAnnotations = False
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserFormData = False
pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.FullPrintRights

' Change or set the document ecrpytion password
pdf.Password = "123"
pdf.SaveAs("secured.pdf")
$vbLabelText   $csharpLabel

11. Firmar PDF digitalmente

También puedes firmar digitalmente un PDF de la siguiente manera:

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-20.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("testFile.pdf");
pdf.Sign(new PdfSignature("cert123.pfx", "password"));
pdf.SaveAs("signed.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")
pdf.Sign(New PdfSignature("cert123.pfx", "password"))
pdf.SaveAs("signed.pdf")
$vbLabelText   $csharpLabel

Ejemplo avanzado para un mayor control:

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-21.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("testFile.pdf");
IronPdf.Signing.PdfSignature signature = new IronPdf.Signing.PdfSignature("cert123.pfx", "123");

// Optional signing options
signature.SigningContact = "support@ironsoftware.com";
signature.SigningLocation = "Chicago, USA";
signature.SigningReason = "To show how to sign a PDF";

// Sign the PDF with the PdfSignature. Multiple signing certificates may be used
pdf.Sign(signature);
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")
Dim signature As New IronPdf.Signing.PdfSignature("cert123.pfx", "123")

' Optional signing options
signature.SigningContact = "support@ironsoftware.com"
signature.SigningLocation = "Chicago, USA"
signature.SigningReason = "To show how to sign a PDF"

' Sign the PDF with the PdfSignature. Multiple signing certificates may be used
pdf.Sign(signature)
$vbLabelText   $csharpLabel

12. Extraer texto e imágenes de PDF

Extraer texto e imágenes Con IronPdf puede extraer texto e imágenes de un PDF de la siguiente manera:

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-22.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("testFile.pdf");

pdf.ExtractAllText(); // Extract all text in the pdf
pdf.ExtractTextFromPage(0); // Read text from specific page

// Extract all images in the pdf
var AllImages = pdf.ExtractAllImages();

// Extract images from specific page
var ImagesOfAPage = pdf.ExtractImagesFromPage(0);
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")

pdf.ExtractAllText() ' Extract all text in the pdf
pdf.ExtractTextFromPage(0) ' Read text from specific page

' Extract all images in the pdf
Dim AllImages = pdf.ExtractAllImages()

' Extract images from specific page
Dim ImagesOfAPage = pdf.ExtractImagesFromPage(0)
$vbLabelText   $csharpLabel

12.1. Rasterizar PDF a imagen

También puedes convertir páginas PDF en imágenes de la siguiente manera

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-23.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
PdfDocument pdf = PdfDocument.FromFile("testFile.pdf");

List<int> pageList = new List<int>() { 1, 2 };

pdf.RasterizeToImageFiles("*.png", pageList);
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim pdf As PdfDocument = PdfDocument.FromFile("testFile.pdf")

Dim pageList As New List(Of Integer)() From {1, 2}

pdf.RasterizeToImageFiles("*.png", pageList)
$vbLabelText   $csharpLabel

13. Añadir marca de agua PDF

El siguiente es un ejemplo de cómo incluir marcas de agua en las páginas PDF.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-24.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderUrlAsPdf("https://www.nuget.org/packages/IronPdf");

// Apply watermark
pdf.ApplyWatermark("<h2 style='color:red'>SAMPLE</h2>", 30, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center);
pdf.SaveAs("Watermarked.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderUrlAsPdf("https://www.nuget.org/packages/IronPdf")

' Apply watermark
pdf.ApplyWatermark("<h2 style='color:red'>SAMPLE</h2>", 30, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center)
pdf.SaveAs("Watermarked.pdf")
$vbLabelText   $csharpLabel

La marca de agua tiene un conjunto restringido de opciones y funciones. Para mayor control, puedes utilizar la clase HTMLStamper.

:path=/static-assets/pdf/content-code-examples/tutorials/dotnet-core-pdf-generating-25.cs
IronPdf.License.LicenseKey = "YourLicenseKey";
ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<div>test text </div>");

// Configure HTML stamper
HtmlStamper backgroundStamp = new HtmlStamper()
{
    Html = "<h2 style='color:red'>copyright 2018 ironpdf.com",
    MaxWidth = new Length(20),
    MaxHeight = new Length(20),
    Opacity = 50,
    Rotation = -45,
    IsStampBehindContent = true,
    VerticalAlignment = VerticalAlignment.Middle
};

pdf.ApplyStamp(backgroundStamp);
pdf.SaveAs("stamped.pdf");
IronPdf.License.LicenseKey = "YourLicenseKey"
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<div>test text </div>")

' Configure HTML stamper
Dim backgroundStamp As New HtmlStamper() With {
	.Html = "<h2 style='color:red'>copyright 2018 ironpdf.com",
	.MaxWidth = New Length(20),
	.MaxHeight = New Length(20),
	.Opacity = 50,
	.Rotation = -45,
	.IsStampBehindContent = True,
	.VerticalAlignment = VerticalAlignment.Middle
}

pdf.ApplyStamp(backgroundStamp)
pdf.SaveAs("stamped.pdf")
$vbLabelText   $csharpLabel

Acceso rápido a tutoriales

Brand Visual Studio related to Acceso rápido a tutoriales

Obtener el código fuente

Accede a todo el código fuente encontrado en este tutorial como un archivo ZIP de proyecto de Visual Studio, fácil de usar y compartir para tu proyecto.

Obtener el código

Acceso al tutorial de GitHub

Explore este tutorial y muchos más a través de GitHub. Utilizar los proyectos y el código fuente es la mejor manera de aprender y aplicarlo a tus propias necesidades y casos de uso de PDF .NET Core.

Generar PDFs en .NET Core Tutorial
Github Icon related to Acceso rápido a tutoriales
Html To Pdf Icon related to Acceso rápido a tutoriales

Conserve el PDF CSharp Cheat Sheet

Desarrolle PDF en sus aplicaciones .NET usando nuestro práctico documento de referencia. Proporcionando acceso rápido a funciones comunes y ejemplos para generar y editar PDF en C# y VB.NET, esta herramienta compartible le ayuda a ahorrar tiempo y esfuerzo al comenzar con IronPDF y los requisitos comunes de PDF en su proyecto.

Guarda la Hoja de Trucos

Más documentación

Lea la Referencia de la API de IronPDF, que presenta exhaustivamente los detalles de todas las características de IronPDF, además de los espacios de nombres, clases, métodos, campos y enums.

Documentación de Referencia de la API
Documentation related to Acceso rápido a tutoriales
Chaknith Bin
Ingeniero de software
Chaknith trabaja en IronXL e IronBarcode. Tiene una gran experiencia en C# y .NET, ayudando a mejorar el software y a apoyar a los clientes. Sus conocimientos de las interacciones con los usuarios contribuyen a mejorar los productos, la documentación y la experiencia general.