IRONSOFTWAREHOME
FILMY

Jak korzystać z niestandardowego logowania w języku C#

Curtis Chau
Curtis Chau
Updated: 19 lipca 2026

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:

  1. 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.

  2. Kompleksowa krzywa uczenia: XSL-FO wymaga skomplikowanego znaczników opartego na XML z wyspecjalizowanymi obiektami formatowania (fo:block, fo:table, fo:page-sequence, itp.).

  3. 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).

  4. Porzucone/Nieutrzymywane: Pakiet Fonet na nuget.org został ostatnio opublikowany w kwietniu 2011 roku (v1.0.0, .NET Framework 2.0). Społeczność forkująca Fonet.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.

  5. Praktycznie tylko dla Windows: Starsza wersja Fonet zależy od API System.Drawing (GDI+), co efektywnie ogranicza go do Windows.

  6. Ograniczone nowoczesne funkcje: Brak silnika JavaScript, brak CSS3 (flexbox/grid), brak nowoczesnego ładowania czcionek webowych.

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

Aspektfo.net (FO.NET)IronPDF
Format danych wejściowychXSL-FO (przestarzały XML)HTML/CSS (nowoczesne standardy internetowe)
Krzywa uczenia sięSteep (doświadczenie w zakresie XSL-FO)Łagodny (znajomość HTML/CSS)
KonserwacjaPorzucony (ostatnie wydanie maj 2020)Aktywnie utrzymywane
Obsługa platformTylko dla systemu WindowsCross-platform (.NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+)
Obsługa CSSNonePełna obsługa CSS3 (Flexbox, Grid)
JavaScriptNonePełna obsługaJavaScript
Renderowanie adresów URLNieobsługiwaneWbudowane
Nowoczesne funkcjeOgraniczoneNagłówki, stopki, znaki wodne, zabezpieczenia
DokumentacjaNieaktualneSzczegół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

  1. **Środowisko .NET:**IronPDF obsługuje .NET Framework 4.6.2+, .NET Core 3.1+, .NET 5/6/7/8/9+
  2. Dostęp do NuGet: Upewnij się, że możesz instalować pakiety z NuGet
  3. 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"
SHELL

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*"
SHELL

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
SHELL

Krok 2: Aktualizacja przestrzeni nazw

// Before (fo.net)
using Fonet;
using Fonet.Render.Pdf;
using System.Xml;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;

Krok 3: Zainicjuj IronPDF

// 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");

Kompletna dokumentacija API

Mapowanie przestrzeni nazw

fo.net Przestrzeń nazwOdpowiednik IronPDF
FonetIronPdf
Fonet.Render.PdfIronPdf
Fonet.LayoutNie dotyczy
Fonet.FoNie dotyczy
Fonet.ImageIronPdf

FonetDriver do ChromePdfRenderer

Metoda FonetDriverOdpowiednik IronPDF
FonetDriver.Make()new ChromePdfRenderer()
driver.Render(inputStream, outputStream)renderer.RenderHtmlAsPdf(html)
driver.Render(inputFile, outputStream)renderer.RenderHtmlFileAsPdf(path)
driver.BaseDirectoryRenderingOptions.BaseUrl
driver.OnError += handlerTry/catch wokół renderowania

RenderingOptions (konfiguracja PDF)

fo.net (atrybuty XSL-FO)IronPDF RenderingOptions
page-heightPaperSize lub SetCustomPaperSize()
page-widthPaperSize
margin-topMarginTop
margin-bottomMarginBottom
margin-leftMarginLeft
margin-rightMarginRight
reference-orientationPaperOrientation

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-FOOdpowiednik 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-FOOdpowiednik CSSPrzykład
font-familyfont-familyTa sama składnia
font-sizefont-sizeTa sama składnia
font-weightfont-weightbold, normal, 700
text-aligntext-alignleft, center, right, justify
colorcolorHex, RGB, nazwy
background-colorbackground-colorTa sama składnia
space-beforemargin-topPrzed elementem
space-aftermargin-bottomPo elemencie
start-indentmargin-leftWcięcie po lewej stronie
keep-togetherpage-break-inside: avoidZapobieganie podziałom
break-before="page"page-break-before: alwaysWymuś 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));
    }
}

Po (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");
    }
}

Podejś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));
    }
}

Po (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");
    }
}

IronPDF 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();
    }
}

Po (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");
    }
}

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

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
};

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

Po (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;
}

Kwestie 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;
}

Pomocnik 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 inch

Rozwią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);

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

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
};

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 Fonet lub FO.NET: dotnet remove package Fonet
  • Zainstaluj pakiet IronPdf: dotnet add package IronPdf
  • Zaktualizuj importy nazw przestrzeni od Fonet do IronPdf
  • Ustaw klucz licencyjny IronPDF podczas uruchamiania

Migracja kodu

  • Zastąp FonetDriver.Make() przez new ChromePdfRenderer()
  • Zastąp driver.Render() przez renderer.RenderHtmlAsPdf()
  • Zaktualizuj wyjście pliku z strumieni na pdf.SaveAs()
  • Zastąp procedury obsługi błędów konstrukcją try/catch
  • Konwertuj fo:static-content na HtmlHeaderFooter
  • 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 .fo i .xslfo
  • Usuń kod i narzędzia związane z fo.net
  • Aktualizacja dokumentacji

Dla głębszego pokrycia wykorzystanego interfejsu IronPDF, zobacz Dokumentacja API IronPDF.

Zwróć uwagę: FO.NET, Fonet i Apache FOP są znakami towarowymi odpowiednich właścicieli. Ta strona nie jest powiązana, wspierana ani sponsorowana przez projekt FO.NET lub Apache Software Foundation. Wszystkie nazwy produktów, logo i marki są własnością ich odpowiednich właścicieli. Porównania mają charakter wyłącznie informacyjny i odzwierciedlają informacje dostępne publicznie w momencie pisania.
Curtis Chau
Autor tekstów technicznych

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.

...
Czytaj więcej

Powiązane artykuły

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Zarezerwuj swoje darmowe Demo na żywo
Booking Badge

Zaufane przez miliony inżynierów na całym świecie

Logotypy klientów Iron Software
Otrzymaj swoje Konsultacja Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta