IRONSOFTWAREHOME
使用IRONPDF

在Dotnet Core中生成PDF文件:图1 - HTML到PDF输出PDF文件

Curtis Chau
Curtis Chau
Updated: 2026年9月4日

在 ASP.NET Core 中动态生成专业的 PDF 文档,方法是将 HTML 内容转换为精美的 PDF,并将其直接流式传输到浏览器——无需磁盘存储,无需管理临时文件。

在 ASP.NET Core 中构建现代 Web 应用程序时,按需生成PDF 文档的功能是一个反复出现的需求。 发票需要在付款到账后立即下载。 审计员点击"导出"后,合规性报告必须立即显示。证书应该在用户来得及怀疑是否出了问题之前就准备就绪。 IronPDF通过其基于 Chromium 的PDF 库处理所有这些场景,该库将 HTML(包括 CSS、JavaScript 和 Web 字体)转换为像素精确的 PDF 输出,而无需将任何内容写入磁盘。

本指南涵盖您需要了解的一切:安装库、从 HTML 字符串生成发票、从 Entity Framework 数据流式传输报告、应用页面标头和安全设置,以及采用最佳实践来保持高流量 ASP.NET 应用程序的良好性能。

即时创建 PDF 是什么意思?

"即时生成"是指在发出 HTTP 请求时,文档在内存中构建并直接发送给调用者。 不会向文件系统写入 PDF 文件,不会在后台作业中排队处理工作,也不会在请求之间缓存结果。

这种方法之所以重要,原因有以下几点。 首先,云部署目标(Azure 应用服务、AWS Lambda、Docker 容器)通常运行在本地文件系统是临时的或只读的环境中。 在这些环境下,将 PDF 文件生成到临时文件夹然后再读取回来是不安全的。 其次,避免磁盘写入可以减少攻击面:不会留下残留文件,后续请求可能会意外地将文件提供给错误的用户。 第三,仅内存生成通常速度更快,因为它消除了关键路径中的两次 I/O 操作(写入和读取)。

IronPDF的ChromePdfRenderer在每个生成的文档上公开.Stream属性。 两者都可以直接传递给ASP.NET Core FileResult,使流媒体在实践中成为一行代码。

第一步:
arrow pointer

如何在 ASP.NET Core 项目中安装 IronPDF?

可以通过程序包管理器控制台或 .NET CLI 添加 NuGet 程序包:

PM > Install-Package IronPdf

安装包后,在应用程序启动时设置您的许可证密钥 -- 通常是在创建第一个渲染器之前的Program.cs中:

using IronPdf;

// Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY";

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();

// Register ChromePdfRenderer as a singleton so the Chromium engine
// is initialised once and reused across all requests.
builder.Services.AddSingleton<ChromePdfRenderer>();

var app = builder.Build();
app.MapDefaultControllerRoute();
app.Run();

ChromePdfRenderer注册为单例很重要。 渲染器首次使用时会启动一个内部 Chromium 子进程。 如果每次请求都创建一个新实例,则每次调用都需要支付启动成本,这会在负载下增加数百毫秒的延迟。 单例实例是线程安全的,无需额外配置即可处理并发渲染请求。

要更全面地了解安装选项(包括私有源的 NuGet.config 设置),请访问安装概述

如何根据 HTML 字符串生成发票 PDF?

最常见的即时使用场景是生成交易文档——发票、收据、订单确认——其中内容会根据请求而变化,但布局保持不变。

模式是:构建一个带有插值数据的HTML字符串,将其传递给RenderHtmlAsPdf,并将二进制结果作为文件下载返回。

using IronPdf;
using Microsoft.AspNetCore.Mvc;

public class DocumentController : Controller
{
    private readonly ChromePdfRenderer _renderer;

    public DocumentController(ChromePdfRenderer renderer)
    {
        _renderer = renderer;
    }

