C#でHTML要素・ページの一部をPDF 変換する方法|IronPDF

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronPDFは、特定のHTML要素をターゲットにするための組み込みのSelectCssメソッドを公開していません。 ChromePdfRendererは、完全なHTMLドキュメントをレンダリングします - 完全なページ、完全なURL、完全なHTML文字列。 ページの特定のセクションからPDFを生成するために、JavaScript DOM操作、CSSインジェクション、サーバーサイドのHTMLフラグメント抽出、URLレンダリングとJSターゲティングの4つのアプローチの1つを使用してレンダリング前にターゲット要素を分離します。

各アプローチは異なる制約に適しています。 JavaScript DOMの分離は、ターゲットを除いて全てを削除する必要がある場合に、URLや完全なページをレンダリングする際に機能します。 CSSインジェクションは、DOMを変更せずに不要なコンテンツを隠します。 サーバーサイドの抽出は、生のHTMLにアクセスできる場合に最もクリーンな結果を提供します。 URLレンダリングとJSターゲティングは、ソースHTMLが利用できないライブダッシュボードやサードパーティーページを処理します。

無料の30日間トライアルを開始して、全てのアプローチをテストしてください。

クイックスタート: 特定のHTML要素をPDF 変換で抽出する

JavaScript DOMアイソレーションとWaitForを使用してCSSセレクタで任意の要素をターゲットにし、そのフラグメントだけをPDFにレンダリングします。

  1. IronPDF をNuGetパッケージマネージャでインストール

    PM > Install-Package IronPdf
  2. このコード スニペットをコピーして実行します。

    using IronPdf;
    
    var renderer = new ChromePdfRenderer();
    renderer.RenderingOptions.EnableJavaScript = true;
    renderer.RenderingOptions.JavaScript = @"
        var target = document.querySelector('#invoice-summary');
        document.body.innerHTML = target.outerHTML;
    ";
    renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000);
    
    var pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
    pdf.SaveAs("invoice-summary.pdf");
  3. 実際の環境でテストするためにデプロイする

    今日プロジェクトで IronPDF を使い始めましょう無料トライアル

    arrow pointer

最小のワークフロー (3つのステップ)

  1. NuGetを通じてIronPDFをインストールします: Install-Package IronPdf
  2. ChromePdfRenderOptions.JavaScriptでターゲット要素を分離し、WaitForで存在を確認します
  3. RenderHtmlAsPdf()またはRenderUrlAsPdf()を呼び出します - PDFには分離したコンテンツのみが含まれます

JavaScript DOM操作で要素を分離する方法は?

ChromePdfRenderOptions.JavaScriptプロパティはHTMLの読み込み後、PDFのレンダリング前に実行されるJavaScriptの文字列を受け取ります。 レンダリングされたページから他の全てを削除するためにターゲット要素のouterHTMLと置き換えます。 これは最も多用途なアプローチで、RenderUrlAsPdf()の両方で機能します。

WaitFor.HtmlQuerySelector()メソッドは、JavaScript実行前にターゲット要素がDOMに存在することを確認します。 これは非同期コンテンツを含むページでは重要です — Reactコンポーネント、Angularテンプレート、API駆動のデータが初期ページ読み込み後に入力されます。

using IronPdf;

string fullPageHtml = @"
<html>
<body>
    <header><h1>Acme Corp Invoice</h1></header>
    <nav>Navigation links...</nav>
    <div id='invoice-summary'>
        <h2>Invoice #12345</h2>
        <table>
            <tr><td>Widget A</td><td>$49.99</td></tr>
            <tr><td>Widget B</td><td>$29.99</td></tr>
            <tr><td><strong>Total</strong></td><td><strong>$79.98</strong></td></tr>
        </table>
    </div>
    <footer>Footer content...</footer>
</body>
</html>";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

// Replace the body with only the target element
renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        document.body.innerHTML = el.outerHTML;
    }
";

// Wait for the target element to exist before JS executes
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-summary-only.pdf");
using IronPdf;

string fullPageHtml = @"
<html>
<body>
    <header><h1>Acme Corp Invoice</h1></header>
    <nav>Navigation links...</nav>
    <div id='invoice-summary'>
        <h2>Invoice #12345</h2>
        <table>
            <tr><td>Widget A</td><td>$49.99</td></tr>
            <tr><td>Widget B</td><td>$29.99</td></tr>
            <tr><td><strong>Total</strong></td><td><strong>$79.98</strong></td></tr>
        </table>
    </div>
    <footer>Footer content...</footer>
</body>
</html>";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

// Replace the body with only the target element
renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        document.body.innerHTML = el.outerHTML;
    }
";

// Wait for the target element to exist before JS executes
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-summary-only.pdf");
Imports IronPdf

Dim fullPageHtml As String = "
<html>
<body>
    <header><h1>Acme Corp Invoice</h1></header>
    <nav>Navigation links...</nav>
    <div id='invoice-summary'>
        <h2>Invoice #12345</h2>
        <table>
            <tr><td>Widget A</td><td>$49.99</td></tr>
            <tr><td>Widget B</td><td>$29.99</td></tr>
            <tr><td><strong>Total</strong></td><td><strong>$79.98</strong></td></tr>
        </table>
    </div>
    <footer>Footer content...</footer>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = True

' Replace the body with only the target element
renderer.RenderingOptions.JavaScript = "
    var el = document.querySelector('#invoice-summary');
    if (el) {
        document.body.innerHTML = el.outerHTML;
    }
"

' Wait for the target element to exist before JS executes
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000)

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fullPageHtml)
pdf.SaveAs("invoice-summary-only.pdf")
$vbLabelText   $csharpLabel

JavaScriptは#invoice-summary divのouterHTMLでページ全体を置き換えます。 結果のPDFには請求書テーブルのみが含まれます — ヘッダー、ナビゲーション、フッターはありません。 WaitFor.HtmlElementById()メソッドは、IDでターゲットする場合により簡単な代替案を提供します。

// Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
// Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
' Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000)
$vbLabelText   $csharpLabel

複雑なセレクタ(クラス名、データ属性、ネストされた要素)には、document.querySelector()で受け入れられる任意の有効なCSSセレクタ文字列を受け入れます。 追加のHtmlQuerySelector()に委任しますが、コード内でのより明確な意図を提供します。

ターゲット要素が親コンテナから継承されたスタイルに依存している場合、outerHTML置換は祖先セレクタに依存するCSSルールを失う可能性があります(例:.dashboard .widget table { ... })。 これを保持するためには、関連する<head>からJSアイソレーションにコピーします。

renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        var head = document.head.innerHTML;
        document.body.innerHTML = el.outerHTML;
        document.head.innerHTML = head;
    }
";
renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        var head = document.head.innerHTML;
        document.body.innerHTML = el.outerHTML;
        document.head.innerHTML = head;
    }
";
renderer.RenderingOptions.JavaScript = "
    var el = document.querySelector('#invoice-summary');
    if (el) {
        var head = document.head.innerHTML;
        document.body.innerHTML = el.outerHTML;
        document.head.innerHTML = head;
    }
"
$vbLabelText   $csharpLabel

これにより、元の<head>コンテンツ(スタイルシート、フォント、メタタグ)が保持され、ボディのみが置き換えられます。 JavaScriptからPDFへの方法WaitForの方法は、複数の非同期データソースを含むページのためのNetworkIdle0()の追加設定オプションをカバーしています。

CSSインジェクションで要素を分離する方法は?

ChromePdfRenderOptions.CustomCssUrlプロパティは、IronPDFがレンダリング前に適用するスタイルシートへのファイルパスまたはURLを受け入れます。 DOMを操作する代わりに、ターゲット要素以外をCSS display: noneで隠します。 これにより、元のDOM構造が保持され、JavaScriptの実行を完全に避けることができます。

using IronPdf;

// Create a CSS file that hides everything except #invoice-summary
string cssContent = @"
body > *:not(#invoice-summary) {
    display: none !important;
}
#invoice-summary {
    display: block !important;
    margin: 0;
    padding: 20px;
}
";
File.WriteAllText("isolate-element.css", cssContent);

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CustomCssUrl = "isolate-element.css";

PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-css-isolated.pdf");
using IronPdf;

// Create a CSS file that hides everything except #invoice-summary
string cssContent = @"
body > *:not(#invoice-summary) {
    display: none !important;
}
#invoice-summary {
    display: block !important;
    margin: 0;
    padding: 20px;
}
";
File.WriteAllText("isolate-element.css", cssContent);

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CustomCssUrl = "isolate-element.css";

PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-css-isolated.pdf");
Imports IronPdf
Imports System.IO

' Create a CSS file that hides everything except #invoice-summary
Dim cssContent As String = "
body > *:not(#invoice-summary) {
    display: none !important;
}
#invoice-summary {
    display: block !important;
    margin: 0;
    padding: 20px;
}
"
File.WriteAllText("isolate-element.css", cssContent)

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CustomCssUrl = "isolate-element.css"

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fullPageHtml)
pdf.SaveAs("invoice-css-isolated.pdf")
$vbLabelText   $csharpLabel

注意: RenderHtmlAsPdf()とだけ組み合わせて機能します。 URLレンダリングの場合、CSSインジェクションをJavaScriptプロパティに埋め込みます。

renderer.RenderingOptions.JavaScript = @"
    var style = document.createElement('style');
    style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
    document.head.appendChild(style);
";
renderer.RenderingOptions.JavaScript = @"
    var style = document.createElement('style');
    style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
    document.head.appendChild(style);
";
renderer.RenderingOptions.JavaScript = "
    var style = document.createElement('style');
    style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
    document.head.appendChild(style);
"
$vbLabelText   $csharpLabel

ソースHTMLを制御している場合、@media printルールは最も軽量な代替案を提供します — 外部依存関係はありません、実行時のインジェクションもありません。

@media print {
    header, nav, footer, .sidebar { display: none !important; }
    #invoice-summary { width: 100%; margin: 0; }
}

CssMediaTypePdfCssMediaType.Printに設定してこれらのルールをアクティブ化します。

renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
$vbLabelText   $csharpLabel

これは、すでに印刷専用のレイアウトを定義しているアプリケーションのフォームセクション印刷シナリオに最適です。 保険請求フォームや多段階のウィザード、チェックアウトサマリーは、@media printルールを使用してナビゲーションと進捗インジケーターを隠しながら、関連するコンテンツセクションを全幅に拡大することが一般的です。

CSSアプローチには1つ重要な制限があります: display: noneを誤った特異性レベルで使用すると、隠された要素がドキュメントフロー内のスペースを占有したままになります。 特定のブレークポイントで要素を再表示する可能性のあるフレームワークスタイル(Bootstrap、Tailwind)を上書きするには、常に!importantを使用します。 深くネストされたターゲットの場合、より正確なセレクタがコラテラルな隠れを回避します。

body > *:not(#target),
body > *:not(#target) ~ * {
    display: none !important;
}

サーバーサイドでHTMLフラグメントを抽出する方法は?

生のHTMLにアクセス可能な場合 — ファイル、データベース、CMS、HTTPレスポンスから読み取るとき — 最もクリーンなアプローチはHTMLパーサーを使用してターゲット要素をサーバーサイドで抽出し、RenderHtmlAsPdf()にフラグメントを渡すことです。 JavaScriptもCSSインジェクションも実行時DOM操作もありません。

AngleSharpは、このパターンの標準的な.NET HTMLパーサーです。

using IronPdf;
using AngleSharp;
using AngleSharp.Html.Parser;

string fullPageHtml = @"
<html>
<head>
    <style>
        table { border-collapse: collapse; width: 100%; }
        td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
    </style>
</head>
<body>
    <header><h1>Dashboard</h1></header>
    <div id='revenue-widget'>
        <h3>Q4 Revenue</h3>
        <table>
            <tr><th>Month</th><th>Revenue</th></tr>
            <tr><td>October</td><td>$1.2M</td></tr>
            <tr><td>November</td><td>$1.5M</td></tr>
            <tr><td>December</td><td>$1.8M</td></tr>
        </table>
    </div>
    <div id='other-content'>Other widgets...</div>
</body>
</html>";

// Parse and extract the target element
var parser = new HtmlParser();
var document = parser.ParseDocument(fullPageHtml);
var targetElement = document.QuerySelector("#revenue-widget");

if (targetElement is null)
{
    Console.WriteLine("Target element not found.");
    return;
}

// Wrap the fragment in a minimal HTML document to preserve styles
string fragmentHtml = $@"
<html>
<head>
    <style>
        table {{ border-collapse: collapse; width: 100%; }}
        td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
    </style>
</head>
<body>
    {targetElement.OuterHtml}
</body>
</html>";

var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget.pdf");
using IronPdf;
using AngleSharp;
using AngleSharp.Html.Parser;

string fullPageHtml = @"
<html>
<head>
    <style>
        table { border-collapse: collapse; width: 100%; }
        td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
    </style>
</head>
<body>
    <header><h1>Dashboard</h1></header>
    <div id='revenue-widget'>
        <h3>Q4 Revenue</h3>
        <table>
            <tr><th>Month</th><th>Revenue</th></tr>
            <tr><td>October</td><td>$1.2M</td></tr>
            <tr><td>November</td><td>$1.5M</td></tr>
            <tr><td>December</td><td>$1.8M</td></tr>
        </table>
    </div>
    <div id='other-content'>Other widgets...</div>
</body>
</html>";

// Parse and extract the target element
var parser = new HtmlParser();
var document = parser.ParseDocument(fullPageHtml);
var targetElement = document.QuerySelector("#revenue-widget");

if (targetElement is null)
{
    Console.WriteLine("Target element not found.");
    return;
}

// Wrap the fragment in a minimal HTML document to preserve styles
string fragmentHtml = $@"
<html>
<head>
    <style>
        table {{ border-collapse: collapse; width: 100%; }}
        td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
    </style>
</head>
<body>
    {targetElement.OuterHtml}
</body>
</html>";

var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget.pdf");
Imports IronPdf
Imports AngleSharp
Imports AngleSharp.Html.Parser

Dim fullPageHtml As String = "
<html>
<head>
    <style>
        table { border-collapse: collapse; width: 100%; }
        td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
    </style>
</head>
<body>
    <header><h1>Dashboard</h1></header>
    <div id='revenue-widget'>
        <h3>Q4 Revenue</h3>
        <table>
            <tr><th>Month</th><th>Revenue</th></tr>
            <tr><td>October</td><td>$1.2M</td></tr>
            <tr><td>November</td><td>$1.5M</td></tr>
            <tr><td>December</td><td>$1.8M</td></tr>
        </table>
    </div>
    <div id='other-content'>Other widgets...</div>
</body>
</html>"

' Parse and extract the target element
Dim parser As New HtmlParser()
Dim document = parser.ParseDocument(fullPageHtml)
Dim targetElement = document.QuerySelector("#revenue-widget")

If targetElement Is Nothing Then
    Console.WriteLine("Target element not found.")
    Return
End If

' Wrap the fragment in a minimal HTML document to preserve styles
Dim fragmentHtml As String = $"
<html>
<head>
    <style>
        table {{ border-collapse: collapse; width: 100%; }}
        td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
    </style>
</head>
<body>
    {targetElement.OuterHtml}
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml)
pdf.SaveAs("revenue-widget.pdf")
$vbLabelText   $csharpLabel

キーディテールは、抽出したフラグメントを適切な<link>タグを含む完全なHTMLドキュメントにラップすることです。 このラッパーがないと、インラインスタイルは正しくレンダリングされるが、外部スタイルシートと継承されたCSSルールは失われます。メールテンプレートプレビューのレンダリングでは、すでに文字列として保存されているテンプレートHTMLは、この抽出パターンによってピクセル単位で完璧な結果を得ることができます。

同様のパターンは、代替パーサーとしてHtmlAgilityPackで機能します。

using HtmlAgilityPack;
using IronPdf;

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(fullPageHtml);

var targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']");
if (targetNode is null)
{
    Console.WriteLine("Target element not found.");
    return;
}

string fragmentHtml = $"<html><body>{targetNode.OuterHtml}</body></html>";

var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget-hap.pdf");
using HtmlAgilityPack;
using IronPdf;

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(fullPageHtml);

var targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']");
if (targetNode is null)
{
    Console.WriteLine("Target element not found.");
    return;
}

string fragmentHtml = $"<html><body>{targetNode.OuterHtml}</body></html>";

var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget-hap.pdf");
Imports HtmlAgilityPack
Imports IronPdf

Dim htmlDoc As New HtmlDocument()
htmlDoc.LoadHtml(fullPageHtml)

Dim targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']")
If targetNode Is Nothing Then
    Console.WriteLine("Target element not found.")
    Return
End If

Dim fragmentHtml As String = $"<html><body>{targetNode.OuterHtml}</body></html>"

Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml)
pdf.SaveAs("revenue-widget-hap.pdf")
$vbLabelText   $csharpLabel

AngleSharpとHtmlAgilityPackの選択は主に好みの問題です。 AngleSharpはCSSセレクタ(QuerySelector)を使用し、フロントエンド開発者のメンタルモデルと合致します。 HtmlAgilityPackはXPath(SelectSingleNode)を使用し、XMLを多用する.NETコードベースでより馴染み深いです。

メールテンプレートプレビューのレンダリングでは、テンプレートHTMLがデータベースまたはCMSに文字列として保存されている場合、サーバーサイドの抽出により、レンダリングされたコンテンツのあらゆる面を制御することができるため、ピクセル単位で完璧な結果が得られます。 また、RenderHtmlAsPdf(string Html, string BaseUrlOrPath)を使用し、2番目のパラメータをローカルアセットディレクトリに指定することで、相対パスで参照される画像やスタイルシートを正しく解決することができます。

PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml, "C:\templates\assets\")
$vbLabelText   $csharpLabel

JavaScript DOMの分離とのトレードオフは、サーバーサイドの抽出ではクライアントサイドのレンダリングを必要とするコンテンツ(JavaScript生成の要素、SPAコンポーネント、APIで取得したデータ)を処理できないことです。 HTMLに<div id="app"></div>が含まれる場合、ReactやVueアプリケーションが実行時に入力する場合、抽出されたフラグメントは空になります。 そのような場合は、アプローチ1または4を使用します。

ライブURLをレンダリングする際に要素をターゲットにする方法は?

ソースHTMLにアクセスできないライブURLの場合 — サードパーティのダッシュボード、外部レポート、ホストされたアプリケーション — ではRenderUrlAsPdf()JavascriptプロパティおよびWaitForを組み合わせ、ページ読み込み後に特定のセクションを分離します。

これは、ダッシュボードウィジェットをエクスポートするシナリオです: BIツールがウェブページ上でチャートやテーブルをレンダリングし、単一のウィジェットを利害関係者配信用のPDFとしてエクスポートする必要があります。

using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

// Wait for the dashboard widget to render (async content)
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000);

