Jak przejść z Apache PDFBox na IronPDF
Apache PDFBox to ceniona biblioteka Java typu open source służąca do obsługi plików PDF. Jednak dla programistów .NET dostępne opcje to nieoficjalne porty tworzone przez społeczność, które stwarzają poważne wyzwania — interfejsy API w stylu Java, niepełny zakres funkcji i ograniczone wsparcie społeczności .NET. Niniejszy przewodnik zawiera szczegółową ścieżkę migracji z portów Apache PDFBox .NET do IronPDF, natywnej biblioteki PDF dla platformy .NET, stworzonej specjalnie dla ekosystemu .NET.
Dlaczego warto rozważyć migrację z portów Apache PDFBox .NET?
Chociaż Apache PDFBox doskonale sprawdza się w ekosystemie Java, jego nieoficjalne porty na platformę .NET stwarzają szereg wyzwań, które mają wpływ na zespoły programistów .NET.
Nieoficjalny status portu
Apache PDFBox to przede wszystkim biblioteka Java. Wszystkie wersje .NET są portami tworzonymi przez społeczność, które nie mają oficjalnego wsparcia ze strony projektu Apache. Te wersje często pozostają w tyle za wydaniami Javy i mogą nie zawierać kluczowych funkcji, poprawek błędów lub aktualizacji zabezpieczeń. Dla zespołów tworzących aplikacje, których żywotność ma sięgać 2025 i 2026 roku, ta niepewność stwarza ryzyko techniczne.
Projektowanie API z priorytetem dla Javy
Przeniesione interfejsy API zachowują konwencje języka Java, które w kodzie .NET wydają się obce. Programiści spotykają się z metodami camelCase zamiast PascalCase, obiekty Java File zamiast standardowych ciągów znaków .NET Standard oraz jawne wywołania close() zamiast wzorców IDisposable. To obciążenie poznawcze wpływa na szybkość rozwoju i łatwość utrzymania kodu.
Brak możliwości renderowania HTML
Apache PDFBox jest przeznaczony do manipulacji plikami PDF, a nie do konwersji HTML na PDF. Tworzenie plików PDF wymaga ręcznego konstruowania stron z precyzyjnym pozycjonowaniem współrzędnych — jest to żmudny i podatny na błędy proces, który nie nadaje się do współczesnych potrzeb w zakresie generowania dokumentów.
Ograniczone wsparcie społeczności .NET
Ekosystem .NET wokół portów Apache PDFBox jest skromny. Znalezienie pomocy, przykładów lub najlepszych praktyk dotyczących konkretnych problemów związanych z platformą .NET okazuje się trudne w porównaniu z bibliotekami posiadającymi aktywne społeczności .NET.
Potencjalne zależności JVM
Niektóre porty Apache PDFBox mogą wymagać komponentów środowiska uruchomieniowego Java, co zwiększa złożoność wdrażania i zarządzania środowiskiem w infrastrukturze opartej na .NET.
Apache PDFBox a IronPDF: kluczowe różnice
Zrozumienie podstawowych różnic między tymi bibliotekami pomaga w zaplanowaniu skutecznej strategii migracji.
| Aspekt | Porty Apache PDFBox .NET | IronPDF |
|---|---|---|
| Natyny Design | Nieoficjalny port .NET zorientowany na Javę | Natywny .NET, profesjonalne wsparcie |
| Styl API | Konwencje języka Java (camelCase, close()) |
Idiomatyczny C# (PascalCase, using) |
| Renderowanie HTML | Nieobsługiwane (ręczne tworzenie stron) | Pełny HTML/CSS/JS oparty na Chromium |
| Tworzenie plików PDF | Ręczne pozycjonowanie współrzędnych | Układ oparty na CSS |
| Społeczność | Niewiele zasobów dotyczących .NET, skupionych na Javie | Aktywna społeczność .NET, ponad 10 mln pobrań |
| Wsparcie | Tylko dla społeczności | Dostępne profesjonalne wsparcie |
| Porządkowanie zasobów | Wyraźne wywołania close() |
IDisposable z instrukcjami using |
Przygotowania przed migracją
Wymagania wstępne
Upewnij się, że Twoje środowisko spełnia następujące wymagania:
- .NET Framework 4.6.2+ lub .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ lub JetBrains Rider
- Dostęp do menedżera pakietów NuGet
- Klucz licencyjnyIronPDF(bezpłatna wersja próbna dostępna na stronie ironpdf.com)
Audyt wykorzystania Apache PDFBox
Uruchom te polecenia w katalogu rozwiązania, aby zidentyfikować wszystkie odwołania do Apache PDFBox:
grep -r "apache.pdfbox\|PdfBox\|PDDocument\|PDFTextStripper" --include="*.cs" .
grep -r "PdfBox\|Apache.PdfBox" --include="*.csproj" .
grep -r "apache.pdfbox\|PdfBox\|PDDocument\|PDFTextStripper" --include="*.cs" .
grep -r "PdfBox\|Apache.PdfBox" --include="*.csproj" .
Zmiany wymagające dostosowania
| Kategoria | Apache PDFBox .NET Port | IronPDF | Działanie migracyjne |
|---|---|---|---|
| Model obiektowy | PDDocument, PDPage |
PdfDocument, ChromePdfRenderer |
Inna hierarchia klas |
| Tworzenie plików PDF | Strony podręcznika/strumienie treści | Renderowanie HTML | Przepisz logikę tworzenia |
| Styl metody | camelCase() (styl Java) |
PascalCase() (styl .NET) |
Zaktualizuj nazwy metod |
| Porządkowanie zasobów | document.close() |
using instrukcje |
Zmiana schematu usuwania |
| Dostęp do plików | Obiekty Java File |
Standardowe ciągi znaków/strumienie .NET Standard | Użyj typów .NET |
| Ekstrakcja tekstu | PDFTextStripper class |
pdf.ExtractAllText() |
Prostsze API |
Proces migracji krok po kroku
Krok 1: Zaktualizuj pakiety NuGet
Usuń pakiety portu Apache PDFBox .NET i zainstaluj IronPDF:
# Remove PDFBox .NET port packages
dotnet remove package PdfBox
dotnet remove package PDFBoxNet
dotnet remove package Apache.PdfBox
# Install IronPDF
dotnet add package IronPdf
# Remove PDFBox .NET port packages
dotnet remove package PdfBox
dotnet remove package PDFBoxNet
dotnet remove package Apache.PdfBox
# Install IronPDF
dotnet add package IronPdf
Krok 2: Skonfiguruj klucz licencyjny
Dodaj klucz licencyjnyIronPDFpodczas uruchamiania aplikacji:
// Add at application startup, before anyIronPDFoperations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup, before anyIronPDFoperations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup, before any IronPDF operations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Krok 3: Zaktualizuj odniesienia do przestrzeni nazw
Przeprowadź globalne wyszukiwanie i zamianę w całym rozwiązaniu:
| Znajdź | Zastąp przez |
|---|---|
using org.apache.pdfbox.pdmodel; |
using IronPdf; |
using org.apache.pdfbox.text; |
using IronPdf; |
using org.apache.pdfbox.multipdf; |
using IronPdf; |
using PdfBoxDotNet.Pdmodel; |
using IronPdf; |
using Apache.Pdfbox.PdModel; |
using IronPdf; |
Kompletna dokumentacja API
Operacje na dokumentach
| Metoda Apache PDFBox | MetodaIronPDF |
|---|---|
PDDocument.load(path) |
PdfDocument.FromFile(path) |
PDDocument.load(stream) |
PdfDocument.FromStream(stream) |
new PDDocument() |
new ChromePdfRenderer() |
document.save(path) |
pdf.SaveAs(path) |
document.close() |
using lub Dispose() |
document.getNumberOfPages() |
pdf.PageCount |
document.getPage(index) |
pdf.Pages[index] |
document.removePage(index) |
pdf.RemovePages(index) |
Wyodrębnianie tekstu
| Metoda Apache PDFBox | MetodaIronPDF |
|---|---|
new PDFTextStripper() |
Nie jest potrzebne |
stripper.getText(document) |
pdf.ExtractAllText() |
stripper.setStartPage(n) |
pdf.Pages[n].Text |
stripper.setSortByPosition(true) |
Automatyczne |
Operacje scalania i dzielenia
| Metoda Apache PDFBox | MetodaIronPDF |
|---|---|
new PDFMergerUtility() |
Nie jest potrzebne |
merger.addSource(file) |
Załaduj z FromFile() |
merger.mergeDocuments() |
PdfDocument.Merge(pdfs) |
new Splitter() |
Nie jest potrzebne |
splitter.split(document) |
pdf.CopyPages(indices) |
Bezpieczeństwo i szyfrowanie
| Metoda Apache PDFBox | MetodaIronPDF |
|---|---|
StandardProtectionPolicy |
pdf.SecuritySettings |
policy.setUserPassword() |
pdf.SecuritySettings.UserPassword |
policy.setOwnerPassword() |
pdf.SecuritySettings.OwnerPassword |
policy.setPermissions() |
pdf.SecuritySettings.AllowUserXxx |
Przykłady migracji kodu
Wyodrębnianie tekstu
Najczęstsza operacja Apache PDFBox pokazuje uproszczenie API zapewniane przez IronPDF.
Wdrożenie portu Apache PDFBox .NET:
// Apache PDFBox .NET ports are experimental and incomplete
using PdfBoxDotNet.Pdmodel;
using PdfBoxDotNet.Text;
using System;
using System.IO;
class Program
{
static void Main()
{
// Note: PDFBox-dotnet has limited functionality
using (var document = PDDocument.Load("document.pdf"))
{
var stripper = new PDFTextStripper();
string text = stripper.GetText(document);
Console.WriteLine(text);
}
}
}
// Apache PDFBox .NET ports are experimental and incomplete
using PdfBoxDotNet.Pdmodel;
using PdfBoxDotNet.Text;
using System;
using System.IO;
class Program
{
static void Main()
{
// Note: PDFBox-dotnet has limited functionality
using (var document = PDDocument.Load("document.pdf"))
{
var stripper = new PDFTextStripper();
string text = stripper.GetText(document);
Console.WriteLine(text);
}
}
}
Imports PdfBoxDotNet.Pdmodel
Imports PdfBoxDotNet.Text
Imports System
Imports System.IO
Class Program
Shared Sub Main()
' Note: PDFBox-dotnet has limited functionality
Using document = PDDocument.Load("document.pdf")
Dim stripper = New PDFTextStripper()
Dim text As String = stripper.GetText(document)
Console.WriteLine(text)
End Using
End Sub
End Class
Wdrożenie IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("document.pdf");
string text = pdf.ExtractAllText();
Console.WriteLine(text);
// Or extract text from specific pages
string pageText = pdf.ExtractTextFromPage(0);
Console.WriteLine(pageText);
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var pdf = PdfDocument.FromFile("document.pdf");
string text = pdf.ExtractAllText();
Console.WriteLine(text);
// Or extract text from specific pages
string pageText = pdf.ExtractTextFromPage(0);
Console.WriteLine(pageText);
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim pdf = PdfDocument.FromFile("document.pdf")
Dim text As String = pdf.ExtractAllText()
Console.WriteLine(text)
' Or extract text from specific pages
Dim pageText As String = pdf.ExtractTextFromPage(0)
Console.WriteLine(pageText)
End Sub
End Class
IronPDF całkowicie eliminuje klasę PDFTextStripper, zastępując wieloetapowe wyodrębnianie pojedynczym wywołaniem metody.
Konwersja HTML do PDF
Apache PDFBox nie obsługuje natywnie konwersji HTML do PDF — stanowi to fundamentalną lukę w funkcjonalności.
Wdrożenie IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is HTML to PDF</p>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is HTML to PDF</p>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is HTML to PDF</p>")
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End Class
Silnik renderującyIronPDFoparty na Chromium zapewnia pełną obsługę HTML, CSS i JavaScript. W przypadku zaawansowanych scenariuszy zapoznaj się z dokumentacją dotyczącą konwersji HTML do PDF.
Łączenie wielu plików PDF
Wdrożenie portu Apache PDFBox .NET:
// Apache PDFBox .NET port attempt (incomplete support)
using PdfBoxDotNet.Pdmodel;
using PdfBoxDotNet.Multipdf;
using System;
using System.IO;
class Program
{
static void Main()
{
// PDFBox-dotnet ports have incomplete API coverage
var merger = new PDFMergerUtility();
merger.AddSource("document1.pdf");
merger.AddSource("document2.pdf");
merger.SetDestinationFileName("merged.pdf");
merger.MergeDocuments();
Console.WriteLine("PDFs merged");
}
}
// Apache PDFBox .NET port attempt (incomplete support)
using PdfBoxDotNet.Pdmodel;
using PdfBoxDotNet.Multipdf;
using System;
using System.IO;
class Program
{
static void Main()
{
// PDFBox-dotnet ports have incomplete API coverage
var merger = new PDFMergerUtility();
merger.AddSource("document1.pdf");
merger.AddSource("document2.pdf");
merger.SetDestinationFileName("merged.pdf");
merger.MergeDocuments();
Console.WriteLine("PDFs merged");
}
}
Imports PdfBoxDotNet.Pdmodel
Imports PdfBoxDotNet.Multipdf
Imports System
Imports System.IO
Module Program
Sub Main()
' PDFBox-dotnet ports have incomplete API coverage
Dim merger As New PDFMergerUtility()
merger.AddSource("document1.pdf")
merger.AddSource("document2.pdf")
merger.SetDestinationFileName("merged.pdf")
merger.MergeDocuments()
Console.WriteLine("PDFs merged")
End Sub
End Module
Wdrożenie IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}
Imports IronPdf
Imports System
Imports System.Collections.Generic
Module Program
Sub Main()
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim pdf3 = PdfDocument.FromFile("document3.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2, pdf3)
merged.SaveAs("merged.pdf")
Console.WriteLine("PDFs merged successfully")
End Sub
End Module
Statyczna metoda Merge wIronPDFakceptuje bezpośrednio wiele dokumentów, eliminując wzorzec klasy użytkowej.
Tworzenie plików PDF od podstaw
Najbardziej wyraźna różnica pojawia się podczas tworzenia plików PDF. Apache PDFBox wymaga ręcznego ustawiania współrzędnych.
Wdrożenie portu Apache PDFBox .NET:
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.pdmodel.font;
using org.apache.pdfbox.pdmodel.edit;
public void CreatePdf(string outputPath)
{
PDDocument document = new PDDocument();
try
{
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
PDFont font = PDType1Font.HELVETICA_BOLD;
contentStream.beginText();
contentStream.setFont(font, 24);
contentStream.moveTextPositionByAmount(72, 700);
contentStream.drawString("Hello World");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA, 12);
contentStream.moveTextPositionByAmount(72, 650);
contentStream.drawString("This is a paragraph of text.");
contentStream.endText();
contentStream.close();
document.save(outputPath);
}
finally
{
document.close();
}
}
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.pdmodel.font;
using org.apache.pdfbox.pdmodel.edit;
public void CreatePdf(string outputPath)
{
PDDocument document = new PDDocument();
try
{
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
PDFont font = PDType1Font.HELVETICA_BOLD;
contentStream.beginText();
contentStream.setFont(font, 24);
contentStream.moveTextPositionByAmount(72, 700);
contentStream.drawString("Hello World");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA, 12);
contentStream.moveTextPositionByAmount(72, 650);
contentStream.drawString("This is a paragraph of text.");
contentStream.endText();
contentStream.close();
document.save(outputPath);
}
finally
{
document.close();
}
}
Imports org.apache.pdfbox.pdmodel
Imports org.apache.pdfbox.pdmodel.font
Imports org.apache.pdfbox.pdmodel.edit
Public Sub CreatePdf(outputPath As String)
Dim document As New PDDocument()
Try
Dim page As New PDPage()
document.addPage(page)
Dim contentStream As New PDPageContentStream(document, page)
Dim font As PDFont = PDType1Font.HELVETICA_BOLD
contentStream.beginText()
contentStream.setFont(font, 24)
contentStream.moveTextPositionByAmount(72, 700)
contentStream.drawString("Hello World")
contentStream.endText()
contentStream.beginText()
contentStream.setFont(PDType1Font.HELVETICA, 12)
contentStream.moveTextPositionByAmount(72, 650)
contentStream.drawString("This is a paragraph of text.")
contentStream.endText()
contentStream.close()
document.save(outputPath)
Finally
document.close()
End Try
End Sub
Wdrożenie IronPDF:
using IronPdf;
public void CreatePdf(string outputPath)
{
var renderer = new ChromePdfRenderer();
string html = @"
<html>
<head>
<style>
body { font-family: Helvetica, Arial, sans-serif; margin: 1in; }
h1 { font-size: 24pt; font-weight: bold; }
p { font-size: 12pt; }
</style>
</head>
<body>
<h1>Hello World</h1>
<p>This is a paragraph of text.</p>
</body>
</html>";
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void CreatePdf(string outputPath)
{
var renderer = new ChromePdfRenderer();
string html = @"
<html>
<head>
<style>
body { font-family: Helvetica, Arial, sans-serif; margin: 1in; }
h1 { font-size: 24pt; font-weight: bold; }
p { font-size: 12pt; }
</style>
</head>
<body>
<h1>Hello World</h1>
<p>This is a paragraph of text.</p>
</body>
</html>";
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub CreatePdf(outputPath As String)
Dim renderer As New ChromePdfRenderer()
Dim html As String = "
<html>
<head>
<style>
body { font-family: Helvetica, Arial, sans-serif; margin: 1in; }
h1 { font-size: 24pt; font-weight: bold; }
p { font-size: 12pt; }
</style>
</head>
<body>
<h1>Hello World</h1>
<p>This is a paragraph of text.</p>
</body>
</html>"
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
End Using
End Sub
Tworzenie oparte na HTML/CSS eliminuje obliczenia współrzędnych, zarządzanie czcionkami i manipulowanie strumieniem treści.
Dodawanie ochrony hasłem
Wdrożenie portu Apache PDFBox .NET:
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.pdmodel.encryption;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
PDDocument document = PDDocument.load(new File(inputPath));
try
{
AccessPermission ap = new AccessPermission();
ap.setCanPrint(true);
ap.setCanExtractContent(false);
StandardProtectionPolicy spp = new StandardProtectionPolicy(password, password, ap);
spp.setEncryptionKeyLength(128);
document.protect(spp);
document.save(outputPath);
}
finally
{
document.close();
}
}
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.pdmodel.encryption;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
PDDocument document = PDDocument.load(new File(inputPath));
try
{
AccessPermission ap = new AccessPermission();
ap.setCanPrint(true);
ap.setCanExtractContent(false);
StandardProtectionPolicy spp = new StandardProtectionPolicy(password, password, ap);
spp.setEncryptionKeyLength(128);
document.protect(spp);
document.save(outputPath);
}
finally
{
document.close();
}
}
Imports org.apache.pdfbox.pdmodel
Imports org.apache.pdfbox.pdmodel.encryption
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Dim document As PDDocument = PDDocument.load(New File(inputPath))
Try
Dim ap As New AccessPermission()
ap.setCanPrint(True)
ap.setCanExtractContent(False)
Dim spp As New StandardProtectionPolicy(password, password, ap)
spp.setEncryptionKeyLength(128)
document.protect(spp)
document.save(outputPath)
Finally
document.close()
End Try
End Sub
Wdrożenie IronPDF:
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Using pdf = PdfDocument.FromFile(inputPath)
pdf.SecuritySettings.UserPassword = password
pdf.SecuritySettings.OwnerPassword = password
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF wykorzystuje właściwości silnie typowane zamiast oddzielnych obiektów uprawnień i zasad.
Dodawanie znaków wodnych
Wdrożenie portu Apache PDFBox .NET:
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.pdmodel.edit;
using org.apache.pdfbox.pdmodel.font;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
PDDocument document = PDDocument.load(new File(inputPath));
try
{
PDFont font = PDType1Font.HELVETICA_BOLD;
for (int i = 0; i < document.getNumberOfPages(); i++)
{
PDPage page = document.getPage(i);
PDPageContentStream cs = new PDPageContentStream(
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
cs.beginText();
cs.setFont(font, 72);
cs.setNonStrokingColor(200, 200, 200);
cs.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(45), 200, 400));
cs.showText(watermarkText);
cs.endText();
cs.close();
}
document.save(outputPath);
}
finally
{
document.close();
}
}
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.pdmodel.edit;
using org.apache.pdfbox.pdmodel.font;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
PDDocument document = PDDocument.load(new File(inputPath));
try
{
PDFont font = PDType1Font.HELVETICA_BOLD;
for (int i = 0; i < document.getNumberOfPages(); i++)
{
PDPage page = document.getPage(i);
PDPageContentStream cs = new PDPageContentStream(
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
cs.beginText();
cs.setFont(font, 72);
cs.setNonStrokingColor(200, 200, 200);
cs.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(45), 200, 400));
cs.showText(watermarkText);
cs.endText();
cs.close();
}
document.save(outputPath);
}
finally
{
document.close();
}
}
Imports org.apache.pdfbox.pdmodel
Imports org.apache.pdfbox.pdmodel.edit
Imports org.apache.pdfbox.pdmodel.font
Public Sub AddWatermark(inputPath As String, outputPath As String, watermarkText As String)
Dim document As PDDocument = PDDocument.load(New File(inputPath))
Try
Dim font As PDFont = PDType1Font.HELVETICA_BOLD
For i As Integer = 0 To document.getNumberOfPages() - 1
Dim page As PDPage = document.getPage(i)
Dim cs As New PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, True, True)
cs.beginText()
cs.setFont(font, 72)
cs.setNonStrokingColor(200, 200, 200)
cs.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(45), 200, 400))
cs.showText(watermarkText)
cs.endText()
cs.close()
Next
document.save(outputPath)
Finally
document.close()
End Try
End Sub
Wdrożenie IronPDF:
using IronPdf;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.ApplyWatermark(
$"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
rotation: 45,
opacity: 50);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.ApplyWatermark(
$"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
rotation: 45,
opacity: 50);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub AddWatermark(inputPath As String, outputPath As String, watermarkText As String)
Using pdf = PdfDocument.FromFile(inputPath)
pdf.ApplyWatermark(
$"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
rotation:=45,
opacity:=50)
pdf.SaveAs(outputPath)
End Using
End Sub
Znak wodny oparty na HTML firmyIronPDFeliminuje iterację stron i obliczenia macierzowe.
Konwersja adresów URL do formatu PDF
Apache PDFBox nie obsługuje konwersji adresów URL do formatu PDF.IronPDFzapewnia natywną obsługę:
using IronPdf;
public void ConvertUrlToPdf(string url, string outputPath)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ConvertUrlToPdf(string url, string outputPath)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ConvertUrlToPdf(url As String, outputPath As String)
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderUrlAsPdf(url)
pdf.SaveAs(outputPath)
End Using
End Sub
Pełne opcje konwersji adresów URL można znaleźć w dokumentacji funkcji URL to PDF.
Nagłówki i stopki
Apache PDFBox wymaga ręcznego pozycjonowania na każdej stronie, ponieważ nie obsługuje wbudowanych nagłówków i stopek.IronPDFzapewnia konfigurację deklaratywną:
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Title",
FontSize = 12
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Title",
FontSize = 12
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub CreatePdfWithHeaderFooter(html As String, outputPath As String)
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Document Title",
.FontSize = 12
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page} of {total-pages}",
.FontSize = 10
}
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
End Using
End Sub
Aby uzyskać informacje na temat zaawansowanych układów, zapoznaj się z dokumentacją dotyczącą nagłówków i stopek.
Integracja z ASP.NET Core.NET Core
IronPDF w naturalny sposób integruje się z nowoczesnymi aplikacjami internetowymi .NET:
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(request.Html);
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(request.Html);
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
<HttpPost>
Public Function GeneratePdf(<FromBody> request As ReportRequest) As IActionResult
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(request.Html)
Return File(pdf.BinaryData, "application/pdf", "report.pdf")
End Using
End Function
Obsługa asynchroniczna
Porty Apache PDFBox nie obsługują operacji asynchronicznych.IronPDFzapewnia pełną obsługę async/await:
using IronPdf;
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
using IronPdf;
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
Imports IronPdf
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
End Function
Konfiguracja wstrzykiwania zależności
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
string ExtractText(string pdfPath);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
}
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
string ExtractText(string pdfPath);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
}
Imports System.Threading.Tasks
Public Interface IPdfService
Function GeneratePdfAsync(html As String) As Task(Of Byte())
Function ExtractText(pdfPath As String) As String
End Interface
Public Class IronPdfService
Implements IPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte()) Implements IPdfService.GeneratePdfAsync
Using pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
End Function
Public Function ExtractText(pdfPath As String) As String Implements IPdfService.ExtractText
Using pdf = PdfDocument.FromFile(pdfPath)
Return pdf.ExtractAllText()
End Using
End Function
End Class
Optymalizacja wydajności
Porównanie zużycia pamięci
| Scenariusz | Apache PDFBox .NET Port | IronPDF |
|---|---|---|
| Wyodrębnianie tekstu | ~80 MB | ~50 MB |
| Tworzenie plików PDF | ~100 MB | ~60 MB |
| Partia (100 plików PDF) | Wysoki (ręczne czyszczenie) | ~100 MB |
Wskazówki dotyczące optymalizacji
Użyj instrukcji using:
// Automatyczne cleanup with IDisposable pattern
using var pdf = PdfDocument.FromFile(path);
// Automatyczne cleanup with IDisposable pattern
using var pdf = PdfDocument.FromFile(path);
Ponowne wykorzystanie renderera do operacji wsadowych:
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
For Each html In htmlList
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs($"output_{i}.pdf")
End Using
Next
Wykorzystanie Async w aplikacjach internetowych:
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
Rozwiązywanie typowych problemów związanych z migracją
Problem: Nie znaleziono nazw metod w stylu Java
Zastąp metody Java camelCase odpowiednikami .NET PascalCase:
// PDFBox: stripper.getText(document)
// IronPDF: pdf.ExtractAllText()
// PDFBox: document.getNumberOfPages()
// IronPDF: pdf.PageCount
// PDFBox: stripper.getText(document)
// IronPDF: pdf.ExtractAllText()
// PDFBox: document.getNumberOfPages()
// IronPDF: pdf.PageCount
' PDFBox: stripper.getText(document)
' IronPDF: pdf.ExtractAllText()
' PDFBox: document.getNumberOfPages()
' IronPDF: pdf.PageCount
Problem: Brak metody close()
IronPDF używa wzorca IDisposable:
// PDFBox
document.close();
// IronPDF
using var pdf = PdfDocument.FromFile(path);
// Automatyczne disposal at end of scope
// PDFBox
document.close();
// IronPDF
using var pdf = PdfDocument.FromFile(path);
// Automatyczne disposal at end of scope
Problem: Brak odpowiednika PDFTextStripper
Pobieranie tekstu zostało uproszczone do jednej metody:
// IronPDF: Just call ExtractAllText()
string text = pdf.ExtractAllText();
// Per-page extraction:
string pageText = pdf.Pages[0].Text;
// IronPDF: Just call ExtractAllText()
string text = pdf.ExtractAllText();
// Per-page extraction:
string pageText = pdf.Pages[0].Text;
' IronPDF: Just call ExtractAllText()
Dim text As String = pdf.ExtractAllText()
' Per-page extraction:
Dim pageText As String = pdf.Pages(0).Text
Problem: PDFMergerUtility Nie znaleziono
Użyj metody statycznej Merge:
//IronPDFuses static Merge
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
//IronPDFuses static Merge
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
' IronPDF uses static Merge
Dim merged = PdfDocument.Merge(pdf1, pdf2, pdf3)
Lista kontrolna po migracji
Po zakończeniu migracji kodu sprawdź, czy:
- Uruchom wszystkie istniejące testy jednostkowe i integracyjne
- Porównaj wizualnie pliki PDF z poprzednimi wersjami
- Sprawdź dokładność wyodrębniania tekstu
- Sprawdź, czy licencjonowanie działa poprawnie (
IronPdf.License.IsLicensed) - Testy wydajności w porównaniu z poprzednią implementacją
- Aktualizacja zależności potoku CI/CD
- Opisz nowe wzorce dla swojego zespołu programistów
Zabezpieczenie infrastruktury PDF na przyszłość
W obliczu zbliżającej się premiery .NET 10 i wprowadzenia nowych funkcji językowych w C# 14, wybór natywnej biblioteki PDF dla platformy .NET zapewnia kompatybilność z rozwijającymi się 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.
Dodatkowe zasoby
- Dokumentacja IronPDF
- Samouczki dotyczące konwersji HTML do PDF
- Dokumentacja API
- Pakiet NuGet
- Opcje licencyjne
Przejście z portów Apache PDFBox .NET naIronPDFprzekształca kod PDF z wzorców w stylu Java na idiomatyczny C#. Przejście od ręcznego pozycjonowania współrzędnych do renderowania HTML/CSS, w połączeniu z natywną obsługą asynchroniczności i nowoczesną integracją z platformą .NET, zapewnia czystszy i łatwiejszy w utrzymaniu kod oraz profesjonalne wsparcie dla aplikacji produkcyjnych.

