IRONSOFTWAREHOME
使用IRONPDF

html2pdf页面断裂在C#中已修复(开发者教程)

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

在使用现代应用程序时,像您这样的.NET开发人员可能会发现需要构建一个集中的PDF生成服务。无论您是生成发票、报告、证书或合同,拥有一个专门的.NET PDF API对于高效管理PDF文件都是有益的。 那么它如何改善您的PDF生成任务呢? 它通过在桌面和Web应用程序之间提供一致性、可维护性和可扩展性来实现这一点。 从未有过如此轻松地管理文档内容、PDF页面和PDF表单字段。

在本教程中,您将学习如何使用ASP.NET Core和IronPDF,一个强大的.NET PDF库,构建一个可用于生产的PDF API。 我们将创建可以从HTML生成PDF、合并文档、添加水印并处理Web API中各种实际PDF生成场景的RESTful端点。

为什么构建一个专门的PDF API?

在深入研究代码之前,让我们了解为什么创建一个专门的PDF API是有意义的:

  • **集中化逻辑:**所有 PDF 生成逻辑集中于一处,便于维护和更新
  • **微服务架构:**非常适合面向服务的架构,其中不同应用程序需要 PDF 功能
  • 性能优化:更容易为大型PDF文件、多页面和动态数据优化和扩展专用服务。
  • **语言无关:**无论使用何种编程语言,任何客户端应用程序均可调用该 API
  • 输出一致性:确保整个组织的所有PDF文档都保持一致的文档布局、段落格式和PDF内容。

准备好开始构建了吗? 下载IronPDF的免费试用版,并按此教程一起编程实现.NET Framework项目中的PDF文件创建。

IronPDF: 完整的.NET PDF库

IronPDF被认为是.NET开发人员的首选PDF库,提供了一套全面的功能,使Web API项目中的PDF生成过程简单可靠。 它建立在Chrome渲染引擎上,确保像素级精准的HTML到PDF转换,通常只需几行代码即可完成。 这在保持所有样式、JavaScript执行和响应布局的同时完成。

使IronPDF成为.NET PDF API开发的理想选择的关键能力有:

  • **基于 Chrome 的渲染:**利用 Google Chrome 的渲染引擎,将 PDF 文档从 HTML 内容中准确转换,并完全支持嵌入的图像和其他 Web 资源
  • **丰富的功能集:**支持对新文档和现有文档进行编辑,包括数字签名、PDF 表单、批注、加密、压缩等功能
  • 创建安全的PDF文档: 使用加密、数字签名和文档保护来管理敏感的PDF内容。
  • **多种输入格式:**支持使用 HTML、URL、图片Office 文档创建 PDF 文档
  • **高级操作:**合并PDF页面、拆分文档、应用水印、创建互动PDF表单,并以编程方式操作PDF文件。
  • **跨平台支持:**可在 Windows、Linux、macOS、Docker 及云平台上运行
  • 性能优化:异步操作、高效的内存管理以及快速的渲染

如何设置您的PDF文档API项目?

让我们从创建一个新的ASP.NET Core Web API项目并安装必要的包开始。

前提条件

  • .NET 6.0 SDK或更高版本
  • Visual Studio 2022或Visual Studio Code
  • Postman或类似的API测试工具,以测试您的PDF REST API

创建项目

首先,让我们创建一个项目,我们将在其中构建我们的PDF生成工具。

dotnet new webapi -n PdfApiService
cd PdfApiService
Text

安装 IronPDF

下一步是通过NuGet将IronPDF添加到您的项目中:

dotnet add package IronPdf
Text

或者,在Visual Studio中使用NuGet包管理器控制台:

PM > Install-Package IronPdf

项目结构

C#开发的一个重要方面是保持一个干净且结构良好的项目文件夹。 例如:

如何创建您的第一个PDF端点?

让我们构建一个简单的端点,将HTML转换为PDF格式。 首先,创建服务接口和实现:

创建PDF服务

首先,我们将在我们的IPdfService.cs文件中添加以下内容:

public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}

在PdfService.cs文件中,我们将添加:

using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}