    [HttpGet("invoice/{orderId:int}")]
    public IActionResult GetInvoice(int orderId)
    {
        // In a real application, fetch this from your database or order service.
        var order = GetOrderData(orderId);

        string html = $"""
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="utf-8">
                <style>
                    body  {{font-family: Arial, sans-serif; margin: 40px; color: #333;}}
                    h1   {{color: #1a56db;}}
                    table {{width: 100%; border-collapse: collapse; margin-top: 24px;}}
                    th, td {{padding: 10px 14px; border: 1px solid #d1d5db; text-align: left;}}
                    th   {{background: #f3f4f6;}}
                    tfoot td {{font-weight: bold;}}
                </style>
            </head>
            <body>
                <h1>Invoice #{order.InvoiceNumber}</h1>
                <p>Date: {DateTime.UtcNow:yyyy-MM-dd} &nbsp;|&nbsp; Customer: {order.CustomerName}</p>
                <table>
                    <thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
                    <tbody>
                        {string.Join("", order.Items.Select(i =>
                            $"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
                            $"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
                    </tbody>
                    <tfoot>
                        <tr><td colspan="3">Total</td><td>${order.Items.Sum(i => i.Quantity * i.UnitPrice):F2}</td></tr>
                    </tfoot>
                </table>
            </body>
            </html>
            """;

        var pdf = _renderer.RenderHtmlAsPdf(html);
        return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
    }
}
C#

RenderHtmlAsPdf处理完整的HTML文档 -- CSS网格、Flexbox、网页字体,甚至内联SVG -- 使用与Google Chrome相同的Chromium引擎。 返回的MemoryStream)。 将"application/pdf"和一个文件名一起触发浏览器下载。

对于需要像素级精确度的布局,请参阅HTML 到 PDF 渲染指南,其中涵盖响应式 CSS、自定义字体和JavaScript 渲染

生成的发票 PDF 文件长什么样?

Professional PDF invoice showing Invoice #123 dated 2025-11-13 with a styled header section, organized table containing Product A ($10.99) and Product B ($5.49), demonstrating dynamic PDF generation capabilities with custom CSS styling

如何在不弹出下载对话框的情况下将 PDF 文件直接流式传输到浏览器?

内嵌服务PDF -- 在浏览器的内置查看器中打开而不是下载 -- 需要两处小改动:将File()调用中的文件名。

[HttpPost("report/preview")]
public async Task<IActionResult> PreviewReport([FromBody] ReportRequest request)
{
    string html = BuildReportHtml(request);

    var pdfDocument = await _renderer.RenderHtmlAsPdfAsync(html);

    // "inline" tells the browser to display rather than download.
    Response.Headers["Content-Disposition"] = "inline; filename=report.pdf";

    return new FileContentResult(pdfDocument.BinaryData, "application/pdf");
}

由于它在Chromium渲染时释放线程池线程,因此对于ASP.NET Core控制器,建议使用异步重载RenderHtmlAsPdfAsync,从而在并发负载下保持服务器响应。

基于内存的PDF生成是如何工作的?

生成的PDF报告显示

pdfDocument.BinaryData字节数组完全存在于托管内存中。 不涉及中间文件路径。 Content-Disposition控制PDF是内嵌显示还是提供下载 -- 由HTTP规范定义的浏览器行为。 要深入了解 MemoryStream 方法,包括流式传输到 Azure Blob 存储,请访问PDF 内存流文档

如何从 Entity Framework Core 查询结果生成 PDF?

大多数业务应用程序都从数据库中提取报表数据,而不是在调用时构建报表。以下模式查询Entity Framework Core ,构建 HTML 表格,并返回 PDF 文件——所有操作都在单个控制器操作中完成。

[HttpGet("report/monthly")]
public async Task<IActionResult> MonthlyReport(int year, int month)
{
    // Pull aggregated transaction data from EF Core.
    var rows = await _dbContext.Transactions
        .Where(t => t.Date.Year == year && t.Date.Month == month)
        .GroupBy(t => t.Category)
        .Select(g => new { Category = g.Key, Count = g.Count(), Total = g.Sum(t => t.Amount) })
        .OrderByDescending(g => g.Total)
        .ToListAsync();

    string tableRows = string.Join("", rows.Select(r =>
        $"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"));

    string html = $"""
        <html><body style="font-family:Arial,sans-serif;padding:32px">
        <h1>Monthly Report -- {month:D2}/{year}</h1>
        <table style="width:100%;border-collapse:collapse">
          <thead>
            <tr style="background:#e5e7eb">
              <th style="padding:8px;border:1px solid #d1d5db">Category</th>
              <th style="padding:8px;border:1px solid #d1d5db">Transactions</th>
              <th style="padding:8px;border:1px solid #d1d5db">Total</th>
            </tr>
          </thead>
          <tbody>{tableRows}</tbody>
        </table>
        </body></html>
        """;

    var pdf = _renderer.RenderHtmlAsPdf(html);
    pdf.MetaData.Title  = $"Monthly Report {month:D2}/{year}";
    pdf.MetaData.Author = "Reporting System";

    return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf");
}

