How to Convert HTML to PDF with Responsive CSS using C#
fo .NET (FO .NET) からIronPDFへの移行は、 .NET PDF 生成プロセスの主要な更新です。 このガイドでは、開発チームが既に持っているスキルを活用して、コードベースを古い XSL-FO マークアップから最新の HTML/CSS ベースの PDF 生成に移行するための、わかりやすく段階的な方法を紹介します。
なぜfo.netからIronPDFへ移行するのか
fo.netの課題
fo.net (FO.NET)は、XSL-FOドキュメントをPDFに変換する初期のApache FOPビルドのC#版です。 これはApache 2.0ライセンスですが、現在の開発にはいくつかの制限があります。
-
旧式技術: XSL-FO (拡張スタイルシート言語フォーマットオブジェクト) は2001年のW3C規格です; W3Cは2013年にXSL-FOワーキンググループを閉じ、言語にはこれ以上の開発はありませんでした。
-
複雑な学習曲線: XSL-FOは、特化されたフォーマットオブジェクト(
fo:page-sequenceなど)を用いた詳細なXMLベースのマークアップを必要とします。 -
HTML/CSSのサポートなし: fo.netはHTMLやCSSをレンダリングできません—HTMLをXSL-FOに変換する必要があります(通常はXSLTを使用)。
-
放棄/非メンテナンス: nuget.orgの
Fonetパッケージは、2011年4月に最後に公開されました(v1.0.0、.NET Framework 2.0)。 コミュニティフォークFonet.Standard(.NET Standard 2.0)は、2020年5月に最後に公開されました(v1.0.5)。 CodePlexリポジトリは廃止され、GitHubフォーク(hahmed/Fo.Net)は休止状態です。 -
実際にはWindows専用: レガシー
System.Drawing(GDI+)APIに依存しており、実質的にWindowsに限定されます。 -
近代的機能の制限: JavaScriptエンジンなし、CSS3(flexbox/grid)なし、近代的なウェブフォントのロードなし。
- URL レンダリングなし: fo .NET はWeb ページを直接レンダリングできないため、手動で HTML から XSL-FO に変換する必要があります。
fo.netとIronPDFの比較
| アスペクト | fo.net (FO.NET) | IronPDF |
|---|---|---|
| 入力フォーマット | XSL-FO(古いXML) | HTML/CSS(最新のウェブ標準) |
| 学習曲線 | スティープ(XSL-FOの専門知識) | ジェントル(HTML/CSSの知識) |
| メンテナンス | 放棄(最後のリリース2020年5月) | 積極的なメンテナンス |
| プラットフォームサポート | Windowsのみ | マルチプラットフォーム(.NET Framework 4.6.2以上、.NET Core 3.1以上、.NET 5/6/7/8/9以上) |
| CSSサポート | None | フルCSS3(フレックスボックス、グリッド) |
| JavaScript | None | JavaScriptフルサポート |
| URLレンダリング | サポートされていません | 内蔵 |
| 最新の機能 | 制限的 | ヘッダー、フッター、透かし、セキュリティ |
| ドキュメンテーション | 古い | 徹底的なチュートリアル |
なぜ切り替えは理にかなっているのか
fo.netは、XSL-FOが文書フォーマットの標準になると予想されたときに設計されました。 そのような期待は実現しませんでした。 HTML/CSSは普遍的なドキュメント形式になりましたが、XSL-FOはニッチなスキルのままであり、ほとんどのXSL-FOリソースは2005–2010年からで、メンテナンスがますます困難になっています。
IronPDFを使用すると、すでに持っているスキルを活かしてモダンな.NETでプロフェッショナルなPDFを作成できます。
始める前に
前提条件
- .NET環境: IronPDFは.NET Framework 4.6.2以降、 .NET Core 3.1以降、 .NET 5/6/7/8/9以降をサポートしています。
- NuGetアクセス: NuGetからパッケージをインストールできることを確認する 3.ライセンスキー: IronPDFから本番環境で使用するIronPDFライセンスキーを取得します。
プロジェクトのバックアップ
# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net toIronPDFmigration"
# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net toIronPDFmigration"
すべてのfo.netの使用法を特定する
# Find all fo.net references
grep -r "FonetDriver\|Fonet\|\.fo\"\|xsl-region" --include="*.cs" --include="*.csproj" .
# Find all XSL-FO template files
find . -name "*.fo" -o -name "*.xslfo" -o -name "*xsl-fo*"
# Find all fo.net references
grep -r "FonetDriver\|Fonet\|\.fo\"\|xsl-region" --include="*.cs" --include="*.csproj" .
# Find all XSL-FO template files
find . -name "*.fo" -o -name "*.xslfo" -o -name "*xsl-fo*"
XSL-FOテンプレートを文書化する
移行する前に、すべてのXSL-FOファイルをカタログ化し、メモしてください:
- ページ寸法と余白
- 使用フォント
- 表とその構造
- ヘッダーとフッター(
fo:static-content) - ページ番号のパターン
- 画像参照
クイック スタート マイグレーション
ステップ 1: NuGet パッケージを更新する
# Remove fo.net package
dotnet remove package Fonet
dotnet remove package FO.NET
# Install IronPDF
dotnet add package IronPdf
# Remove fo.net package
dotnet remove package Fonet
dotnet remove package FO.NET
# Install IronPDF
dotnet add package IronPdf
ステップ 2: 名前空間の更新
// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;
// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;
// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;
// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;
Imports IronPdf
Imports IronPdf.Rendering
ステップ3: IronPDFを初期化する
// Set license key at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Set license key at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Set license key at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
ステップ 4: 基本的な変換パターン
// Before (fo.net with XSL-FO)
FonetDriver driver = FonetDriver.Make();
using (FileStream output = new FileStream("output.pdf", FileMode.Create))
{
driver.Render(new StringReader(xslFoContent), output);
}
// After (IronPDF with HTML)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
// Before (fo.net with XSL-FO)
FonetDriver driver = FonetDriver.Make();
using (FileStream output = new FileStream("output.pdf", FileMode.Create))
{
driver.Render(new StringReader(xslFoContent), output);
}
// After (IronPDF with HTML)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Imports System.IO
Imports Fonet
Imports IronPdf
' Before (fo.net with XSL-FO)
Dim driver As FonetDriver = FonetDriver.Make()
Using output As FileStream = New FileStream("output.pdf", FileMode.Create)
driver.Render(New StringReader(xslFoContent), output)
End Using
' After (IronPDF with HTML)
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
完全な API リファレンス
名前空間マッピング
| fo.net 名前空間 | IronPDF 同等物 |
|---|---|
Fonet |
IronPdf |
Fonet.Render.Pdf |
IronPdf |
Fonet.Layout |
該当なし |
Fonet.Fo |
該当なし |
Fonet.Image |
IronPdf |
FonetDriverからChromePdfRendererへの翻訳
| FonetDriver メソッド | IronPDF 同等物 |
|---|---|
FonetDriver.Make() |
new ChromePdfRenderer() |
driver.Render(inputStream, outputStream) |
renderer.RenderHtmlAsPdf(html) |
driver.Render(inputFile, outputStream) |
renderer.RenderHtmlFileAsPdf(path) |
driver.BaseDirectory |
RenderingOptions.BaseUrl |
driver.OnError += handler |
レンダリング周りのトライ/キャッチ |
レンダリングオプション (PDF 設定)
| fo.net (XSL-FO属性) | IronPDF レンダリングオプション |
|---|---|
page-height |
PaperSize または SetCustomPaperSize() |
page-width |
PaperSize |
margin-top |
MarginTop |
margin-bottom |
MarginBottom |
margin-left |
MarginLeft |
margin-right |
MarginRight |
reference-orientation |
PaperOrientation |
XSL-FOからHTMLへの変換ガイド
XSL-FO要素をHTML/CSSに変換する
このfo.net移行における基本的なシフトは、XSL-FO要素を同等のHTMLに変換することです:
| XSL-FO要素 | HTML/CSS相当 |
|---|---|
<fo:root> |
<html> |
<fo:layout-master-set> |
CSS @page ルール |
<fo:simple-page-master> |
CSS @page |
<fo:page-sequence> |
<body> または <div> |
<fo:flow> |
<main> または <div> |
<fo:static-content> |
HtmlHeaderFooter |
<fo:block> |
<p>, <div>, <h1>-<h6> |
<fo:inline> |
<span> |
<fo:table> |
<table> |
<fo:table-row> |
<tr> |
<fo:table-cell> |
<td>, <th> |
<fo:list-block> |
<ul>, <ol> |
<fo:list-item> |
<li> |
<fo:external-graphic> |
<img> |
<fo:page-number> |
{page} プレースホルダー |
<fo:page-number-citation> |
{total-pages} |
<fo:basic-link> |
<a href> |
XSL-FOプロパティからCSSへ
| XSL-FOプロパティ | CSS相当 | 翻訳例 |
|---|---|---|
font-family |
font-family |
同じ構文 |
font-size |
font-size |
同じ構文 |
font-weight |
font-weight |
bold, normal, 700 |
text-align |
text-align |
left, center, right, justify |
color |
color |
16進数、RGB、名前 |
background-color |
background-color |
同じ構文 |
space-before |
margin-top |
翻訳前 |
space-after |
margin-bottom |
要素 |
start-indent |
margin-left |
左インデント |
keep-together |
page-break-inside: avoid |
改行を防ぐ |
break-before="page" |
page-break-before: always |
強制改ページ |
コード例
例1: 基本的なHTMLからPDFへ
ビフォア(XSL-FO付きfo.net):
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;
class Program
{
static void Main()
{
// fo.net requires XSL-FO format, not HTML
// First convert HTML to XSL-FO (manual process)
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='page'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='page'>
<fo:flow flow-name='xsl-region-body'>
<fo:block>Hello World</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("output.pdf", FileMode.Create));
}
}
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;
class Program
{
static void Main()
{
// fo.net requires XSL-FO format, not HTML
// First convert HTML to XSL-FO (manual process)
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='page'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='page'>
<fo:flow flow-name='xsl-region-body'>
<fo:block>Hello World</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("output.pdf", FileMode.Create));
}
}
Imports Fonet
Imports Fonet.Render.Pdf
Imports System.IO
Imports System.Xml
Module Program
Sub Main()
' fo.net requires XSL-FO format, not HTML
' First convert HTML to XSL-FO (manual process)
Dim xslFo As String = "<?xml version='1.0' encoding='utf-8'?>" & _
"<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>" & _
"<fo:layout-master-set>" & _
"<fo:simple-page-master master-name='page'>" & _
"<fo:region-body/>" & _
"</fo:simple-page-master>" & _
"</fo:layout-master-set>" & _
"<fo:page-sequence master-reference='page'>" & _
"<fo:flow flow-name='xsl-region-body'>" & _
"<fo:block>Hello World</fo:block>" & _
"</fo:flow>" & _
"</fo:page-sequence>" & _
"</fo:root>"
Dim driver As FonetDriver = FonetDriver.Make()
driver.Render(New StringReader(xslFo),
New FileStream("output.pdf", FileMode.Create))
End Sub
End Module
翻訳後(HTML付きIronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<h1>Hello World</h1><p>This is HTML content.</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string html = "<h1>Hello World</h1><p>This is HTML content.</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html As String = "<h1>Hello World</h1><p>This is HTML content.</p>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDFのアプローチは25行以上のXSL-FOマークアップをわずか4行のクリーンなC#コードに削減します。 HTMLからPDFへのオプションについては、IronPDF HTML to PDF documentationをご覧ください。
例2: カスタム設定のPDF
ビフォア(XSL-FO付きfo.net):
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
class Program
{
static void Main()
{
// fo.net settings are configured in XSL-FO markup
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='A4'
page-height='297mm' page-width='210mm'
margin-top='20mm' margin-bottom='20mm'
margin-left='25mm' margin-right='25mm'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='A4'>
<fo:flow flow-name='xsl-region-body'>
<fo:block font-size='14pt'>Custom PDF</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("custom.pdf", FileMode.Create));
}
}
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
class Program
{
static void Main()
{
// fo.net settings are configured in XSL-FO markup
string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
<fo:layout-master-set>
<fo:simple-page-master master-name='A4'
page-height='297mm' page-width='210mm'
margin-top='20mm' margin-bottom='20mm'
margin-left='25mm' margin-right='25mm'>
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference='A4'>
<fo:flow flow-name='xsl-region-body'>
<fo:block font-size='14pt'>Custom PDF</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>";
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("custom.pdf", FileMode.Create));
}
}
Imports Fonet
Imports Fonet.Render.Pdf
Imports System.IO
Class Program
Shared Sub Main()
' fo.net settings are configured in XSL-FO markup
Dim xslFo As String = "<?xml version='1.0' encoding='utf-8'?>" & _
"<fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>" & _
"<fo:layout-master-set>" & _
"<fo:simple-page-master master-name='A4' " & _
"page-height='297mm' page-width='210mm' " & _
"margin-top='20mm' margin-bottom='20mm' " & _
"margin-left='25mm' margin-right='25mm'>" & _
"<fo:region-body/>" & _
"</fo:simple-page-master>" & _
"</fo:layout-master-set>" & _
"<fo:page-sequence master-reference='A4'>" & _
"<fo:flow flow-name='xsl-region-body'>" & _
"<fo:block font-size='14pt'>Custom PDF</fo:block>" & _
"</fo:flow>" & _
"</fo:page-sequence>" & _
"</fo:root>"
Dim driver As FonetDriver = FonetDriver.Make()
driver.Render(New StringReader(xslFo),
New FileStream("custom.pdf", FileMode.Create))
End Sub
End Class
翻訳後(HTML付きIronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 25;
renderer.RenderingOptions.MarginRight = 25;
string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 25;
renderer.RenderingOptions.MarginRight = 25;
string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom.pdf");
}
}
Imports IronPdf
Imports IronPdf.Engines.Chrome
Class Program
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 25
renderer.RenderingOptions.MarginRight = 25
Dim html As String = "<h1 style='font-size:14pt'>Custom PDF</h1>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("custom.pdf")
End Sub
End Class
IronPDFはXMLマークアップに設定を埋め込む代わりに、プログラムによるレンダリングオプションを提供します。
例3: URLからPDFへ
Before(fo.netはサポートされていません):。
// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;
class Program
{
static void Main()
{
// fo.net does not support URL rendering directly
// Must manually download, convert HTML to XSL-FO, then render
string url = "https://example.com";
string html = new WebClient().DownloadString(url);
// Manual conversion from HTML to XSL-FO required (complex)
string xslFo = ConvertHtmlToXslFo(html); // Not built-in
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("webpage.pdf", FileMode.Create));
}
static string ConvertHtmlToXslFo(string html)
{
// Custom implementation required - extremely complex
throw new System.NotImplementedException();
}
}
// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;
class Program
{
static void Main()
{
// fo.net does not support URL rendering directly
// Must manually download, convert HTML to XSL-FO, then render
string url = "https://example.com";
string html = new WebClient().DownloadString(url);
// Manual conversion from HTML to XSL-FO required (complex)
string xslFo = ConvertHtmlToXslFo(html); // Not built-in
FonetDriver driver = FonetDriver.Make();
driver.Render(new StringReader(xslFo),
new FileStream("webpage.pdf", FileMode.Create));
}
static string ConvertHtmlToXslFo(string html)
{
// Custom implementation required - extremely complex
throw new System.NotImplementedException();
}
}
Imports Fonet
Imports System.IO
Imports System.Net
Class Program
Shared Sub Main()
' fo.net does not support URL rendering directly
' Must manually download, convert HTML to XSL-FO, then render
Dim url As String = "https://example.com"
Dim html As String = New WebClient().DownloadString(url)
' Manual conversion from HTML to XSL-FO required (complex)
Dim xslFo As String = ConvertHtmlToXslFo(html) ' Not built-in
Dim driver As FonetDriver = FonetDriver.Make()
driver.Render(New StringReader(xslFo),
New FileStream("webpage.pdf", FileMode.Create))
End Sub
Shared Function ConvertHtmlToXslFo(html As String) As String
' Custom implementation required - extremely complex
Throw New System.NotImplementedException()
End Function
End Class
翻訳後(IronPDF - 組み込みサポート):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
URLからPDFへのレンダリングは、このfo.net移行での実用的な成果の一つです。IronPDFはJavaScript実行でネイティブにそれを処理します。 URLからPDFへの変換の詳細については、こちらをご覧ください。
例4: ヘッダーとフッター
ビフォア(XSL-FO付きfo.net):
<fo:static-content flow-name="xsl-region-before">
<fo:block text-align="center" font-size="10pt">
Company Name - Confidential
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="right" font-size="10pt">
Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-before">
<fo:block text-align="center" font-size="10pt">
Company Name - Confidential
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="right" font-size="10pt">
Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
</fo:block>
</fo:static-content>
翻訳後(IronPDF):。
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
HtmlFragment = "<div style='text-align:center; font-size:10pt;'>Company Name - Confidential</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
HtmlFragment = "<div style='text-align:right; font-size:10pt;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
HtmlFragment = "<div style='text-align:center; font-size:10pt;'>Company Name - Confidential</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
HtmlFragment = "<div style='text-align:right; font-size:10pt;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
Imports System
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter() With {
.HtmlFragment = "<div style='text-align:center; font-size:10pt;'>Company Name - Confidential</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter() With {
.HtmlFragment = "<div style='text-align:right; font-size:10pt;'>Page {page} of {total-pages}</div>",
.DrawDividerLine = True
}
IronPDFは複雑なXSL-FO領域定義をシンプルなHTMLヘッダーとフッターに置き換えます。
例5: PDFセキュリティ
ビフォア(fo.net):
// fo.net has very limited PDF security options
// Must use post-processing with another library
// fo.net has very limited PDF security options
// Must use post-processing with another library
' fo.net has very limited PDF security options
' Must use post-processing with another library
翻訳後(IronPDF):。
using IronPdf;
public byte[] GenerateSecurePdf(string html)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Set metadata
pdf.MetaData.Title = "Confidential Report";
pdf.MetaData.Author = "Company Name";
// Password protection
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user456";
// Restrict permissions
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserEdits = IronPdf.Security.PdfEditSecurity.NoEdit;
return pdf.BinaryData;
}
using IronPdf;
public byte[] GenerateSecurePdf(string html)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Set metadata
pdf.MetaData.Title = "Confidential Report";
pdf.MetaData.Author = "Company Name";
// Password protection
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user456";
// Restrict permissions
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserEdits = IronPdf.Security.PdfEditSecurity.NoEdit;
return pdf.BinaryData;
}
Imports IronPdf
Public Function GenerateSecurePdf(html As String) As Byte()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
' Set metadata
pdf.MetaData.Title = "Confidential Report"
pdf.MetaData.Author = "Company Name"
' Password protection
pdf.SecuritySettings.OwnerPassword = "owner123"
pdf.SecuritySettings.UserPassword = "user456"
' Restrict permissions
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserPrinting = IronPdf.Security.PdfPrintSecurity.NoPrint
pdf.SecuritySettings.AllowUserEdits = IronPdf.Security.PdfEditSecurity.NoEdit
Return pdf.BinaryData
End Function
パフォーマンスの考慮事項
ChromePdfRendererを再利用してください
fo.net移行時の最適なパフォーマンスのために、ChromePdfRendererインスタンスを再利用してください:
// GOOD - Reuse the renderer
public class PdfService
{
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}
// BAD - Creating new instance each time
public byte[] GenerateBad(string html)
{
var renderer = new ChromePdfRenderer(); // Wasteful
return renderer.RenderHtmlAsPdf(html).BinaryData;
}
// GOOD - Reuse the renderer
public class PdfService
{
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] Generate(string html) => _renderer.RenderHtmlAsPdf(html).BinaryData;
}
// BAD - Creating new instance each time
public byte[] GenerateBad(string html)
{
var renderer = new ChromePdfRenderer(); // Wasteful
return renderer.RenderHtmlAsPdf(html).BinaryData;
}
Imports System
' GOOD - Reuse the renderer
Public Class PdfService
Private Shared ReadOnly _renderer As New ChromePdfRenderer()
Public Function Generate(html As String) As Byte()
Return _renderer.RenderHtmlAsPdf(html).BinaryData
End Function
End Class
' BAD - Creating new instance each time
Public Function GenerateBad(html As String) As Byte()
Dim renderer As New ChromePdfRenderer() ' Wasteful
Return renderer.RenderHtmlAsPdf(html).BinaryData
End Function
ユニット変換ヘルパー
fo.net XSL-FOはさまざまな単位を使用します。 IronPDFは余白にミリメートルを使用しています。 ヘルパークラスはこちらです:
public static class UnitConverter
{
public static double InchesToMm(double inches) => inches * 25.4;
public static double PointsToMm(double points) => points * 0.352778;
public static double PicasToMm(double picas) => picas * 4.233;
public static double CmToMm(double cm) => cm * 10;
}
// Usage
renderer.RenderingOptions.MarginTop = UnitConverter.InchesToMm(1); // 1 inch
public static class UnitConverter
{
public static double InchesToMm(double inches) => inches * 25.4;
public static double PointsToMm(double points) => points * 0.352778;
public static double PicasToMm(double picas) => picas * 4.233;
public static double CmToMm(double cm) => cm * 10;
}
// Usage
renderer.RenderingOptions.MarginTop = UnitConverter.InchesToMm(1); // 1 inch
Public Module UnitConverter
Public Function InchesToMm(inches As Double) As Double
Return inches * 25.4
End Function
Public Function PointsToMm(points As Double) As Double
Return points * 0.352778
End Function
Public Function PicasToMm(picas As Double) As Double
Return picas * 4.233
End Function
Public Function CmToMm(cm As Double) As Double
Return cm * 10
End Function
End Module
' Usage
renderer.RenderingOptions.MarginTop = UnitConverter.InchesToMm(1) ' 1 inch
トラブルシューティング
課題1:ページサイズの違い
問題: fo .NET移行後、PDF ページ サイズが異なって見えます。
解決策: XSL-FO ページのサイズを正しくマップします。
// XSL-FO: page-height='11in' page-width='8.5in' (Letter)
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// XSL-FO: page-height='297mm' page-width='210mm' (A4)
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Custom size (in mm)
renderer.RenderingOptions.SetCustomPaperSize(210, 297);
// XSL-FO: page-height='11in' page-width='8.5in' (Letter)
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// XSL-FO: page-height='297mm' page-width='210mm' (A4)
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Custom size (in mm)
renderer.RenderingOptions.SetCustomPaperSize(210, 297);
' XSL-FO: page-height='11in' page-width='8.5in' (Letter)
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
' XSL-FO: page-height='297mm' page-width='210mm' (A4)
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
' Custom size (in mm)
renderer.RenderingOptions.SetCustomPaperSize(210, 297)
課題2:fo:blockからHTMLへのマッピング
問題: <fo:block> が何になるべきかわからない。
解決策:適切なセマンティック HTML を使用します。
- 見出し:
<h1>から<h6> - 段落:
<p> - 一般的なコンテナ:
<div> - インラインテキスト:
<span>
問題3:フォントが一致しない
問題:フォントが fo .NET出力と異なって見えます。
解決策: Web フォントを使用するか、CSS でシステム フォントを指定します。
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', Arial, sans-serif; }
</style>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', Arial, sans-serif; }
</style>
課題4:ページ番号が機能しない
問題: <fo:page-number/> が動作しない。
解決策:ヘッダー/フッターにIronPDFプレースホルダーを使用します。
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
HtmlFragment = "<div style='text-align:center;'>Page {page} of {total-pages}</div>",
MaxHeight = 15 // mm
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
{
HtmlFragment = "<div style='text-align:center;'>Page {page} of {total-pages}</div>",
MaxHeight = 15 // mm
};
Imports System
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter() With {
.HtmlFragment = "<div style='text-align:center;'>Page {page} of {total-pages}</div>",
.MaxHeight = 15 ' mm
}
移行チェックリスト
移行前
- すべてのXSL-FOテンプレートファイルをカタログ化する(
.xslfo) - 文書ページの寸法と使用される余白
- ヘッダー/フッターの設定を記録する(
fo:static-content) - 表の構造とスタイルを識別する
- バージョン管理にプロジェクトをバックアップする
- IronPDFライセンスキーを取得する
パッケージの移行
FonetまたはFO.NETパッケージを削除する:dotnet remove package FonetIronPdfパッケージをインストールする:dotnet add package IronPdf- 名前空間のインポートを
IronPdfに更新する - 起動時にIronPDFライセンスキーを設定する
コードの移行
FonetDriver.Make()をnew ChromePdfRenderer()に置き換えるdriver.Render()をrenderer.RenderHtmlAsPdf()に置き換える- ファイル出力をストリームから
pdf.SaveAs()に更新する - エラーイベントハンドラをtry/catchに置き換える
fo:static-contentをHtmlHeaderFooterに変換する<fo:page-number/>を{page}プレースホルダーに置き換える
テスティング
- 出力の外観を元の fo .NET PDF と比較する
- ページのサイズと余白を確認する
- ヘッダーとフッターを確認する
- ページ番号を検証する
- テストテーブルのレンダリング
- 画像の読み込みを確認する
移行後
.foおよび.xslfoテンプレートファイルを削除する- fo.net関連のコードとユーティリティを削除する
- ドキュメントの更新
上記で使用されたIronPDFの表面についてより深く知るには、IronPDF APIリファレンスを参照してください。

