Jak przeprowadzić migrację z Api2pdf do IronPDF w języku C#
Api2pdf oferuje usługę w chmurze do generowania plików PDF, ale wysyłanie poufnych dokumentów na serwery zewnętrzne może prowadzić do zagrożeń bezpieczeństwa, problemów z zgodnością z przepisami oraz stałych kosztów, które z czasem mogą się sumować. Niniejszy przewodnik zawiera szczegółową ścieżkę migracji z Api2pdf doIronPDF— natywnej biblioteki PDF dla platformy .NET, która przetwarza dokumenty całkowicie w ramach własnej infrastruktury, eliminując obawy związane z transmisją danych i zamieniając koszty poszczególnych konwersji na jednorazową inwestycję.
Dlaczego warto rozważyć odejście od Api2pdf?
Chociaż Api2pdf zapewnia wygodne generowanie plików PDF w chmurze, kilka czynników skłania zespoły programistów do poszukiwania lokalnych alternatyw dla swoich potrzeb w zakresie generowania plików PDF.
Kwestie bezpieczeństwa i zgodności
Api2pdf działa jako usługa w chmurze, w ramach której poufne pliki HTML i dokumenty są wysyłane do serwerów stron trzecich w celu przetworzenia. Stanowi to poważny problem dla organizacji zajmujących się danymi podlegającymi regulacjom.
| Ryzyko | Api2pdf | IronPDF |
|---|---|---|
| Transmisja danych | Wszystkie treści wysyłane na serwery zewnętrzne | Przetwarzanie lokalnie w Twojej infrastrukturze |
| Zgodność z RODO | Dane przekraczają granice jurysdykcji | Dane nigdy nie opuszczają Twojego środowiska |
| Zgodność z HIPAA | Dane medyczne przekazywane na zewnątrz | Dane medyczne pozostają w Państwa systemach |
| SOC 2 | Zależności od podmiotów zewnętrznych | Pełna kontrola nad przetwarzaniem danych |
| PCI DSS | Potencjalne ujawnienie danych kart | Brak transmisji zewnętrznej |
Kumulacja kosztów w czasie
Api2pdf pobiera opłatę w wysokości około 0,005 USD za konwersję bezterminowo, podczas gdyIronPDFoferuje jednorazową Licencję wieczystą. W przypadku aplikacji generujących znaczne ilości plików PDF różnica w kosztach staje się znaczna:
| Objętość | Api2pdf (roczna) | IronPDF(jednorazowe zlecenie) |
|---|---|---|
| 10 000 plików PDF miesięcznie | ~600 USD/rok | 749 USD (wersja Lite) |
| 50 000 plików PDF miesięcznie | ~3000 USD/rok | 749 USD (wersja Lite) |
| 100 000 plików PDF miesięcznie | ~6 000 USD/rok | 1499 USD (Plus) |
W przypadku większości aplikacji produkcyjnych inwestycja wIronPDFzwraca się w ciągu kilku miesięcy.
Wydajność i dostępność
Api2pdf wymaga komunikacji sieciowej, co powoduje opóźnienie wynoszące 2–5 sekund przy każdym żądaniu generowania pliku PDF.IronPDFprzetwarza dane lokalnie w ciągu 100–500 milisekund. PonadtoIronPDFdziała w pełni w trybie offline oraz w środowiskach odizolowanych — co ma kluczowe znaczenie dla aplikacji, które nie mogą polegać na dostępności usług zewnętrznych.
Api2pdf a IronPDF: kluczowe różnice
| Aspekt | Api2pdf | IronPDF |
|---|---|---|
| Obsługa danych | Wysłane do zewnętrznych serwerów w chmurze | Przetwarzane lokalnie w Twojej infrastrukturze |
| Ceny | Płatność za konwersję (~0,005 USD/PDF) | Jednorazowa Licencja wieczysta |
| Opóźnienie | 2–5 sekund (czas przesyłu w obie strony) | 100–500 ms (przetwarzanie lokalne) |
| Offline | Niedostępne | Działa całkowicie w trybie offline |
| Instalacja | Klucz API + klient HTTP | Prosty pakiet NuGet |
| Zgodność | Kwestie związane z RODO/HIPAA (dane opuszczają sieć) | Pełna kontrola zgodności |
Proces migracji krok po kroku
Krok 1: Zaktualizuj pakiety NuGet
Usuń pakiet Api2pdf i zainstaluj IronPDF:
# Remove Api2pdf
dotnet remove package Api2Pdf
# Install IronPDF
dotnet add package IronPdf
# Remove Api2pdf
dotnet remove package Api2Pdf
# Install IronPDF
dotnet add package IronPdf
Lub za pomocą konsoli menedżera pakietów:
Uninstall-Package Api2Pdf
Install-Package IronPdf
Krok 2: Aktualizacja odniesień do przestrzeni nazw
Zastąp przestrzenie nazw Api2pdf przez IronPDF:
// Remove these
using Api2Pdf;
using Api2Pdf.DotNet;
// Add these
using IronPdf;
using IronPdf.Rendering;
// Remove these
using Api2Pdf;
using Api2Pdf.DotNet;
// Add these
using IronPdf;
using IronPdf.Rendering;
Imports IronPdf
Imports IronPdf.Rendering
Krok 3: Skonfiguruj klucz licencyjny
Ustaw klucz licencyjnyIronPDFpodczas uruchamiania aplikacji:
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or configure via appsettings.json:
// { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or configure via appsettings.json:
// { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }
' Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"
' Or configure via appsettings.json:
' { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }
Krok 4: Usuń konfigurację klucza API
IronPDF działa lokalnie i nie wymaga kluczy API:
// Remove this Api2pdf pattern
var client = new Api2PdfClient("API_KEY");
// Just create the renderer directly
var renderer = new ChromePdfRenderer();
// Remove this Api2pdf pattern
var client = new Api2PdfClient("API_KEY");
// Just create the renderer directly
var renderer = new ChromePdfRenderer();
' Remove this Api2pdf pattern
Dim client = New Api2PdfClient("API_KEY")
' Just create the renderer directly
Dim renderer = New ChromePdfRenderer()
Kompletna dokumentacja API
Mapowanie klas podstawowych
| Klasa Api2pdf | OdpowiednikIronPDF |
|---|---|
Api2PdfClient |
ChromePdfRenderer |
Api2PdfResult |
PdfDocument |
HeadlessChromeOptions |
ChromePdfRenderOptions |
Mapowanie metod
| Metoda Api2pdf | MetodaIronPDF |
|---|---|
client.HeadlessChrome.FromHtmlAsync(html) |
renderer.RenderHtmlAsPdf(html) |
client.HeadlessChrome.FromUrlAsync(url) |
renderer.RenderUrlAsPdf(url) |
response.Pdf (URL) |
pdf.SaveAs(path) |
response.Pdf (pobierz) |
pdf.BinaryData |
client.PdfSharp.MergePdfsAsync(urls) |
PdfDocument.Merge(pdfs) |
client.PdfSharp.SetPasswordAsync(url, pwd) |
pdf.SecuritySettings.OwnerPassword |
Mapowanie opcji renderowania
| Opcja Api2pdf | OpcjaIronPDF |
|---|---|
Landscape = true |
RenderingOptions.PaperOrientation = Landscape |
PageSize = "A4" |
RenderingOptions.PaperSize = PdfPaperSize.A4 |
PrintBackground = true |
RenderingOptions.PrintHtmlBackgrounds = true |
MarginTop, itp. |
RenderingOptions.MarginTop itp. |
Delay = 5000 |
RenderingOptions.WaitFor.RenderDelay(5000) |
Przykłady migracji kodu
Konwersja HTML do PDF
Najczęstsza operacja Api2pdf ilustruje fundamentalną zmianę — przejście od wywołań API w chmurze do przetwarzania lokalnego.
Wdrożenie Api2pdf:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>");
Console.WriteLine(apiResponse.Pdf);
}
}
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>");
Console.WriteLine(apiResponse.Pdf);
}
}
Imports System
Imports System.Threading.Tasks
Imports Api2Pdf.DotNet
Module Program
Async Function Main(args As String()) As Task
Dim a2pClient = New Api2PdfClient("your-api-key")
Dim apiResponse = Await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>")
Console.WriteLine(apiResponse.Pdf)
End Function
End Module
Wdrożenie IronPDF:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
Imports System
Imports IronPdf
Class Program
Shared Sub Main(ByVal args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End Class
IronPDF eliminuje konieczność komunikacji sieciowej, zarządzanie kluczami API oraz oddzielny etap pobierania wymagany przez wzorzec odpowiedzi oparty na adresach URL stosowany przez Api2pdf.
Konwersja adresów URL do formatu PDF
Wdrożenie Api2pdf:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com");
Console.WriteLine(apiResponse.Pdf);
}
}
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com");
Console.WriteLine(apiResponse.Pdf);
}
}
Imports System
Imports System.Threading.Tasks
Imports Api2Pdf.DotNet
Module Program
Async Function Main(args As String()) As Task
Dim a2pClient = New Api2PdfClient("your-api-key")
Dim apiResponse = Await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com")
Console.WriteLine(apiResponse.Pdf)
End Function
End Module
Wdrożenie IronPDF:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF created from URL successfully");
}
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF created from URL successfully");
}
}
Imports System
Imports IronPdf
Module Program
Sub Main(args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
Console.WriteLine("PDF created from URL successfully")
End Sub
End Module
Plik HTML do PDF z opcjami
Wdrożenie Api2pdf:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.IO;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
string html = File.ReadAllText("input.html");
var options = new HeadlessChromeOptions
{
Landscape = true,
PrintBackground = true
};
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Console.WriteLine(apiResponse.Pdf);
}
}
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.IO;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
string html = File.ReadAllText("input.html");
var options = new HeadlessChromeOptions
{
Landscape = true,
PrintBackground = true
};
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Console.WriteLine(apiResponse.Pdf);
}
}
no response after 91 seconds
Wdrożenie IronPDF:
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
string html = File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created with options successfully");
}
}
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
string html = File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created with options successfully");
}
}
Imports System
Imports System.IO
Imports IronPdf
Module Program
Sub Main(args As String())
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
Dim html As String = File.ReadAllText("input.html")
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created with options successfully")
End Sub
End Module
IronPDF konfiguruje opcje renderowania bezpośrednio w obiekcie renderera, zamiast przekazywać je jako oddzielny parametr opcji do każdego wywołania API.
Łączenie wielu plików PDF
Wdrożenie Api2pdf:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var pdfUrls = new List<string>
{
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
};
var request = new PdfMergeRequest { Urls = pdfUrls };
var response = await a2pClient.PdfSharp.MergePdfsAsync(request);
if (response.Success)
{
// Download merged PDF from response.Pdf URL
}
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var pdfUrls = new List<string>
{
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
};
var request = new PdfMergeRequest { Urls = pdfUrls };
var response = await a2pClient.PdfSharp.MergePdfsAsync(request);
if (response.Success)
{
// Download merged PDF from response.Pdf URL
}
Imports Api2Pdf.DotNet
Dim a2pClient = New Api2PdfClient("YOUR_API_KEY")
Dim pdfUrls = New List(Of String) From {
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
}
Dim request = New PdfMergeRequest With {.Urls = pdfUrls}
Dim response = Await a2pClient.PdfSharp.MergePdfsAsync(request)
If response.Success Then
' Download merged PDF from response.Pdf URL
End If
Wdrożenie IronPDF:
using IronPdf;
// Load PDFs from files
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
// Merge all PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");
using IronPdf;
// Load PDFs from files
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
// Merge all PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");
Imports IronPdf
' Load PDFs from files
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim pdf3 = PdfDocument.FromFile("document3.pdf")
' Merge all PDFs
Dim merged = PdfDocument.Merge(pdf1, pdf2, pdf3)
merged.SaveAs("merged.pdf")
Metoda statyczna Merge wIronPDFakceptuje bezpośrednio wiele dokumentów, eliminując przepływ pracy oparty na adresach URL.
Pliki PDF chronione hasłem
Wdrożenie Api2pdf:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
// Generate PDF first
var pdfResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>");
// Then add password protection in separate call
var protectedResponse = await a2pClient.PdfSharp.SetPasswordAsync(
pdfResponse.Pdf,
"secretpassword"
);
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
// Generate PDF first
var pdfResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>");
// Then add password protection in separate call
var protectedResponse = await a2pClient.PdfSharp.SetPasswordAsync(
pdfResponse.Pdf,
"secretpassword"
);
Imports Api2Pdf.DotNet
Dim a2pClient = New Api2PdfClient("YOUR_API_KEY")
' Generate PDF first
Dim pdfResponse = Await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>")
' Then add password protection in separate call
Dim protectedResponse = Await a2pClient.PdfSharp.SetPasswordAsync(pdfResponse.Pdf, "secretpassword")
Wdrożenie IronPDF:
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");
// Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");
// Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>")
' Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123"
pdf.SecuritySettings.UserPassword = "user123"
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SaveAs("protected.pdf")
IronPDF zapewnia szczegółową kontrolę nad uprawnieniami do plików PDF za pomocą właściwości SecuritySettings.
Nagłówki i stopki
Wdrożenie Api2pdf:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var options = new HeadlessChromeOptions
{
HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
};
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var options = new HeadlessChromeOptions
{
HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
};
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Imports Api2Pdf.DotNet
Dim a2pClient = New Api2PdfClient("YOUR_API_KEY")
Dim options = New HeadlessChromeOptions With {
.HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
.FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
}
Dim response = Await a2pClient.HeadlessChrome.FromHtmlAsync(html, options)
Wdrożenie IronPDF:
using IronPdf;
var renderer = new ChromePdfRenderer();
// HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("with-headers.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
// HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("with-headers.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
.DrawDividerLine = True
}
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("with-headers.pdf")
IronPDF obsługuje tokeny zastępcze, takie jak {page} i {total-pages}, służące do dynamicznego numerowania stron. Aby uzyskać więcej opcji, zapoznaj się z dokumentacją dotyczącą nagłówków i stopek.
Integracja z ASP.NET Core.NET Core
Wzorzec asynchronicznego HTTP w Api2pdf znacznie różni się od bezpośredniego generowania plików PDF w IronPDF.
Wzorzec Api2pdf:
[ApiController]
public class PdfController : ControllerBase
{
private readonly Api2PdfClient _client;
public PdfController()
{
_client = new Api2PdfClient("YOUR_API_KEY");
}
[HttpGet("generate")]
public async Task<IActionResult> GeneratePdf()
{
var response = await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>");
if (!response.Success)
return BadRequest(response.Error);
// Redirect to download URL
return Redirect(response.Pdf);
}
}
[ApiController]
public class PdfController : ControllerBase
{
private readonly Api2PdfClient _client;
public PdfController()
{
_client = new Api2PdfClient("YOUR_API_KEY");
}
[HttpGet("generate")]
public async Task<IActionResult> GeneratePdf()
{
var response = await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>");
if (!response.Success)
return BadRequest(response.Error);
// Redirect to download URL
return Redirect(response.Pdf);
}
}
Imports Microsoft.AspNetCore.Mvc
<ApiController>
Public Class PdfController
Inherits ControllerBase
Private ReadOnly _client As Api2PdfClient
Public Sub New()
_client = New Api2PdfClient("YOUR_API_KEY")
End Sub
<HttpGet("generate")>
Public Async Function GeneratePdf() As Task(Of IActionResult)
Dim response = Await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>")
If Not response.Success Then
Return BadRequest(response.Error)
End If
' Redirect to download URL
Return Redirect(response.Pdf)
End Function
End Class
Wzór IronPDF:
[ApiController]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
// Return PDF directly - no download step needed
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}
[ApiController]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
// Return PDF directly - no download step needed
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}
Imports Microsoft.AspNetCore.Mvc
Imports System.Threading.Tasks
<ApiController>
Public Class PdfController
Inherits ControllerBase
<HttpGet("generate")>
Public Function GeneratePdf() As IActionResult
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>")
' Return PDF directly - no download step needed
Return File(pdf.BinaryData, "application/pdf", "report.pdf")
End Function
<HttpGet("generate-async")>
Public Async Function GeneratePdfAsync() As Task(Of IActionResult)
Dim renderer = New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>")
Return File(pdf.Stream, "application/pdf", "report.pdf")
End Function
End Class
IronPDF zwraca plik PDF bezpośrednio poprzez BinaryData lub Stream, eliminując schemat przekierowania do pobrania.
Konfiguracja wstrzykiwania zależności
// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPdfService, IronPdfService>();
}
// IPdfService.cs
public interface IPdfService
{
PdfDocument GenerateFromHtml(string html);
Task<PdfDocument> GenerateFromHtmlAsync(string html);
}
// IronPdfService.cs
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public PdfDocument GenerateFromHtml(string html) =>
_renderer.RenderHtmlAsPdf(html);
public Task<PdfDocument> GenerateFromHtmlAsync(string html) =>
_renderer.RenderHtmlAsPdfAsync(html);
}
// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPdfService, IronPdfService>();
}
// IPdfService.cs
public interface IPdfService
{
PdfDocument GenerateFromHtml(string html);
Task<PdfDocument> GenerateFromHtmlAsync(string html);
}
// IronPdfService.cs
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public PdfDocument GenerateFromHtml(string html) =>
_renderer.RenderHtmlAsPdf(html);
public Task<PdfDocument> GenerateFromHtmlAsync(string html) =>
_renderer.RenderHtmlAsPdfAsync(html);
}
' Program.vb or Startup.vb
Public Sub ConfigureServices(services As IServiceCollection)
services.AddScoped(Of IPdfService, IronPdfService)()
End Sub
' IPdfService.vb
Public Interface IPdfService
Function GenerateFromHtml(html As String) As PdfDocument
Function GenerateFromHtmlAsync(html As String) As Task(Of PdfDocument)
End Interface
' IronPdfService.vb
Public Class IronPdfService
Implements IPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.PrintHtmlBackgrounds = True
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Function GenerateFromHtml(html As String) As PdfDocument Implements IPdfService.GenerateFromHtml
Return _renderer.RenderHtmlAsPdf(html)
End Function
Public Function GenerateFromHtmlAsync(html As String) As Task(Of PdfDocument) Implements IPdfService.GenerateFromHtmlAsync
Return _renderer.RenderHtmlAsPdfAsync(html)
End Function
End Class
Obsługa błędów Migracja
Api2pdf wykorzystuje sprawdzanie obiektów odpowiedzi.IronPDFwykorzystuje standardowe wyjątki platformy .NET.
Wzorzec Api2pdf:
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html);
if (!response.Success)
{
Console.WriteLine($"Error: {response.Error}");
return;
}
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html);
if (!response.Success)
{
Console.WriteLine($"Error: {response.Error}");
return;
}
Imports System
Dim response = Await a2pClient.HeadlessChrome.FromHtmlAsync(html)
If Not response.Success Then
Console.WriteLine($"Error: {response.Error}")
Return
End If
Wzór IronPDF:
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (IronPdf.Exceptions.IronPdfLicenseException ex)
{
Console.WriteLine($"License error: {ex.Message}");
}
catch (IronPdf.Exceptions.IronPdfRenderingException ex)
{
Console.WriteLine($"Rendering error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (IronPdf.Exceptions.IronPdfLicenseException ex)
{
Console.WriteLine($"License error: {ex.Message}");
}
catch (IronPdf.Exceptions.IronPdfRenderingException ex)
{
Console.WriteLine($"Rendering error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
Imports IronPdf.Exceptions
Try
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
Catch ex As IronPdfLicenseException
Console.WriteLine($"License error: {ex.Message}")
Catch ex As IronPdfRenderingException
Console.WriteLine($"Rendering error: {ex.Message}")
Catch ex As Exception
Console.WriteLine($"Error: {ex.Message}")
End Try
Porownanie wydajnosci
| Metryka | Api2pdf | IronPDF |
|---|---|---|
| Prosty HTML | 2–5 sekund (sieć) | 100–500 ms (lokalnie) |
| Złożona strona | 5–10 sekund | 500 ms–2 s |
| Partia 100 sztuk | Minuty (limity stawek) | Sekundy (równoległe) |
| Offline | Niedostępne | Działa w pełni |
| Zimny start | None | ~2 s (pierwsze wyświetlenie) |
Wskazówki dotyczące optymalizacji wydajności
// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
public PdfDocument GeneratePdf(string html)
{
return SharedRenderer.RenderHtmlAsPdf(html);
}
// 2. Parallel generation
var tasks = htmlDocs.Select(html =>
Task.Run(() => SharedRenderer.RenderHtmlAsPdf(html)));
var results = await Task.WhenAll(tasks);
// 3. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay
// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
public PdfDocument GeneratePdf(string html)
{
return SharedRenderer.RenderHtmlAsPdf(html);
}
// 2. Parallel generation
var tasks = htmlDocs.Select(html =>
Task.Run(() => SharedRenderer.RenderHtmlAsPdf(html)));
var results = await Task.WhenAll(tasks);
// 3. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay
Imports System.Threading.Tasks
' 1. Reuse renderer instance
Private Shared ReadOnly SharedRenderer As New ChromePdfRenderer()
Public Function GeneratePdf(html As String) As PdfDocument
Return SharedRenderer.RenderHtmlAsPdf(html)
End Function
' 2. Parallel generation
Dim tasks = htmlDocs.Select(Function(html) Task.Run(Function() SharedRenderer.RenderHtmlAsPdf(html)))
Dim results = Await Task.WhenAll(tasks)
' 3. Disable unnecessary features for speed
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = False ' If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0) ' No delay
Rozwiązywanie typowych problemów związanych z migracją
Problem: Plik PDF wygląda inaczej niż wynik działania Api2pdf
Dopasuj ustawienia Headless Chrome w Api2pdf:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
renderer.RenderingOptions.ViewPortWidth = 1280;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1000);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
renderer.RenderingOptions.ViewPortWidth = 1280;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1000);
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
renderer.RenderingOptions.PrintHtmlBackgrounds = True
renderer.RenderingOptions.ViewPortWidth = 1280
renderer.RenderingOptions.EnableJavaScript = True
renderer.RenderingOptions.WaitFor.RenderDelay(1000)
Problem: Nie ładują się zasoby zewnętrzne
Skonfiguruj limity czasu ładowania zasobów:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout: 10000);
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout: 10000);
// Or use base URL for relative paths
var pdf = renderer.RenderHtmlAsPdf(html, baseUrl: "https://example.com/");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout: 10000);
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout: 10000);
// Or use base URL for relative paths
var pdf = renderer.RenderHtmlAsPdf(html, baseUrl: "https://example.com/");
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout:=10000)
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout:=10000)
' Or use base URL for relative paths
Dim pdf = renderer.RenderHtmlAsPdf(html, baseUrl:="https://example.com/")
Problem: Duże rozmiary plików PDF
Kompresuj obrazy po wygenerowaniu:
renderer.RenderingOptions.ImageQuality = 80;
// Or compress after generation
pdf.CompressImages(quality: 75);
pdf.SaveAs("compressed.pdf");
renderer.RenderingOptions.ImageQuality = 80;
// Or compress after generation
pdf.CompressImages(quality: 75);
pdf.SaveAs("compressed.pdf");
renderer.RenderingOptions.ImageQuality = 80
' Or compress after generation
pdf.CompressImages(quality:=75)
pdf.SaveAs("compressed.pdf")
Lista kontrolna po migracji
Po zakończeniu migracji kodu sprawdź, czy:
- Sprawdź, czy jakość pliku PDF odpowiada oczekiwaniom
- Przetestuj wszystkie skrajne przypadki (duże dokumenty, znaki specjalne)
- Sprawdź wskaźniki wydajności (powinno być widać znaczną poprawę)
- W razie potrzeby zaktualizuj konfiguracje Docker
- Usuń konto na portalu Api2pdf oraz klucze API
- Monitorowanie aktualizacji (nie jest już potrzebne śledzenie opóźnień API)
- Dokumentuj nowe wzorce dla swojego zespołu
- Aktualizacja potoków CI/CD
Zabezpieczenie infrastruktury PDF na przyszłość
Wraz ze zbliżającym się wydaniem .NET 10 i wprowadzeniem nowych funkcji językowych w C# 14, wybór natywnej biblioteki PDF dla .NET zapewnia kompatybilność z ewoluującymi możliwościami środowiska uruchomieniowego. ZaangażowanieIronPDFw obsługę najnowszych wersji .NET oznacza, że inwestycja w migrację przyniesie korzyści w miarę rozszerzania się projektów w latach 2025 i 2026 — bez narastania bieżących kosztów związanych z każdą konwersją.
Dodatkowe zasoby
- Dokumentacja IronPDF
- Samouczki dotyczące konwersji HTML do PDF
- Dokumentacja API
- Pakiet NuGet
- Opcje licencyjne
Przejście z Api2pdf naIronPDFzmienia sposób generowania plików PDF z modelu opartego na chmurze i kosztach za każdą konwersję na lokalną, jednorazową inwestycję. Twoje poufne dokumenty pozostają w Twojej infrastrukturze, opóźnienia spadają z sekund do milisekund, a Ty eliminujesz zależność od dostawców w zakresie tej kluczowej funkcji aplikacji.