PdfService处理将HTML转换为PDF的核心过程。 利用IronPDF的ChromePdfRenderer,此类设置了合理的默认值,如页面边距和背景渲染,以生成一个精美的最终文档。

当控制器传递原始HTML时,服务使用IronPDF将其呈现为专业质量的PDF,并将结果返回为字节数据,准备好下载。 此外,它还可以通过将URL直接转换为PDF来处理整个网页。

创建控制器

现在是为我们的API创建控制器的时间了。 这将提供一个可以从HTML生成PDF文件的API端点。 然后,能够下载并将PDF文档保存到您的系统中,以便进一步使用或共享。

// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}

然后,在HtmlRequest.cs文件中,我们将添加:

// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}

在第一个文件中,我们设置了一个简单的API端点,将HTML转换为可下载的PDF。 当有人通过简单的POST请求将HTML内容发送到api/pdf/html-to-pdf路由时,PdfController将任务传递给专用的服务,将其转换为PDF。

一旦PDF创建完成,控制器将它作为一个准备好下载的文件返回给用户。请求本身是使用HtmlRequest模型结构化的,该模型携带原始HTML和用于最终文档的可选文件名。 简而言之,此设置使得客户端可以轻松发送HTML并立即获得一个精美的PDF作为返回。

注册服务

更新您的Program.cs以注册PDF服务:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

如何处理不同的响应类型?

您的API应该支持基于客户端需求以不同方式返回PDF:

[HttpPost("generate")]
 public IActionResult GeneratePdf([FromBody] PdfRequest request)
 {
     var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
     switch (request.ResponseType?.ToLower())
     {
         case "base64":
             return Ok(new
             {
                 data = Convert.ToBase64String(pdfBytes),
                 filename = request.FileName
             });
         case "inline":
             return File(pdfBytes, "application/pdf");
         default: // download
             return File(pdfBytes, "application/pdf", request.FileName);
     }
 }

在这里,我们在控制器中添加了一个更灵活的PDF生成端点。 而不是总是强制下载文件,GeneratePdf方法让客户端选择他们希望结果如何返回。 此选项提供灵活性,允许PDF以多种格式显示:作为可下载文件,直接在浏览器中,或编码为Base64字符串以便在API中轻松使用。

请求由PdfRequest模型定义,该模型基于之前的HtmlRequest,并添加一个ResponseType选项。 总之,这使用户能够更好地控制如何接收他们的PDF,使API更加多样化和用户友好。

现在,当我们运行程序时,我们将在Swagger上看到此输出。

如何使用IronPDF创建.NET PDF API:图4 - Swagger UI

如何实现常见的PDF操作?

让我们扩展我们的服务以处理各种PDF生成场景:

URL到PDF转换

[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() => 
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf", 
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}

此端点允许客户端发送一个URL并获取该网页的可下载PDF。 当POST /api/pdf/url-to-pdf请求到达时,控制器使用_pdfService后台将给定的URL转换为PDF字节,然后以文件下载的形式返回。 如果在转换过程中出现问题,它会优雅地响应一个清晰的错误信息。

让我们尝试使用网址"https://www.apple.com/nz"并测试POST请求。下面是我们获得的输出。

输出

如何使用IronPDF创建.NET PDF API:图5 - URL PDF 输出

添加自定义水印

public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}

在这里,我们只是手动加载一个本地的文件以进行测试。 然而,您可以调整这个,以便您的PDF API生成PDF文档,然后轻松地应用自定义水印。

水印输出

如何使用IronPDF创建.NET PDF API:图6 - 来自上述代码示例的水印输出

如何使用模板添加动态数据

对于真实世界的应用程序,您通常需要从模板生成带有动态数据的PDFs:

[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}

对于更高级的模板场景,请查看IronPDF的HTML到PDF文档。 您还可以探索CSHTML到PDF转换用于MVC应用程序和Razor到PDF用于Blazor应用程序。

如何优化性能?

在构建生产PDF API时,性能至关重要。 以下是关键的优化策略:

异步操作

当构建涉及使用I/O操作的项目时,明智的做法是使用异步编码。 如果您的PDF内容来自外部资源,这尤其有用,例如:

  • 下载HTML页面(RenderUrlAsPdf)
  • 通过HTTP获取图像、CSS或字体
  • 读取/写入磁盘或云存储的文件