设置pdf.MetaData.Author将该信息嵌入到PDF的文档属性中,这对于合规性跟踪和文档管理系统很有用。 对于更复杂的报告布局,请考虑使用CSS 打印样式显式分页符嵌入式图表图像

如何为生成的 PDF 文件添加页眉、页脚和安全设置?

生产文档通常需要包含文档标题的页眉、页码页脚以及防止未经授权的打印或复制的访问控制。 IronPDF的ChromePdfRenderOptions涵盖了所有这些要求。

[HttpPost("document/secured")]
public async Task<IActionResult> GenerateSecuredDocument([FromBody] SecuredDocRequest request)
{
    var renderOptions = new ChromePdfRenderOptions
    {
        纸张尺寸       = Pdf纸张尺寸.A4,
        MarginTop       = 45,
        MarginBottom    = 45,
        MarginLeft      = 25,
        MarginRight     = 25,
        启用 JavaScript = true,
        WaitFor         = new WaitFor { RenderDelay = 500 }
    };

    renderOptions.TextHeader = new 文本页眉页脚
    {
        CenterText       = request.DocumentTitle,
        DrawDividerLine  = true,
        FontSize         = 11
    };

    renderOptions.TextFooter = new 文本页眉页脚
    {
        LeftText  = "{date} {time}",
        RightText = "Page {page} of {total-pages}",
        FontSize  = 9
    };

    _renderer.RenderingOptions = renderOptions;

    var pdf = await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent);

    if (request.RequirePassword)
    {
        pdf.SecuritySettings.OwnerPassword         = request.OwnerPassword;
        pdf.SecuritySettings.UserPassword          = request.UserPassword;
        pdf.SecuritySettings.AllowUserPrinting     = PdfPrintSecurity.NoPrint;
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    }

    return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf");
}

当您的HTML包含如Chart.js或ApexCharts等异步完成绘制的图表库时,WaitFor.RenderDelay设置特别有用。 设置 300-500 毫秒的延迟可确保 Chromium 捕获最终渲染状态。 对于需要符合归档标准的文档,将上述方法与PDF/A 合规性数字签名相结合。

页脚文本中的{total-pages}标记在渲染时由IronPDF自动解析。额外的页眉和页脚选项包括用于徽标放置的基于HTML的页眉和每节覆盖能力。

有哪些渲染选项?

下表总结了动态生成中最有用的ChromePdfRenderOptions属性:

常用的 ChromePdfRenderOptions 属性
属性翻译类型翻译目的
纸张尺寸Pdf纸张尺寸设置页面尺寸(A4、Letter、Legal、自定义)
上边距/下边距整数(毫米)控制打印区域间距
启用 JavaScriptbool允许在捕获之前执行 JS 操作
WaitFor.RenderDelay整数(毫秒)延迟捕获以进行异步渲染
文本页眉/文本页脚文本页眉页脚页面页眉和页脚
HTML页眉/HTML页脚HtmlHeaderFooter带有图片的 HTML 格式页眉/页脚
灰度bool输出单色 PDF
适应纸张宽度bool将宽内容缩放以适应页面

高容量 PDF 生成的最佳性能实践是什么?

当单个服务器处理数百个并发 PDF 请求时,一些架构决策会对吞吐量和延迟产生巨大的影响。

单例渲染器注册。 如安装部分所示,在DI容器中将ChromePdfRenderer注册为单例可以避免每次请求启动新的Chromium子进程的成本。根据微软ASP.NET Core性能指导,最具影响力的优化是最小化对象分配和重复利用昂贵资源。

