IRONSOFTWAREHOME
使用IRONPDF

如何在C# .NET中将JPG转换为PDF

Curtis Chau
Curtis Chau
Updated: 2026年7月19日

利用 ASP.NET Core 和 IronPDF 构建一个生产就绪的 .NET PDF API,以集中管理 PDF 生成逻辑,通过用于 HTML 转 PDF、合并、添加水印和动态模板处理的 RESTful 端点,实现应用程序间文档创建的一致性。

在开发现代应用程序时,.NET 开发人员通常需要构建一个集中的 PDF 生成服务。无论是生成发票、报告、证书还是合同,拥有一个专用的 .NET PDF API 都能优化您的 PDF 生成工作流程。 它有何帮助?它能在您的桌面和 Web 应用程序中提供一致性、可维护性和可扩展性。 管理文档内容、PDF 页面和 PDF 表单字段变得轻而易举。

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

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

体系结构图显示客户端应用程序(网页、桌面、移动)将HTML内容、URLs或动态数据发送到PDF控制器/服务API层,输出PDF文档。

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

  • 集中化逻辑:所有 PDF 生成逻辑集中于一处,简化了维护和更新工作。
  • 微服务架构:非常适合面向服务的架构,其中不同应用程序需要 PDF 功能。
  • 性能优化:利用异步操作性能优化技术,更轻松地扩展并优化专用于处理大型 PDF、多页文档及动态数据的专用服务。
  • 语言无关:无论使用何种编程语言,任何客户端应用程序均可调用该 API。
  • 输出一致性:确保贵组织内所有 PDF 文件在版式、格式和内容上保持一致。

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

是什么让 IronPDF 成为最全面的 .NET PDF 库?

IronPDF for .NET主页显示C#代码示例用于将HTML转换为PDF,具有HTML渲染、文件保存和NuGet安装命令等功能

IronPDF是 .NET 开发人员首选的 PDF 库,它提供了一套全面的功能,使 Web API 项目中的 PDF 生成变得简单可靠。 该工具基于 Chrome 渲染引擎构建,仅需几行代码即可实现像素级精准的 HTML 转 PDF 转换,同时完整保留所有样式、JavaScript 执行效果及响应式布局

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

如何设置您的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
SHELL

如何安装 IronPDF?

接下来,通过 NuGet 将 IronPDF 添加到您的项目中:

dotnet add package IronPdf

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

PM > Install-Package IronPdf

有关高级安装选项(包括特定平台的软件包Docker 设置Linux 配置),请查阅 IronPDF 安装文档

我应该采用什么样的项目结构?

良好的 C# 开发需要保持项目文件夹的整洁与结构清晰。 例如:

Visual Studio解决方案资源管理器显示.NET PDF API服务项目的文件夹结构,其中包含控制器、模型和服务目录

如何创建您的第一个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,此类配置了默认设置,如页面边距背景渲染,以获得专业的结果。 如需高级渲染配置,请探索IronPDF 的渲染选项

当控制器传递原始 HTML 时,该服务将其渲染成高质量的 PDF,并返回字节数据以供下载。 它还可以使用URL 转 PDF 功能,将整个网页直接转换为 PDF。

如何创建控制器?

现在创建 API 的控制器。 这提供了一个可以从 HTML 生成 PDF 文件的端点,并允许您将 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。 当有人将HTML发送到PdfController将转换工作委托给服务。

创建后,控制器返回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方法让客户端选择如何接收结果:作为下载、在浏览器中内嵌显示,或为API使用的Base64编码

ResponseType选项。 这使用户能够控制 PDF 文件的交付方式,从而使 API 更加灵活。有关在不访问文件系统的情况下处理内存中的 PDF 文件,请参阅IronPDF 的内存流文档

运行程序后,我们会在 Swagger 中看到以下输出:

Swagger UI文档显示PdfApiService端点,具有三个用于PDF操作的POST方法:html-to-pdf、generate和url-to-pdf,以及请求模式。

如何实现常见的PDF操作?

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