这些操作可以阻塞线程,但使用异步可以防止您的API线程空闲等待。

例:

public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() => 
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}

渲染选项

配置IronPDF以获得最佳性能:

_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout

如何保护您的PDF API?

对于任何生产API,安全性都是至关重要的。 这里是一个简单的API密钥身份验证方法:

// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();

对于更高级的身份验证场景,请考虑:

实际案例:发票生成API

让我们构建一个实际的发票生成端点,演示完整的实现。 此示例展示了如何使用生产.NET PDF API生成具有动态数据的专业发票。

第一步:
arrow pointer

首先,我们将在我们的Models文件夹中创建一个新文件。 在这里,我将其称之为Invoice.cs。 然后,将以下代码添加到您的新文件中。

public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}

然后,我们将需要为我们的发票生成器创建一个新的服务文件。 在您的Services文件夹中,添加以下代码。 对于我的,我创建了一个名为InvoiceService.cs的新文件。 这段代码将处理我们的发票PDF文件的样式和布局。

public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
{
    var html = BuildInvoiceHtml(invoice);
    // Add footer with page numbers
    _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        MaxHeight = 15,
        HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
        DrawDividerLine = true
    };
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item => 
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{font-family: Arial, sans-serif;}}
                .invoice-header {{background-color: #f8f9fa; 
                    padding: 20px; 
                    margin-bottom: 20px;}}
                table {{width: 100%; 
                    border-collapse: collapse;}}
                th, td {{padding: 10px; 
                    border-bottom: 1px solid #ddd;}}
                th {{background-color: #007bff; 
                    color: white;}}
                .text-right {{text-align: right;}}
                .text-center {{text-align: center;}}
                .total-section {{margin-top: 20px; 
                    text-align: right;}}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>   
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>    
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
C#

最后,您将需要创建一个新的控制器,以便通过API访问并创建一个新的发票。

[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}

发票输出

如何使用IronPDF创建.NET PDF API:图7 - PDF 发票输出

容器部署注意事项

虽然本教程侧重于本地开发,但这里是关于将您的PDF API容器化的简要概述:

基础Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
    libgdiplus \
    libc6-dev \
    libx11-dev \
    && rm -rf /var/lib/apt/lists/*     
ENTRYPOINT ["dotnet", "PdfApiService.dll"]

有关您的.NET PDF API的详细部署指南,请参阅:

错误处理最佳实践

为了设计更具容错性的程序,最佳实践是实施全局错误处理程序,以获得一致的错误响应,例如下面所示:

// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 500;
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}

对于特定的IronPDF故障排除场景,请参阅IronPDF故障排除指南

结论

您现在已经构建了一个强大的.NET PDF API,使用ASP.NET Core和IronPDF可以处理多种文档生成场景。 这个REST API为您的应用程序提供集中化PDF操作的坚实基础。

关键要点:

  • IronPDF使得Web API项目中的PDF生成变得简单,具有其基于Chrome的渲染
  • 您可以轻松调整Web API以编辑现有PDF文档,利用IronPDF的高级编辑工具
  • RESTful设计原则确保您的PDF API直观且易于维护
  • 适当的错误处理和安全措施对于生产至关重要
  • 通过异步操作和缓存进行性能优化可提高可扩展性
  • 您将拥有支持桌面和Web应用程序的可扩展文档解决方案

IronPDF允许开发人员高效地创建PDF文档、保存PDF文件和转换HTML,使其成为现代.NET Framework应用程序中的必备PDF文档API。

下一步

准备好在您的生产.NET PDF API中实施IronPDF了吗? 以下是您的下一步操作:

  1. 开始免费试用 - 在您的开发环境中测试IronPDF的全部功能
  2. 探索高级功能 - 查看数字签名PDF表单和其他高级PDF功能
  3. 自信地扩展 - 查看许可选项以满足您的生产API需求

今天就构建您的.NET PDF API,并通过IronPDF在整个应用程序生态系统中简化文档生成!

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 Iron Suite
预约您的免费现场演示
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