Jak korzystać z niestandardowego logowania w języku C#
Przejście zfo.net (FO.NET)na IronPDF to znacząca aktualizacja procesu generowania plików PDF w środowisku .NET. Ten przewodnik oferuje prostą, krok po kroku ścieżkę przejścia z przestarzałego znacznika XSL-FO na nowoczesne generowanie plików PDF oparte na HTML/CSS, wykorzystując umiejętności, które Twój zespół programistów już posiada.
Dlaczego warto przejść z fo.net na IronPDF
Wyzwania związane z fo.net
fo.net (FO.NET) jest portem C# wczesnej wersji Apache FOP, który konwertuje dokumenty XSL-FO na PDF. Jest licencjonowany na zasadach Apache 2.0, ale ma kilka ograniczeń dla bieżącego rozwoju:
-
Technologia przestarzała: XSL-FO (extensible Stylesheet Language Formatting Objects) jest specyfikacją W3C z 2001 roku; W3C zamknęło Grupę Roboczą XSL-FO w 2013 roku, a język nie ma dalszego rozwoju.
-
Kompleksowa krzywa uczenia: XSL-FO wymaga skomplikowanego znaczników opartego na XML z wyspecjalizowanymi obiektami formatowania (
fo:block,fo:table,fo:page-sequence, itp.). -
Brak wsparcia HTML/CSS: fo.net nie może przekładać HTML ani CSS — musisz sam przetransformować HTML na XSL-FO (zwykle za pomocą XSLT).
-
Porzucone/Nieutrzymywane: Pakiet
Fonetna nuget.org został ostatnio opublikowany w kwietniu 2011 roku (v1.0.0, .NET Framework 2.0). Społeczność forkującaFonet.Standard(.NET Standard 2.0) została ostatnio opublikowana w maju 2020 roku (v1.0.5). Repozytorium CodePlex jest nieaktywne, a forki na GitHub (prepare/FO.NET,nholik/FO.Net,hahmed/Fo.Net) są uśpione. -
Praktycznie tylko dla Windows: Starsza wersja
Fonetzależy od APISystem.Drawing(GDI+), co efektywnie ogranicza go do Windows. -
Ograniczone nowoczesne funkcje: Brak silnika JavaScript, brak CSS3 (flexbox/grid), brak nowoczesnego ładowania czcionek webowych.
-
Brak renderowania adresów URL: fo.net nie może bezpośrednio renderować stron internetowych — wymaga ręcznej konwersji HTML do XSL-FO.
Porównanie fo.net i IronPDF
| Aspekt | fo.net (FO.NET) | IronPDF |
|---|---|---|
| Format danych wejściowych | XSL-FO (przestarzały XML) | HTML/CSS (nowoczesne standardy internetowe) |
| Krzywa uczenia się | Steep (doświadczenie w zakresie XSL-FO) | Łagodny (znajomość HTML/CSS) |
| Konserwacja | Porzucony (ostatnie wydanie maj 2020) | Aktywnie utrzymywane |
| Obsługa platform | Tylko dla systemu Windows | Cross-platform (.NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+) |
| Obsługa CSS | None | Pełna obsługa CSS3 (Flexbox, Grid) |
| JavaScript | None | Pełna obsługaJavaScript |
| Renderowanie adresów URL | Nieobsługiwane | Wbudowane |
| Nowoczesne funkcje | Ograniczone | Nagłówki, stopki, znaki wodne, zabezpieczenia |
| Dokumentacja | Nieaktualne | Szczegółowe samouczki |
Dlaczego zmiana ma sens
fo.net został zaprojektowany w czasie, gdy oczekiwano, że XSL-FO stanie się standardem formatowania dokumentów. To oczekiwanie nigdy się nie spełniło. HTML/CSS stały się uniwersalnym formatem dokumentu, podczas gdy XSL-FO pozostało umiejętnością niszową — większość zasobów XSL-FO pochodzi z lat 2005–2010, co utrudnia coraz bardziej utrzymanie.
IronPDF pozwala użyć umiejętności, które już posiadasz, do tworzenia profesjonalnych plików PDF na nowoczesnym .NET.
Zanim zaczniesz
Wymagania wstępne
- **Środowisko .NET:**IronPDF obsługuje .NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+
- Dostęp do NuGet: Upewnij się, że możesz instalować pakiety z NuGet
- Klucz licencyjny: Uzyskaj klucz licencyjny IronPDF do użytku produkcyjnego na stronie ironpdf.com
Utwórz kopię zapasową projektu
# Create a backup branch
git checkout -b pre-ironpdf-migration
git add .
git commit -m "Backup before fo.net to IronPDF migration"
Zidentyfikuj wszystkie wystąpienia "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*"
Dokumentuj swoje szablony XSL-FO
Przed migracją należy skatalogować wszystkie pliki XSL-FO i odnotować:
- Wymiary strony i marginesy
- Użyte czcionki
- Tabele i ich struktury
- Nagłówki i stopki (
fo:static-content) - Schematy numeracji stron
- Odnośniki do obrazów
Szybki start – migracja
Krok 1: Zaktualizuj pakiety NuGet
# Remove fo.net package
dotnet remove package Fonet
dotnet remove package FO.NET
# Install IronPDF
dotnet add package IronPdf
Krok 2: Aktualizacja przestrzeni nazw
// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;
// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;Imports IronPdf
Imports IronPdf.RenderingKrok 3: Zainicjuj 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"Krok 4: Podstawowy wzorzec konwersji
// 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")Kompletna dokumentacija API
Mapowanie przestrzeni nazw
| fo.net Przestrzeń nazw | Odpowiednik IronPDF |
|---|---|
Fonet | IronPdf |
Fonet.Render.Pdf | IronPdf |
Fonet.Layout | Nie dotyczy |
Fonet.Fo | Nie dotyczy |
Fonet.Image | IronPdf |
FonetDriver do ChromePdfRenderer
| Metoda FonetDriver | Odpowiednik 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 | Try/catch wokół renderowania |
RenderingOptions (konfiguracja PDF)
| fo.net (atrybuty XSL-FO) | IronPDF RenderingOptions |
|---|---|
page-height | PaperSize lub SetCustomPaperSize() |
page-width | PaperSize |
margin-top | MarginTop |
margin-bottom | MarginBottom |
margin-left | MarginLeft |
margin-right | MarginRight |
reference-orientation | PaperOrientation |
Przewodnik po konwersji z XSL-FO do HTML
Elementy XSL-FO do HTML/CSS
Podstawową zmianą w tej migracji z fo.net jest konwersja elementów XSL-FO na ich odpowiedniki w HTML:
| Element XSL-FO | Odpowiednik HTML/CSS |
|---|---|
<fo:root> | <html> |
<fo:layout-master-set> | Reguła CSS @page |
<fo:simple-page-master> | CSS @page |
<fo:page-sequence> | <body> lub <div> |
<fo:flow> | <main> lub <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> | Symbol zastępczy {page} |
<fo:page-number-citation> | {total-pages} |
<fo:basic-link> | <a href> |
Właściwości XSL-FO do CSS
| Właściwość XSL-FO | Odpowiednik CSS | Przykład |
|---|---|---|
font-family | font-family | Ta sama składnia |
font-size | font-size | Ta sama składnia |
font-weight | font-weight | bold, normal, 700 |
text-align | text-align | left, center, right, justify |
color | color | Hex, RGB, nazwy |
background-color | background-color | Ta sama składnia |
space-before | margin-top | Przed elementem |
space-after | margin-bottom | Po elemencie |
start-indent | margin-left | Wcięcie po lewej stronie |
keep-together | page-break-inside: avoid | Zapobieganie podziałom |
break-before="page" | page-break-before: always | Wymuś podział strony |
Przykłady kodu
Przykład 1: Podstawowy HTML do PDF
Przed (fo.net z XSL-FO):
// 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
Imports Fonet
Imports Fonet.Render.Pdf
Imports System.IO
Imports System.Xml
Class Program
Shared 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 ClassPo (IronPDF z HTML):
// 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 ClassPodejście IronPDF pozwala zredukować ponad 25 wierszy znaczników XSL-FO do zaledwie 4 wierszy przejrzystego kodu C#. Aby uzyskać więcej informacji na temat opcji konwersji HTML do PDF, zapoznaj się z dokumentacją IronPDF HTML to PDF.
Przykład 2: Plik PDF z ustawieniami niestandardowymi
Przed (fo.net z XSL-FO):
// 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
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 ClassPo (IronPDF z HTML):
// 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
Imports IronPdf
Imports IronPdf.Engines.Chrome
Module Program
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 ModuleIronPDF zapewnia opcje renderowania programowego zamiast osadzania konfiguracji w znacznikach XML.
Przykład 3: URL do PDF
Przed (fo.net – nieobsługiwane):
// 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
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 ClassPo (IronPDF – wbudowana obsługa):
// 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 ClassRenderowanie URL to PDF to jedno z praktycznych zysków podczas tej migracji z fo.net:IronPDF obsługuje to natywnie przy wykonywaniu JavaScript. Dowiedz się więcej o konwersji adresów URL do formatu PDF.
Przykład 4: Nagłówki i stopki
Przed (fo.net z XSL-FO):
<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>
Po (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
};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 zastępuje złożone definicje regionów XSL-FO prostymi nagłówkami i stopkami HTML.
Przykład 5: Zabezpieczenia plików PDF
Przed (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 libraryPo (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;
}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 FunctionKwestie związane z wydajnością
Ponowne użycie ChromePdfRenderer
Aby uzyskać optymalną wydajność podczas migracji fo.net, ponownie użyj instancji 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;
}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 FunctionPomocnik do przeliczania jednostek
fo.net XSL-FO wykorzystuje różne jednostki.IronPDF stosuje milimetry jako jednostkę pomiaru marginesów. Oto klasa pomocnicza:
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 inchPublic 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 inchRozwiązywanie problemów
Problem 1: Różnice w rozmiarze stron
Problem: Rozmiar strony PDF wygląda inaczej po migracji do fo.net.
Rozwiązanie: Prawidłowe odwzorowanie wymiarów strony 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)Problem 2: Mapowanie fo:block na HTML
Problem: Nie jest jasne, czym powinno stać się <fo:block>.
Rozwiązanie: Należy używać odpowiedniego semantycznego kodu HTML:
- Nagłówki:
<h1>przez<h6> - Akapity:
<p> - Ogólne kontenery:
<div> - Tekst w linii:
<span>
Problem 3: Niedopasowanie czcionek
Problem: Czcionki wyglądają inaczej niż w wydruku serwisu fo.net.
Rozwiązanie: Użyj czcionek internetowych lub określ czcionki systemowe w CSS:
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', Arial, sans-serif; }
</style>
Problem 4: Numery stron nie działają
Problem: <fo:page-number/> nie działa.
Rozwiązanie: Użyj symboli zastępczych IronPDF w nagłówkach/stopkach:
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
}Lista kontrolna migracji
Przed migracją
- Sporządź katalog wszystkich plików szablonów XSL-FO (
.fo,.xslfo) - Wymiary stron dokumentu i zastosowane marginesy
- Zanotuj konfiguracje nagłówków/stopek (
fo:static-content) - Rozpoznaj struktury tabel i stylizację
- Utwórz kopię zapasową projektu w systemie kontroli wersji
- Uzyskaj klucz licencyjny IronPDF
Migracja pakietów
- Usuń pakiet
FonetlubFO.NET:dotnet remove package Fonet - Zainstaluj pakiet
IronPdf:dotnet add package IronPdf - Zaktualizuj importy nazw przestrzeni od
FonetdoIronPdf - Ustaw klucz licencyjny IronPDF podczas uruchamiania
Migracja kodu
- Zastąp
FonetDriver.Make()przeznew ChromePdfRenderer() - Zastąp
driver.Render()przezrenderer.RenderHtmlAsPdf() - Zaktualizuj wyjście pliku z strumieni na
pdf.SaveAs() - Zastąp procedury obsługi błędów konstrukcją try/catch
- Konwertuj
fo:static-contentnaHtmlHeaderFooter - Zastąp
<fo:page-number/>przez symbol zastępczy{page}
Testowanie
- Porównaj wygląd pliku wyjściowego z oryginalnymi plikami PDF serwisu fo.net
- Sprawdź wymiary strony i marginesy
- Sprawdź nagłówki i stopki
- Sprawdź numery stron
- Renderowanie tabeli testowej
- Sprawdź ładowanie obrazów
Po migracji
- Usuń pliki szablonów
.foi.xslfo - Usuń kod i narzędzia związane z fo.net
- Aktualizacja dokumentacji
Dla głębszego pokrycia wykorzystanego interfejsu IronPDF, zobacz Dokumentacja API IronPDF.

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podręczników.