フッターコンテンツにスキップ
ビデオ

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ライセンスですが、現在の開発にはいくつかの制限があります。

  1. 旧式技術: XSL-FO (拡張スタイルシート言語フォーマットオブジェクト) は2001年のW3C規格です; W3Cは2013年にXSL-FOワーキンググループを閉じ、言語にはこれ以上の開発はありませんでした。

  2. 複雑な学習曲線: XSL-FOは、特化されたフォーマットオブジェクト(fo:page-sequence など)を用いた詳細なXMLベースのマークアップを必要とします。

  3. HTML/CSSのサポートなし: fo.netはHTMLやCSSをレンダリングできません—HTMLをXSL-FOに変換する必要があります(通常はXSLTを使用)。

  4. 放棄/非メンテナンス: 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)は休止状態です。

  5. 実際にはWindows専用: レガシーSystem.Drawing(GDI+)APIに依存しており、実質的にWindowsに限定されます。

  6. 近代的機能の制限: JavaScriptエンジンなし、CSS3(flexbox/grid)なし、近代的なウェブフォントのロードなし。

  7. 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を作成できます。


始める前に

前提条件

  1. .NET環境: IronPDFは.NET Framework 4.6.2以降、 .NET Core 3.1以降、 .NET 5/6/7/8/9以降をサポートしています。
  2. 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"
SHELL

すべての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*"
SHELL

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
SHELL

ステップ 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
$vbLabelText   $csharpLabel

ステップ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"
$vbLabelText   $csharpLabel

ステップ 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")
$vbLabelText   $csharpLabel

完全な 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
$vbLabelText   $csharpLabel

翻訳後(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
$vbLabelText   $csharpLabel

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

翻訳後(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
$vbLabelText   $csharpLabel

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

翻訳後(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
$vbLabelText   $csharpLabel

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>
XML

翻訳後(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
}
$vbLabelText   $csharpLabel

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

翻訳後(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
$vbLabelText   $csharpLabel

パフォーマンスの考慮事項

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

ユニット変換ヘルパー

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

トラブルシューティング

課題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)
$vbLabelText   $csharpLabel

課題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>
HTML

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

移行チェックリスト

移行前

  • すべてのXSL-FOテンプレートファイルをカタログ化する(.xslfo
  • 文書ページの寸法と使用される余白
  • ヘッダー/フッターの設定を記録する(fo:static-content
  • 表の構造とスタイルを識別する
  • バージョン管理にプロジェクトをバックアップする
  • IronPDFライセンスキーを取得する

パッケージの移行

  • Fonet または FO.NET パッケージを削除する: dotnet remove package Fonet
  • IronPdf パッケージをインストールする: dotnet add package IronPdf
  • 名前空間のインポートをIronPdfに更新する
  • 起動時にIronPDFライセンスキーを設定する

コードの移行

  • FonetDriver.Make()new ChromePdfRenderer() に置き換える
  • driver.Render()renderer.RenderHtmlAsPdf() に置き換える
  • ファイル出力をストリームからpdf.SaveAs()に更新する
  • エラーイベントハンドラをtry/catchに置き換える
  • fo:static-contentHtmlHeaderFooter に変換する
  • <fo:page-number/>{page} プレースホルダーに置き換える

テスティング

  • 出力の外観を元の fo .NET PDF と比較する
  • ページのサイズと余白を確認する
  • ヘッダーとフッターを確認する
  • ページ番号を検証する
  • テストテーブルのレンダリング
  • 画像の読み込みを確認する

移行後

  • .fo および .xslfo テンプレートファイルを削除する
  • fo.net関連のコードとユーティリティを削除する
  • ドキュメントの更新

上記で使用されたIronPDFの表面についてより深く知るには、IronPDF APIリファレンスを参照してください。

ご注意FO.NET, Fonet, および Apache FOP はそれぞれの所有者の商標です。 このサイトは、FO.NETプロジェクトまたはApache Software Foundationと提携していない、承認されていない、またはスポンサーされていない。 すべての製品名、ロゴ、およびブランドは各所有者の所有物です。 比較は情報提供のみを目的としており、執筆時点で公開されている情報を反映しています。

Curtis Chau
テクニカルライター

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

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

アイアンサポートチーム

私たちは週5日、24時間オンラインで対応しています。
チャット
メール
電話してね