Passer au contenu du pied de page
UTILISATION DE IRONPDF

Imprimer un formulaire en PDF en C# -- Guide complet pour les développeurs

Le problème avec les modèles PDF parallèles

Page d'accueil IronPDF Les vues Razor sont déjà construites. La page de détails de la facture rend les articles, calcule les totaux et applique la feuille de style de l'entreprise. La page de statut du projet montre les décompositions de tâches avec des sections conditionnelles qui n'apparaissent que lorsque des jalons sont en retard. La vue de la fiche de paie formate les gains, les déductions et les chiffres YTD dans un tableau que l'équipe RH a mis deux semaines à peaufiner. Tout ce travail est fait, puis un intervenant demande un bouton " Télécharger en PDF ".

La réponse standard est de construire un deuxième modèle : une chaîne HTML ou une définition de rapport qui reproduit la même mise en page pour le chemin PDF. Ce deuxième modèle commence comme une copie du premier, puis commence immédiatement à diverger. Le designer UI met à jour le style du tableau de la vue de facturation dans le Sprint 14. Personne ne met à jour le modèle PDF jusqu'à ce qu'un utilisateur signale que la facture téléchargée est différente de celle à l'écran. Il y a maintenant deux sources de vérité, et l'une d'elles est toujours légèrement erronée.

Les bibliothèques PDF JavaScript côté client évitent la duplication mais perdent les données rendues côté serveur, les données authentifiées, les totaux calculés côté serveur, et les sections conditionnelles conduites par le ViewModel ne survivent pas au transfert vers un moteur de rendu côté navigateur. L'automatisation de navigateur sans interface utilisateur depuis le serveur est fragile, ajoute des surcharges d'infrastructure et échoue de manière imprévisible dans des environnements containerisés. La fonctionnalité d'impression-to-PDF par le navigateur fonctionne pour un utilisateur imprimant manuellement ; ce n'est pas un bouton " Télécharger PDF " dans une application de production.

Les scénarios réels font surface le vrai coût : un administrateur e-commerce téléchargeant une page de détails de commande pour l'exécution, un client exportant une page de statut de projet depuis un outil de gestion de projet, un employé téléchargeant son bulletin de paie, un répartiteur imprimant un résumé d'itinéraire. Tous s'attendent à ce que le PDF ressemble exactement à ce qu'ils voient à l'écran.

La solution : Rendre la vue existante, pas une copie de celle-ci

IronPDF permet aux applications ASP.NET Core de rendre une vue Razor existante — la même qui sert le navigateur — directement en PDF. L'action du contrôleur PDF rend la vue Razor en une chaîne HTML en utilisant le moteur de vue standard, passe cette chaîne à ChromePdfRenderer.RenderHtmlAsPdf(), et renvoie le résultat en tant que téléchargement de fichier.

Une vue, deux sorties. Quand la vue Razor change, la sortie PDF change avec elle, automatiquement, sans coordination requise. Il n'y a pas de modèles parallèles à maintenir, pas de solutions de contournement côté client à déboguer, et pas de processus de navigateur sans tête à maintenir en vie. Le rendu s'exécute dans l'application .NET existante comme un seul package NuGet.

Comment ça marche en pratique

1. La vue existe déjà : l'action PDF est la nouveauté

Une page de détails de facture sur /invoices/{id} rend le même modèle de données que ce soit pour servir un navigateur ou produire un PDF. Le modèle inclut les éléments de ligne, les totaux, les détails du client et l'image de marque de l'entreprise, toutes les données dont la vue a besoin. Le InvoicesController existant a une action Details qui remplit ce modèle. L'action PDF est son homologue, pas un remplacement.

Quand l'utilisateur clique sur " Télécharger PDF ", la requête atteint /invoices/{id}/pdf. L'action PDF récupère le même ViewModel en utilisant le même appel de service, le modèle est identique. Ce qui diffère, c'est ce qui se passe ensuite.

2. Vue Razor rendue en chaîne HTML

Plutôt que de retourner un ViewResult, l'action PDF utilise un service de rendu de vue pour invoquer le moteur Razor contre le fichier de vue et le ViewModel, capturant le résultat sous forme de chaîne. C'est un schéma courant dans ASP.NET Core, un IViewRenderService injecté dans le contrôleur qui appelle ICompositeViewEngine, exécute la vue dans un faux ActionContext, et renvoie le HTML rendu.

La chaîne HTML rendue est complète : toutes les données sont remplies, toutes les sections conditionnelles sont résolues, tous les noms de classes CSS sont présents. C'est le même HTML que le navigateur recevrait, capturé côté serveur.

3. ChromePdfRenderer convertit la chaîne HTML en PDF

using IronPdf;

[HttpGet("{id}/pdf")]
public async Task<IActionResult> DownloadInvoicePdf(int id)
{
    var model = await _invoiceService.GetInvoiceViewModelAsync(id);

    // Render the existing Razor view to an HTML string
    string html = await _viewRenderer.RenderToStringAsync("Invoices/Details", model);

    var renderer = new ChromePdfRenderer();

    renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
    renderer.RenderingOptions.MarginTop = 15;
    renderer.RenderingOptions.MarginBottom = 15;

    PdfDocument pdf = renderer.RenderHtmlAsPdf(html);

    return File(pdf.BinaryData, "application/pdf"
        $"Invoice-{model.InvoiceNumber}.pdf");
}
using IronPdf;

