フッターコンテンツにスキップ
IRONPDFの使用

ASP.NET Core と IronPDF を使って集中型 PDF 生成サービスを構築する方法

ASP.NET Core と IronPDF を使用して、PDF 生成ロジックを一元管理し、HTML から PDF への変換、結合、透かし、および動的テンプレート処理用の RESTful エンドポイントを使用して、アプリケーション全体で一貫したドキュメント作成を可能にする、運用可能な .NET PDF API を構築します。

.NET開発者は、最新のアプリケーションを扱う際に、一元化されたPDF生成サービスを構築する必要に迫られることがよくあります。請求書、レポート、証明書、契約書など、どのようなファイルを生成する場合でも、専用の.NET PDF APIがあれば、PDF生成ワークフローを改善できます。 どのように役立つのでしょうか? デスクトップ アプリケーションと Web アプリケーション全体に一貫性、保守性、スケーラビリティを提供します。 ドキュメント コンテンツ、PDF ページ、 PDF フォーム フィールドの管理が簡単になります。

このチュートリアルでは、ASP.NET Coreと強力な.NET PDFライブラリであるIronPDFを使用して、プロダクション対応のPDF APIを構築する方法を学びます。 HTML から PDF を生成し、ドキュメントを結合し透かしを追加し、Web API でさまざまな実際の PDF シナリオを処理する RESTful エンドポイントを作成します。

専用PDF APIを構築する理由

クライアント アプリ (Web、デスクトップ、モバイル) が HTML コンテンツ、URL、または動的データを PDF コントローラー/サービス API レイヤーに送信し、PDF ドキュメントを出力する様子を示すアーキテクチャ図。

コードに飛び込む前に、専用PDF APIを作成する意義を理解しましょう:

*集中ロジック*: すべての PDF 生成ロジックが 1 か所にまとめられるため、メンテナンスと更新が簡単になります。 マイクロサービス アーキテクチャ: さまざまなアプリで PDF 機能が必要なサービス指向アーキテクチャに最適です。 パフォーマンスの最適化:非同期操作パフォーマンス技術を使用して、大きな PDF、複数のページ、および動的データ専用のサービスを簡単に拡張および最適化できます。 言語非依存**: プログラミング言語に関係なく、どのクライアント アプリケーションでも API を使用できます。 *一貫した出力: 組織全体のすべての PDF で一貫したレイアウト、書式、コンテンツが維持されます。

構築開始の準備はできましたか? IronPDFの無料トライアルをダウンロードして、このチュートリアルに従って、.NET FrameworkプロジェクトでPDFファイルをプログラムで作成する方法を学びましょう。

IronPDF が完全な .NET PDF ライブラリである理由は何ですか?

! IronPDF for .NET ホームページでは、HTML レンダリング、ファイル保存、NuGet インストール コマンドなどの機能を備えた HTML を PDF に変換する C# コード例を示しています。

IronPDFは、.NET開発者のための最高のPDFライブラリとして際立っており、Web APIプロジェクトでのPDF生成を簡単で信頼性の高いものにする包括的な機能のセットを提供しています。 Chrome レンダリング エンジン上に構築されており、すべてのスタイル、 JavaScript 実行レスポンシブ レイアウトを維持しながら、わずか数行のコードでピクセル単位の完璧なHTML から PDF への変換を実現します。

IronPDFが.NET PDF API開発に理想的な理由となる主な機能:

PDFドキュメントAPIプロジェクトのセットアップ方法

新しいASP.NET Core Web APIプロジェクトを作成し、必要なパッケージをインストールするところから始めましょう。

前提条件は何ですか?

  • .NET 6.0 SDK以降
  • Visual Studio 2022またはVisual Studio Code
  • PDF REST APIをテストするためのPostmanまたは同様のAPIテストツール

プロジェクトを作成するにはどうすればよいですか?

まず、PDF 生成ツールを構築するプロジェクトを作成しましょう。

dotnet new webapi -n PdfApiService
cd PdfApiService
dotnet new webapi -n PdfApiService
cd PdfApiService
SHELL

IronPDF をインストールするにはどうすればよいですか?

次に、NuGet 経由で IronPDF をプロジェクトに追加します。

dotnet add package IronPDF
dotnet add package IronPDF
SHELL

または、Visual StudioのNuGetパッケージマネージャーコンソールを使用して:

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);
}
public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
$vbLabelText   $csharpLabel

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;
    }
}
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;
    }
}
$vbLabelText   $csharpLabel

