管理者ダッシュボードのためのC#でのPDFへのワンクリックエクスポート
HTMLコンテンツを大規模に保持する際の問題
組織がレガシーCMS、イントラネット、または外向けポータルを廃止する際、その上のコンテンツが単純に重要でなくなるわけではありません。 病院が患者健康記事データベースを引退させる場合でも、これらの記事は保存される必要があり、政府機関がウェブサイトをリデザインする際には、特定の時点に存在した公表通知を保持する必要があります。法律事務所がケースリサーチプラットフォームを閉鎖する際には、すべてのページを法的保持に耐える形式に変換する必要があります。
規模が大きいほど、すべての手動アプローチは失敗します。 ブラウザベースのPDFへの印刷 は1つの文書に対して機能します。 一方で、10,000の場合は解決策ではありません。ヘッドレスブラウザのスクリプトは、不正なHTML、欠落したアセット、または認証の壁にぶつかるまで機能しますが、レガシーコンテンツは清潔であることが稀です。
既存のバッチ変換ツールは、2005年のインラインスタイル、標準外のテーブルレイアウト、解決できなくなったパスへの画像参照など、古いマークアップに同様の問題があります。 これらは失敗するか、壊れたレイアウトのPDFを生成するか、各ページごとに手動の修正が必要です。 その間に、ITチームは移行を完了するだけのためにレガシーインフラを無期限にオンラインにし続けることを正当化できません。
出力も一貫している必要があります。 健康記事をアーカイブする病院、規制の遵守のための開示ページを保存する金融機関、保持アーカイブを構築する法律事務所、これらすべての結果としてのPDFは個々のブラウザ出力の集まりではなく、同じシステムから来たものであるかのように見える必要があります。 このチュートリアルでは、IronPDF の例を通じて、このライブラリがどのようにプロジェクトのワークフローを向上させるかをご紹介します。
ソリューション:IronPDFによる自動HTMLからPDFバッチ変換
Iron SoftwareのIronPDFは、.NETアプリケーションがHTMLファイル、HTML文字列、またはライブのURLを標準化されたPDFにシングルランで自動変換できるようにします。 移行スクリプトはソースから読み取ります:HTMLファイルのディレクトリ、HTMLブロブのデータベース、または古いサーバーがオフラインになる前にキャプチャするURLのリストです。各ページをChromePdfRendererにフィードし、出力をアーカイブ先に書き込みます。
Chromiumベースのレンダリングエンジンは、HTMLがどのように書かれたかに関係なく、ブラウザが扱うように不一致のマークアップ、インラインスタイル、および埋め込みアセットを扱い、視覚的に忠実なスナップショットを生成します。 メンテナンスが必要なブラウザ自動化のハックはなく、50,000ページのアーカイブが持続不可能にならないような1ドキュメントごとのAPI料金もありません。変換は.NETコンソールアプリケーションまたはバックグラウンドサービスで実行され、1つのNuGetパッケージで外部プロセスはありません。
実践での動作方法:C# PDFドキュメント作成
1. 移行スクリプトがソースコンテンツを列挙します
スクリプトは通常、移行のために構築されたコンソールアプリケーションで、1回実行または増分コンテンツセットのための繰り返しジョブです。 これは、ディスク上の.htmlファイルのディレクトリ、HTML ブロブとメタデータ(元のURL、作成日、コンテンツID)のデータベーステーブル、または古いサーバーがオフラインになる前にキャプチャするためのライブWebページのフラットリストからのソース列挙で開始します。
データベースのソースでは、クエリはHTMLコンテンツとアーカイブマニフェストを埋めるメタデータの両方を返します。URLリストの場合、処理の順序は優先順位に従って並べ替えることができ、高トラフィックページや法的に機密性の高いコンテンツが最初にキャプチャされます。
2. スタイルシートの挿入が出力を標準化します
レガシーHTMLは本質的に一貫していません。 同じCMSの異なる時代のページは、基本フォントサイズ、余白の規約、レイアウトの仮定が異なることがあります。 レンダリング前に、スクリプトはオプションで各HTML文字列に標準化された<style> ブロックを付け加えることができます - 一致した余白、統一されたボディフォント、固定ページ幅を設定することで、元のスタイルがどうであれ、すべてのアーカイブされたPDFドキュメントが同じ視覚的基準を共有するようにします。
この標準化ステップは、一貫したドキュメントコレクションのように見えるアーカイブと、ブラウザキャプチャのランダムな集合のように見えるアーカイブの違いを示しています。
3. ChromePdfRendererが各ページをPDFファイルに変換します
ディスク上のHTMLファイルまたはデータベースからのHTML文字列の場合、RenderHtmlAsPdf()が変換を処理します。 BaseUrlPathパラメータは、元のファイルのディレクトリに対して相対画像とスタイルシートの参照を解決し、埋め込み資産を保持します:
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
string sourceDir = @"C:\LegacyContent\html";
string archiveDir = @"C:\Archive\pdf";
Directory.CreateDirectory(archiveDir);
foreach (string htmlFile in Directory.EnumerateFiles(sourceDir, "*.html"))
{
string html = File.ReadAllText(htmlFile);
PdfDocument pdf = renderer.RenderHtmlAsPdf(html, sourceDir);
string outputPath = Path.Combine(archiveDir,
Path.GetFileNameWithoutExtension(htmlFile) + ".pdf");
pdf.SaveAs(outputPath);
Console.WriteLine($"Archived: {outputPath}");
}
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
string sourceDir = @"C:\LegacyContent\html";
string archiveDir = @"C:\Archive\pdf";
Directory.CreateDirectory(archiveDir);
foreach (string htmlFile in Directory.EnumerateFiles(sourceDir, "*.html"))
{
string html = File.ReadAllText(htmlFile);
PdfDocument pdf = renderer.RenderHtmlAsPdf(html, sourceDir);
string outputPath = Path.Combine(archiveDir,
Path.GetFileNameWithoutExtension(htmlFile) + ".pdf");
pdf.SaveAs(outputPath);
Console.WriteLine($"Archived: {outputPath}");
}
Imports IronPdf
Imports System.IO
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
Dim sourceDir As String = "C:\LegacyContent\html"
Dim archiveDir As String = "C:\Archive\pdf"
Directory.CreateDirectory(archiveDir)
For Each htmlFile As String In Directory.EnumerateFiles(sourceDir, "*.html")
Dim html As String = File.ReadAllText(htmlFile)
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(html, sourceDir)
Dim outputPath As String = Path.Combine(archiveDir, Path.GetFileNameWithoutExtension(htmlFile) & ".pdf")
pdf.SaveAs(outputPath)
Console.WriteLine($"Archived: {outputPath}")
Next
HTMLファイルがPDF形式に変換される