[HttpGet("{id}/pdf")]
public async Task<IActionResult> DownloadInvoicePdf(int id)
{
    var model = await _invoiceService.GetInvoiceViewModelAsync(id);

    // Render the existing Razor view to an HTML string
    string html = await _viewRenderer.RenderToStringAsync("Invoices/Details", model);

    var renderer = new ChromePdfRenderer();

    renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
    renderer.RenderingOptions.MarginTop = 15;
    renderer.RenderingOptions.MarginBottom = 15;

    PdfDocument pdf = renderer.RenderHtmlAsPdf(html);

    return File(pdf.BinaryData, "application/pdf"
        $"Invoice-{model.InvoiceNumber}.pdf");
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc

<HttpGet("{id}/pdf")>
Public Async Function DownloadInvoicePdf(id As Integer) As Task(Of IActionResult)
    Dim model = Await _invoiceService.GetInvoiceViewModelAsync(id)

    ' Render the existing Razor view to an HTML string
    Dim html As String = Await _viewRenderer.RenderToStringAsync("Invoices/Details", model)

    Dim renderer As New ChromePdfRenderer()

    renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
    renderer.RenderingOptions.MarginTop = 15
    renderer.RenderingOptions.MarginBottom = 15

    Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)

    Return File(pdf.BinaryData, "application/pdf", $"Invoice-{model.InvoiceNumber}.pdf")
End Function
$vbLabelText   $csharpLabel

Document PDF généré

Exemple de sortie PDF IronPDF CssMediaType.Print applique toutes les règles @media print déjà présentes dans la feuille de style de la vue : cacher la barre de navigation, supprimer les boutons d'action, et appliquer un espacement spécifique à l'impression, sans nécessiter de modifications à la vue Razor elle-même.

ConseilsSi la vue Razor référence des feuilles de style ou des images via des chemins relatifs, définissez un BaseUrlPath comme deuxième paramètre de RenderHtmlAsPdf() afin qu'IronPDF résolve correctement ces ressources lors du rendu. Sans cela, les références CSS et image qui fonctionnent dans un contexte de navigateur échoueront à se charger dans le moteur de rendu côté serveur.

4. Ajuster finement la sortie PDF sans toucher la vue

Les ajustements spécifiques au PDF tels que les numéros de page, les marges personnalisées, les en-têtes avec le titre du document, sont configurés sur le moteur de rendu, pas dans la vue Razor. Cela garde la logique d'impression hors du modèle :

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='font-size:9px; color:#888; text-align:center; width:100%;'>
            Invoice — Page {page} of {total-pages}
        </div>",
    DrawDividerLine = true
};

PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='font-size:9px; color:#888; text-align:center; width:100%;'>
            Invoice — Page {page} of {total-pages}
        </div>",
    DrawDividerLine = true
};

PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
Imports IronPdf

Dim renderer As New ChromePdfRenderer()

renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "
        <div style='font-size:9px; color:#888; text-align:center; width:100%;'>
            Invoice — Page {page} of {total-pages}
        </div>",
    .DrawDividerLine = True
}

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

Fichier PDF de sortie

Fichier PDF avec réglages de sortie personnalisés La vue Razor n'a jamais besoin de savoir si elle se rend à un navigateur ou à un PDF. L'action du contrôleur possède la configuration spécifique au PDF, et la vue reste un modèle d'affichage pur.

Avis Réels

Duplication de modèle nulle. La vue Razor est la source unique de vérité pour la mise en page et le contenu du document. Le navigateur et le PDF se rendent à partir du même fichier, il n'y a pas de second modèle à maintenir et pas de dérive à corriger.

Adoption instantanée. Si la vue existe déjà, l'export PDF est à une action du contrôleur. Il n'y a pas de réaménagement des mises en page, de reconstruction des modèles, ou de portage de logique conditionnelle vers un autre système de rendu.

Sortie précise au pixel près. Le rendu basé sur Chromium signifie que la grille CSS, flexbox, les polices web, et les requêtes médias fonctionnent toutes dans le PDF. La sortie correspond à ce que produit le navigateur, pas une approximation dégradée.

Stylisation spécifique à l'impression. Les règles @media print déjà dans la feuille de style de la vue contrôlent ce qui apparaît dans le PDF : masquer la navigation, ajuster la largeur des colonnes pour le papier, ou réorganiser le contenu. Pas de modèle séparé, pas de styles d'impression en ligne à gérer séparément.

Facilité de maintenance. Mettez à jour la vue Razor et à la fois la sortie navigateur et la sortie PDF reflètent le changement. Il n'y a pas de second système à coordonner pour les mises à jour, pas de risque qu'un changement de designer atteigne le navigateur mais pas le PDF.

Pas de coût par document. Le rendu s'exécute dans le processus au sein de l'application web. Il n'y a pas d'appels API externes, pas de mesure d'utilisation, et pas de modèle de coût qui évolue en fonction du volume de téléchargement.

Conclusion

Si la vue Razor est déjà construite, l'export PDF n'est pas une nouvelle fonctionnalité, c'est un nouveau chemin de livraison pour le travail existant. Le même modèle, la même vue, le même style : la seule addition est une action du contrôleur qui capture la sortie HTML de la vue et la passe dans un moteur de rendu avant de la renvoyer comme fichier.

Cette architecture garde la base de code propre et la sortie PDF en permanence synchronisée avec le navigateur. IronPDF gère le cycle de vie complet de la génération de PDF en C# sur ironpdf.com, depuis le rendu HTML jusqu'à la sauvegarde, le streaming, et la manipulation de documents. Si vous êtes prêt à ajouter l'export PDF à vos vues Razor existantes, commencez votre essai gratuit de 30 jours et validez la sortie par rapport à votre rendu navigateur actuel avant de déployer la fonctionnalité.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite

Équipe de soutien Iron

Nous sommes en ligne 24 heures sur 24, 5 jours sur 7.
Chat
Email
Appelez-moi