PdfService HTML から PDF への変換を処理します。 このクラスは、IronPDF のChromePdfRendererを使用して、ページ余白背景レンダリングなどのデフォルトを設定し、プロフェッショナルな結果を実現します。 高度なレンダリング構成については、 IronPDF のレンダリング オプションを参照してください。

コントローラーが生の HTML を渡すと、サービスはそれを高品質の PDF にレンダリングし、ダウンロード用のバイト データを返します。 また、 URL から PDF への変換を使用して、Web ページ全体を直接 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}");
        }
    }
}
// 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}");
        }
    }
}
$vbLabelText   $csharpLabel

次に、 HtmlRequest.csファイルに以下を追加します。

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

これにより、HTML をダウンロード可能な PDF に変換する API エンドポイントが設定されます。 誰かが HTML をapi/pdf/html-to-pdfに送信すると、 PdfController変換をサービスに委任します。

コントローラーはPDFファイルを作成すると、ダウンロード可能なファイルとして返します。リクエストにはHTMLとオプションのファイル名を含むHtmlRequestモデルが使用されます。 これにより、クライアントは HTML を送信し、洗練された PDF を受け取ることが容易になります。

サービスを登録するにはどうすればいいですか?

PDFサービスを登録するために、Program.csを更新してください:

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();
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();
$vbLabelText   $csharpLabel

さまざまなレスポンスタイプの処理方法

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);
    }
}
[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);
    }
}
$vbLabelText   $csharpLabel

これにより、柔軟な PDF 生成エンドポイントが追加されます。 GeneratePdfメソッドでは、ダウンロードを強制する代わりに、ダウンロード、ブラウザー内のインライン、または API 使用のためにBase64 でエンコードされた形式で結果を受信する方法をクライアントが選択できます。

PdfRequestモデルは、 ResponseTypeオプションを使用してHtmlRequestを拡張します。 これにより、ユーザーはPDF配信を制御できるようになり、APIの汎用性が向上します。ファイルシステムにアクセスせずにメモリ内でPDFを処理する方法については、 IronPDFのメモリストリームに関するドキュメントをご覧ください。

プログラムを実行すると、Swagger に次の出力が表示されます。

! PDF 操作用の 3 つの POST メソッド (html-to-pdf、generate、url-to-pdf) を持つ PdfApiService エンドポイントとリクエスト スキーマを示す 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; }
}
[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; }
}
$vbLabelText   $csharpLabel

このエンドポイントは、URL をダウンロード可能な PDF に変換します。 POST リクエストが/api/pdf/url-to-pdfに到達すると、コントローラーは_pdfServiceを使用して、バックグラウンドで URL を PDF バイトに変換し、ダウンロード用に返します。 変換に失敗した場合は、明確なエラー メッセージが返されます。 認証が必要な Web サイトの場合は、 IronPDF のログイン ドキュメントをご覧ください。

URL"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;
}
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;
}
$vbLabelText   $csharpLabel

これにより、テスト用にローカル ファイルが手動で読み込まれます。 これを調整することで、PDF API が PDF を生成し、カスタム透かしを簡単に適用できるようになります。 画像の透かしやカスタム配置などの高度な透かしオプションについては、透かしガイドを参照してください。

透かしの出力はどのようになりますか?

空白ページに斜めにCONFIDENTIALの透かしが入った安全な文書。上部に文書ID: BA811648DCE1FF2AAA55E7CEが表示されている。

テンプレートを使用して動的データを追加するにはどうすればよいでしょうか?

実際の世界のアプリケーションでは、動的データを含むテンプレートからPDFを生成する必要がよくあります:

[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";
}
[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";
}
$vbLabelText   $csharpLabel

Razor、Handlebars、またはその他のエンジンを使用した高度なテンプレート シナリオについては、 IronPDF の HTML から PDF へのドキュメントを参照してください。 また、MVCアプリケーションでのCSHTMLからPDF変換や、BlazorアプリケーションでのRazorからPDF変換を探索することもできます。 ヘッドレス Razor レンダリングについては、 CSHTML ヘッドレス ガイドを参照してください。

パフォーマンスを最適化する方法

本番PDF APIを構築する際には、パフォーマンスが重要です。 最適化のための重要な戦略は以下の通りです:

非同期操作を使用する理由