// Isolate the widget after it renders
renderer.RenderingOptions.JavaScript = @"
    var widget = document.querySelector('[data-widget=""revenue-chart""]');
    if (widget) {
        // Preserve computed styles by cloning into a clean body
        document.body.innerHTML = '';
        document.body.appendChild(widget);
    }
";

PdfDocument pdf = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report");
pdf.SaveAs("revenue-chart-export.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

// Wait for the dashboard widget to render (async content)
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000);

// Isolate the widget after it renders
renderer.RenderingOptions.JavaScript = @"
    var widget = document.querySelector('[data-widget=""revenue-chart""]');
    if (widget) {
        // Preserve computed styles by cloning into a clean body
        document.body.innerHTML = '';
        document.body.appendChild(widget);
    }
";

PdfDocument pdf = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report");
pdf.SaveAs("revenue-chart-export.pdf");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = True

' Wait for the dashboard widget to render (async content)
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000)

' Isolate the widget after it renders
renderer.RenderingOptions.JavaScript = "
    var widget = document.querySelector('[data-widget=""revenue-chart""]);
    if (widget) {
        // Preserve computed styles by cloning into a clean body
        document.body.innerHTML = '';
        document.body.appendChild(widget);
    }
"

Dim pdf As PdfDocument = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report")
pdf.SaveAs("revenue-chart-export.pdf")
$vbLabelText   $csharpLabel

WaitFor.HtmlQuerySelector()呼び出しによって、ウィジェットがJavaScript実行前にDOMに存在することを確認します。 15秒のタイムアウトは、ダッシュボードデータを入力するAPI呼び出しの遅さに対応しています。 JavaScriptはその後、ページを該当のウィジェットのみへと削減します。

複雑なCSS依存のページの場合、outerHTMLのコピー)は、要素がCSSOMにおける位置を保持するため、より多くの計算スタイルを保持します。 第一アプローチのinnerHTML置換アプローチは簡素ですが、祖先セレクタに依存するスタイルを失う可能性があります。

ターゲットページが認証を必要とする場合、RenderUrlAsPdf()を呼び出す前にレンダラーでクッキーを設定します。

renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "session_id", "abc123" },
    { "auth_token", "bearer-xyz" }
};
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "session_id", "abc123" },
    { "auth_token", "bearer-xyz" }
};
Imports System.Collections.Generic

renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
    {"session_id", "abc123"},
    {"auth_token", "bearer-xyz"}
}
$vbLabelText   $csharpLabel

WaitForクラスはHtmlQuerySelector()を超える追加の待機戦略を提供します。 NetworkIdle0()は、全てのネットワークリクエストがゼロの未解決接続で完了するまで待機します — 複数のAPIエンドポイントからデータをロードするダッシュボードで有用です。 NetworkIdle2()は最大2つの未解決接続を許容し、持続的なWebSocket接続やロングポーリングを持つページを処理します。 window.ironpdf.notifyRender()をコールするまで待機します — 全てのデータロードとアニメーションが完了した後にレンダリング準備完了を明示的にシグナルできるターゲットページを制御する場合の最も正確なオプションです。

定期的なダッシュボードエクスポート(例:夜間のPDF生成を利害関係者メール配信用)では、タイムアウト例外をキャッチするリトライループにレンダリングをラップします。 もしmaxWaitTimeを超えた場合、IronPDFは利用可能なコンテンツでレンダリングを続行します - これは不完全である可能性があります。 タイムアウトを延ばすかNetworkIdle0()に切り替えることにより、通常は遅いネットワークでの一時的な失敗を解決します。

4つのアプローチの比較