始终使用异步。 Task<PdfDocument>并在Chromium工作时挂起控制器线程。 这样可以释放线程池,使其能够并行处理其他传入的请求,这也是异步文档建议 Web 主机使用此重载的原因。 同步重载仅适用于可以接受线程阻塞的控制台工具或后台服务。

直接流式传输,尽可能跳过中间数组。 对于大型PDF,.Stream可以直接写入响应主体,而不需要实现完整的字节数组:

[HttpGet("document/large")]
public IActionResult StreamLargeDocument(int documentId)
{
    string html = BuildLargeDocumentHtml(documentId);
    var pdf = _renderer.RenderHtmlAsPdf(html);

    // Stream.Position is already at 0; no seek needed.
    return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf");
}

使用后处理。 IDisposable。 将其包裹在using语句中可以及时释放底层内存缓冲区,这在连续生成多个大型PDF时很重要:

using var pdf = _renderer.RenderHtmlAsPdf(html);
byte[] data = pdf.BinaryData;
// pdf is disposed here; data is safely copied to the local array.
return File(data, "application/pdf", "output.pdf");

IronPDF 文档针对Azure 、AWS、Docker 和 Linux 环境提供了云部署指导,并提供了特定于环境的配置说明。 如果启动后的首次渲染很慢,请咨询 热身和缓存指南 以了解在首次用户请求到达之前预先初始化渲染器的策略。

如何在生成的PDF文件中添加水印?

在流式传输之前,可以在生成的文档的每一页上添加文本或图像水印:

[HttpGet("document/draft/{id:int}")]
public IActionResult GetDraftDocument(int id)
{
    string html = BuildDocumentHtml(id);
    var pdf = _renderer.RenderHtmlAsPdf(html);

    // Stamp "DRAFT" diagonally across every page.
    pdf.ApplyWatermark(
        "<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
        rotation: 45,
        opacity: 30
    );

    return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf");
}

有关完整的水印配置选项(包括图像水印和每页控制),请参阅水印文档

NuGet使用 NuGet 安装

PM > Install-Package IronPdf

Install IronPDF by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.

下一步计划是什么?

ASP.NET Core中的动态PDF生成遵循一致的模式:构建您的HTML,调用FileResult返回结果。 IronPDF 可以处理中间的所有步骤——Chromium 渲染、CSS 应用、JavaScript 执行——而无需在任何阶段进行磁盘 I/O。

从这里出发,您可以根据自己的应用需求探索多个方向。 如果您的 PDF 需要合并多个源文档,合并和拆分指南涵盖了如何将现有 PDF 与新渲染的页面连接起来。 如果您需要用户填写并提交嵌入在 PDF 中的表单,交互式表单文档将展示如何创建和读取字段值。 对于受监管的行业, PDF/A 合规性PDF/UA 可访问性可确保文档符合存档和可访问性标准。

如果您正在评估 IronPDF 与其他替代方案, iText 与 IronPDF 的比较提供了并排的技术分析。 准备好投入生产时,请购买许可证以解锁所有功能并获得优先工程支持。 完整的API 参考文档包含了本指南中讨论的每个类和方法。

如果在实施过程中遇到任何问题,工程支持团队随时为您提供帮助。关于Blazor Server或 MAUI 等平台的具体说明,我们提供了专门的指南,其中涵盖了每种主机型号的配置差异。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

...
阅读更多

相关文章

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

OR
bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge

深受全球数百万工程师信赖

Iron Software 的客户徽标
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户
C# 用于 PDF 的 NuGet 库
通过 NuGet 安装

版本: 2026.9

PM > Install-Package IronPdf
nuget.org/packages/IronPdf/
  1. 在解决方案资源管理器中,右键点击引用,管理 NuGet 包
  2. 选择浏览并搜索 “IronPDF”
  3. 选择包并安装
C# PDF DLL
下载 DLL

版本: 2026.9

或在此处下载 Windows 安装程序。

  1. 下载并解压 IronPDF 到您的解决方案目录中的 ~/Libs 之类的位置
  2. 在 Visual Studio 解决方案资源管理器中,右键点击引用。选择浏览,“IronPDF.dll”

$999