プロジェクトに I/O 操作が含まれる場合は、非同期コーディングを使用します。 これは、PDF コンテンツが次のような外部リソースから取得される場合に特に役立ちます。

  • HTML ページのダウンロード (RenderUrlAsPdf<//code>)
  • 画像、CSS、フォントのHTTPによる取得
  • ディスクやクラウドストレージへの読み込み/書き込み

これらの操作はスレッドをブロックする可能性がありますが、非同期により API スレッドがアイドル状態で待機することが防止されます。 包括的な非同期 PDF 生成パターンについては、非同期 PDF 生成ガイドを参照してください。

例:

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

並列 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
_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
$vbLabelText   $csharpLabel

ビューポート設定カスタム用紙サイズページの向きなどの包括的なレンダリング構成オプションについては、レンダリング オプションのドキュメントを参照してください。

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>();
// 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>();
$vbLabelText   $csharpLabel

高度な認証シナリオでは、次の点を考慮してください。

PDF 固有のセキュリティについては、パスワード保護デジタル署名、およびPDF サニタイズを実装して、潜在的に悪意のあるコンテンツを削除します。

実際の請求書生成 API を構築するにはどうすればよいでしょうか?

完全な実装を示す実用的な請求書生成エンドポイントを構築しましょう。 この例では、運用 .NET PDF API が動的なデータを使用してプロフェッショナルな請求書を生成する方法を示します。

今IronPDFを始めましょう。
green 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;
}
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;
}
$vbLabelText   $csharpLabel

次に、請求書ジェネレーターの新しいサービス ファイルを作成します。 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>";
    }
}
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>";
    }
}
$vbLabelText   $csharpLabel

最後に、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}");
        }
    }
}
[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}");
        }
    }
}
$vbLabelText   $csharpLabel

高度な請求書機能については、バーコードQR コードページ番号カスタム ヘッダー/フッターの追加を検討してください。 また、長期アーカイブ用にPDF/A 準拠を実装したり、電子署名ワークフローと統合したりすることもできます。

請求書の出力はどのようになりますか?

! 2025年8月22日付の請求書番号INV-1023を示すPDF請求書文書。"その他のオブジェクト"の1行項目で、合計495.00ドル(税込)

コンテナのデプロイメントに関する考慮事項は何ですか?

このチュートリアルはローカル開発に焦点を当てていますが、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;
    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));
    }
}
// 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));
    }
}
$vbLabelText   $csharpLabel

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で合理化してください!

よくある質問

IronPDFは.NETアプリケーションで何に使われていますか?

IronPDFは.NETアプリケーション内でPDFを生成、操作、変換するために使用され、集中型PDFサービスの作成に理想的です。

IronPDF はどのようにASP.NET Coreと統合できますか?

IronPDF NuGetパッケージをインストールすることで、IronPDFをASP.NET Coreに統合し、集中型のPDF生成サービスを構築することができます。

PDF生成のためのIronPdfの主な機能は何ですか?

IronPDFの主な機能には、HTMLからPDFへの変換、PDFの結合と分割、ヘッダーとフッターの追加、テキストと画像の抽出などがあります。

IronPdfは複雑なPDFレイアウトに対応できますか?

IronPDFはHTMLやCSSのコンテンツを正確にレンダリングされたPDFドキュメントに変換するため、複雑なPDFレイアウトを扱うことができます。

IronPDFでPDF作成をカスタマイズすることは可能ですか?

はい、IronPdfはPDFの作成において、ページサイズや余白の設定、透かしや注釈の追加などのカスタマイズが可能です。

IronPDFはPDFのセキュリティ機能をサポートしていますか?

IronPDFは生成されたPDFドキュメントを保護するためにパスワード保護や暗号化などのPDFセキュリティ機能をサポートしています。

IronPDFはどのようなフォーマットをPDFに変換できますか?

IronPdfはHTML、URL、ASPXファイルを含む様々なフォーマットをPDFに変換することができます。

IronPDFはどのように大規模なPDF生成に対応していますか?

IronPDFはパフォーマンスのために最適化されており、.NETアプリケーション内で大規模なPDF生成タスクを効率的に処理することができます。

IronPDFはクラウドベースのアプリケーションで使用できますか?

はい、IronPdfはクラウドベースのアプリケーションで使用することができ、スケーラブルなPDFサービスのためにAzureやAWSのようなプラットフォームへのデプロイをサポートします。

IronPDFはどのバージョンの.NETをサポートしていますか?

IronPDFは.NET Coreと.NET Frameworkを含む複数の.NETバージョンをサポートし、幅広いプロジェクトとの互換性を保証します。

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。