出力例:HTMLファイル対出力PDF
動作中のサーバーからキャプチャが必要なページの場合、RenderUrlAsPdf()が各リクエストを処理します。並列バッチ処理により、大きなURLセット全体での実行時間を適切に管理できます:
using IronPdf;
var renderer = new ChromePdfRenderer();
int completed = 0, failed = 0;
await Parallel.ForEachAsync(urlList,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
async (url, _) =>
{
try
{
PdfDocument pdf = renderer.RenderUrlAsPdf(url);
string filename = Uri.EscapeDataString(url).Replace("%", "_") + ".pdf";
pdf.SaveAs(Path.Combine(@"C:\Archive\pdf", filename));
Interlocked.Increment(ref completed);
}
catch (Exception ex)
{
Interlocked.Increment(ref failed);
Console.Error.WriteLine($"Failed: {url} — {ex.Message}");
}
Console.WriteLine($"Progress: {completed} completed, {failed} failed");
});
using IronPdf;
var renderer = new ChromePdfRenderer();
int completed = 0, failed = 0;
await Parallel.ForEachAsync(urlList,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
async (url, _) =>
{
try
{
PdfDocument pdf = renderer.RenderUrlAsPdf(url);
string filename = Uri.EscapeDataString(url).Replace("%", "_") + ".pdf";
pdf.SaveAs(Path.Combine(@"C:\Archive\pdf", filename));
Interlocked.Increment(ref completed);
}
catch (Exception ex)
{
Interlocked.Increment(ref failed);
Console.Error.WriteLine($"Failed: {url} — {ex.Message}");
}
Console.WriteLine($"Progress: {completed} completed, {failed} failed");
});
Imports IronPdf
Imports System.IO
Imports System.Threading
Imports System.Threading.Tasks
Dim renderer As New ChromePdfRenderer()
Dim completed As Integer = 0
Dim failed As Integer = 0
Await Parallel.ForEachAsync(urlList,
New ParallelOptions With {.MaxDegreeOfParallelism = 4},
Async Function(url, _) As Task
Try
Dim pdf As PdfDocument = renderer.RenderUrlAsPdf(url)
Dim filename As String = Uri.EscapeDataString(url).Replace("%", "_") & ".pdf"
pdf.SaveAs(Path.Combine("C:\Archive\pdf", filename))
Interlocked.Increment(completed)
Catch ex As Exception
Interlocked.Increment(failed)
Console.Error.WriteLine($"Failed: {url} — {ex.Message}")
End Try
Console.WriteLine($"Progress: {completed} completed, {failed} failed")
End Function)
URLから生成されたファイル