アプローチ 最適 ソースHTMLが必要 JS依存 複雑
JavaScript DOMアイソレーション 任意のソースからの一般的な要素抽出 なし はい 中規模
CSSインジェクション DOMの変更なしにセクションを隠します; @media printレイアウト 部分的(CustomCssUrlはRenderHtmlAsPdfが必要) なし(URLのためにJSで注入しない限り) 低レベル
サーバーサイドフラグメント抽出 CMSコンテンツ、保存されたテンプレート、メールプレビュー はい なし 低–中
JSターゲティングによるURLレンダリング ライブダッシュボード、サードパーティーページ、SPAウィジェット なし はい 中 –高

正しいアプローチの選択

決定は2つの要素に依存します: 生のHTMLにアクセスできるかどうかと、ターゲットコンテンツがJavaScriptでレンダリングを必要としているかどうか。

請求書の行項目抽出は最も一般的なユースケースです。 請求書のHTMLがサーバーサイドで生成される場合(Razorビュー、Handlebarsテンプレート、保存されたHTML文字列)、アプローチ3(サーバーサイド抽出)はランタイムオーバーヘッドゼロで最もクリーンな結果を提供します。 #line-itemsテーブルを抽出し、スタイル付きHTMLシェルにラップしてレンダリングします。

ダッシュボードウィジェットのエクスポートはJavaScriptの実行を必要とします。なぜならウィジェットの内容は初期ページ読み込み後にAPI呼び出しで入力されるからです。 アプローチ1(JS DOMアイソレーション)は、ダッシュボードがローカルで実行されるか、認証の背後にある場合に処理します。 アプローチ4(JSターゲティングによるURLレンダリング)は、ダッシュボードがサードパーティのホストされたアプリケーションでURLしか持たない場合に必要です。

フォームセクション印刷 — ユーザーの見直しやコンプライアンスアーカイブのために、マルチステップフォームの特定のセクションを抽出する — は、アプリケーションがすでに@media printルールを定義している場合、アプローチ2(CSSインジェクション)に自然に一致します。また、フォームHTMLがサーバーサイドで組み立てられる場合はアプローチ3です。

メールテンプレートプレビューのレンダリング - HTMLメールテンプレートの送信前にPDFプレビューを生成する - は純粋なアプローチ3のシナリオです。 テンプレートHTMLは保存された文字列であり、外部リソース(画像、フォント)は既知のURLにホストされており、RenderHtmlAsPdf()を指定し、全ての相対パスを解決します。

複数のシナリオをサポートする必要があるアプリケーションでは、戦略パラメータを受け入れるサービスインターフェースの背後でレンダリングロジックをカプセル化します。

public enum ElementExtractionStrategy
{
    JavaScriptIsolation,
    CssInjection,
    ServerSideExtraction,
    UrlWithJsTargeting
}
public enum ElementExtractionStrategy
{
    JavaScriptIsolation,
    CssInjection,
    ServerSideExtraction,
    UrlWithJsTargeting
}
Public Enum ElementExtractionStrategy
    JavaScriptIsolation
    CssInjection
    ServerSideExtraction
    UrlWithJsTargeting
End Enum
$vbLabelText   $csharpLabel

これにより、レンダラー構成を重複させることなく、入力タイプに基づいて適切なアプローチを呼び出すコードが選択できます。

次のステップ

IronPDFでのHTML要素のアイソレーションはレンダリング時の課題であり、組み込みのAPI機能ではありません。 上記の4つのアプローチは全範囲をカバーしています - サーバーサイドテンプレート抽出(ゼロJS、最もクリーンな出力)からライブURLターゲティング(完全なJS実行、SPAと非同期コンテンツに対応)まで。 比較表は迅速な参照を提供し、実世界のシナリオは一般的なビジネス要件を適切な戦略にマップします。

プロダクション展開に関する追加の考慮事項がいくつかあります:

パフォーマンス: サーバーサイド抽出(アプローチ3)はJavaScriptの実行を完全にスキップするため最速です。 JavaScriptをベースにしたアプローチ(1と4)は、ページの複雑さとWaitForタイムアウトに比例してオーバーヘッドを追加します。 バッチ処理(例:500件の請求書PDFの生成)の場合は、サーバーサイド抽出とChromePdfRendererインスタンスを使用すると最高のスループットが得られます。