如何将网址转换为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请求到达_pdfService在后台将URL转换为PDF字节,然后返回以供下载。 如果转换失败,它会显示明确的错误信息。 对于需要身份验证的网站,请查看IronPDF 的登录文档

我们来试试使用这个网址"https://www.apple.com/nz并测试 POST 请求。以下是我们得到的输出:

输出结果是什么样的?

Apple新西兰网站主页显示多个产品部分,包括iPhone 16、MacBook Air、Apple Watch和AirPods,带有'了解更多'和'购买'按钮——演示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,然后轻松应用自定义水印。 有关高级水印选项,包括图像水印和自定义定位,请参阅水印指南

水印输出效果是什么样的?

一个显示有'机密'水印的安全文件,水印对角线显示在空白页上,文档ID:BA811648DCE1FF2AAA55E7CE显示在顶部

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

对于真实世界的应用程序,您通常需要从模板生成带有动态数据的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";
}

对于使用 Razor、Handlebars 或其他引擎的高级模板场景,请查看IronPDF 的 HTML 转 PDF 文档。 您还可以探索CSHTML到PDF转换用于MVC应用程序和Razor到PDF用于Blazor应用程序。 对于无头 Razor 渲染,请参阅CSHTML 无头指南

如何优化性能?

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

为什么要使用异步操作?

当你的项目涉及 I/O 操作时,请使用异步编码。 当您的 PDF 内容来自外部资源时,这一点尤其有用,例如:

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

这些操作可能会阻塞线程,但异步操作可以防止 API 线程空闲等待。 有关完整的异步 PDF 生成模式,请参阅异步 PDF 生成指南

例:

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

对于并行生成 PDF 的场景,可以探索多线程并行处理技术。

我应该配置哪些渲染选项?

配置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>();

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

对于 PDF 的特定安全措施,应实施密码保护数字签名PDF 清理,以删除潜在的恶意内容。

如何构建一个实际应用的发票生成 API?

让我们构建一个实用的发票生成端点,以演示完整的实现过程。 本示例展示了生产环境中的 .NET PDF API 如何使用动态数据生成专业发票。

First Step:
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}");
        }
    }
}

对于高级发票功能,可以考虑添加条形码二维码页码自定义页眉/页脚。 您还可以实施PDF/A 合规性以进行长期存档,或与电子签名工作流程集成。

发票输出格式是什么样的?

PDF invoice document showing Invoice #INV-1023 dated 2025-08-22, with a single line item for 'Misc Object' totaling $495.00 including tax

容器部署需要考虑哪些因素?

虽然本教程侧重于本地开发,但这里是关于将您的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"]
Text

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

错误处理的最佳实践有哪些?

对于容错程序,应实现全局错误处理程序,以确保错误响应的一致性:

// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ErrorHandlingMiddleware> _logger;
    public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred processing request {Path}", context.Request.Path);
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = ex switch
        {
            ArgumentNullException => 400,
            UnauthorizedAccessException => 401,
            _ => 500
        };
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message,
            statusCode = context.Response.StatusCode
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}

有关 IronPDF 的具体故障排除方案,请参阅: 快速故障排除指南 *工程支持指南 *自定义日志配置 *防止内存泄漏 *性能优化技巧

准备好构建您的生产级 .NET PDF API 了吗?

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

关键要点:

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

IronPDF 使开发人员能够高效地创建 PDF、保存 PDF 文件和转换 HTML,使其成为现代 .NET Framework 应用程序必不可少的 PDF API。

下一步是什么?

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

1.开始免费试用- 在您的开发环境中测试 IronPDF 的全部功能。 2.探索高级功能- 查看数字签名PDF 表单PDF/A 合规性元数据管理和其他高级 PDF 功能。 3.自信扩展- 查看满足您生产 API 需求的许可选项,包括扩展升级

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

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...
Read More

Related Articles

Key in blue circle

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

bullet_checked无需信用卡或创建账户
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge related to IronPDF Product Demo

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

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