例の出力
各出力PDFは、元のサイト階層を反映するフォルダ構造に保存され、各文書の元のURL、変換タイムスタンプ、出力パスを記録するマニフェストファイルがあります。
実世界の利点
スループット。 IronPDFは数ミリ秒で各ページをレンダリングします。 4つの並列スレッドで10,000ページのアーカイブは通常、標準のサーバーハードウェアで数時間で完了します。夜間のバッチウィンドウは不要で、変換実行間の手作業の引継ぎもありません。
視覚的忠実度。 Chromiumベースのレンダリングにより、テーブル、CSSレイアウト、埋め込み画像、およびインラインスタイルがブラウザで処理されるのと同じ方法で処理されます。 アーカイブされたPDFは、元のページの見た目と一致し、単なる簡略化された概算ではありません。
スケジュール通りに廃止。 アーカイブ実行が完了し、マニフェストが確認されると、レガシーサーバー、データベース、およびCMSインストールはシャットダウンできます。 コンテンツは、自給自足のPDFコレクションとして永続的に存在し、古いインフラが提供した何にも依存しません。
規制遵守。 変わらないPDFスナップショットは、法的保持および保持要件を満たします。 IronPDFは、長期アーカイブ保存のためにPDF/A出力をサポートしており、ISO標準化された形式に変換する単一のレンダリングオプションが、規制されている文書保持のために受け入れられます。
コンテンツ品質の一貫性。 レンダリング前に標準化されたスタイルシートを挿入することで、開発者が基準に従って記述したか、Wordから貼り付けたコンテンツ作成者が書いたかに関わらず、すべてのアーカイブされたPDFが統一された余白、フォント、およびページ寸法を共有することを保証します。
1ドキュメントごとのコストがありません。 変換はプロセス内で実行されます。 外部変換ベンダーへのAPI呼び出しはなく、大規模なアーカイブを不均衡に高価にする価格モデルもありません。500ページや50,000ページをインフラストラクチャの観点で変換するコストは同じです。
結び
廃止期限があるコンテンツ移行では、手動の変換ワークフローや不正なHTMLで失敗するツールに時間を残すことはできません。 変換は自動的に実行され、一貫した出力を大量に生成し、古いサーバーがオフラインになる前に終了する必要があります。
.NET移行スクリプトを使用してIronPDFでその全面をカバーし、ソースコンテンツを列挙し、スタイルを標準化し、Chromiumを介して各ページをレンダリングし、アーカイブ先に書き込み、レビューのために失敗をログします。 IronPDFは、HTML文字列やURLのレンダリングから、文書を保存、ストリーミング、操作するまで、C#でのPDF生成の全ライフサイクルをironpdf.com で処理します。 移行のスコープを設定したり、パイロットランを開始したりする場合、30日間の無料トライアル は、レガシーコンテンツの代表的なサンプルを変換し、完全なアーカイブに取り組む前に出力を検証するのに十分な時間を与えます。