デバッグ: PDF出力が空白であるかコンテンツが欠けている場合、WaitForタイムアウトを増やします。 ターゲット要素が非同期データに依存する場合、RenderDelayよりも信頼性があります。 レンダリングオプションガイドは、レイアウトに影響を与えるビューポート幅とペーパーフィットの構成をカバーしています。

アプローチの組み合わせ: 戦略のミックスを防ぐものはありません。 複数のフラグメント(1つのソースからのヘッダー、別のソースからのデータテーブル、第三のソースからのチャートSVG)からコンポジットHTMLドキュメントを構築するためにサーバーサイド抽出を使用し、組み立てたドキュメントを単一のPDFとしてレンダリングすることができます。 RenderHtmlAsPdf(string Html, string BaseUrlOrPath)メソッドは、基本URLからの相対アセットパスを解決するため、異なるソースからドキュメントを作成するのが簡単になります。

JavaScriptからPDFへの詳しい手順で高度なJS実行パターン、WaitForドキュメントすべての利用可能な待機戦略、レンダリングオプションガイドで完全なChromePdfRenderOptionsサーフェスを参照し、カスタムJavaScriptコード例で実行可能なスニペットをご覧ください。

ライセンスオプションを閲覧し、$749からスタートします。ChromePdfRenderOptions APIのリファレンスおよびWaitFor APIのリファレンスは、すべてのプロパティとメソッドを文書化しています。

よくある質問

C#でHTML要素をPDFに変換する主な方法は何ですか?

主なアプローチには、JSの分離、CSSの非表示、サーバーサイドでの抽出、およびライブURLの指定が含まれ、これらはすべてIronPDFを使用して実装可能です。

HTMLからPDFへの変換において、JSの分離はどのように機能しますか?

JSアイソレーションとは、HTMLドキュメントをPDFに変換する前に、JavaScriptを実行してそのドキュメントを動的に操作する手法です。IronPDFを使用することで、特定の要素のみがレンダリングされるようにすることができます。

CSSの隠し機能とは何ですか?また、PDF変換においてどのように使用されますか?

CSSによる非表示とは、PDFに表示すべきでない要素をCSSスタイルを使用して非表示にすることです。IronPDFは、変換プロセス中に開発者がスタイルシートやスタイルルールを指定できるようにすることで、この機能をサポートしています。

IronPDFは、PDF生成のためにサーバーサイドで特定のHTML要素を抽出できますか?

はい、IronPDFはサーバーサイドで特定のHTML要素を抽出できるため、ウェブページのどの部分をPDFに変換するかを正確に制御できます。

HTMLからPDFへの変換において、ライブURLの指定にはどのような利点がありますか?

ライブURL対応機能により、IronPDFはライブWebページのURLから要素を直接PDFに変換することができ、ローカルのHTMLファイルを必要とせずに最新のコンテンツを確実に取得できます。

IronPDFを使用して、ウェブページの一部のみをPDFに変換することは可能ですか?

はい、IronPDFにはウェブページの特定のセクションや要素をPDFに変換する機能があり、関連するコンテンツに焦点を当てやすくします。

IronPDFは、HTMLからPDFへの変換時に動的コンテンツをどのように処理しますか?

IronPDFは、変換中にJavaScriptを実行することで動的コンテンツをレンダリングでき、クライアントサイドのスクリプトに依存する要素がPDF内で正確に表現されることを保証します。

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

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

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

準備はできましたか?
Nuget ダウンロード 18,560,885 | バージョン: 2026.4 リリース
Still Scrolling Icon

まだスクロールしていますか?

すぐに証拠が欲しいですか? PM > Install-Package IronPdf
サンプルを実行するHTML が PDF に変換されるのを確認します。