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 (bieżąca linia 3.0.7, starsza 2.0.36, Licencja Apache 2.0). Wszystkie opcje .NET to porty oparte na społeczności, a większość została porzucona: Pdfbox 1.1.1 (ostatnio opublikowane 2013, zbudowane na PDFBox 1.8.2), Pdfbox-IKVM 1.8.9 (ostatnio opublikowane marzec 2017) oraz PdfBox_DotNet_Version 2.0.15 (ostatnio opublikowane lipiec 2019). Jedyną aktywnie utrzymywaną opcją jest MASES.NetPDF (linia 3.0.x, śledząca PDFBox 3.0.x), która jest wrapperem JCOBridge wymagającym JVM w czasie wykonywania obok CLR. Te porty często opóźniają się za wydaniami Java i mogą czasami pominąć kluczowe funkcje, poprawki błędów lub aktualizacje bezpieczeństwa — ryzyko warte zważenia dla długożyjących projektów .NET.
Projektowanie API z priorytetem dla Javy
Przeniesione interfejsy API zachowują konwencje języka Java, które w kodzie .NET wydają się obce. Programiści napotykają metody camelCase zamiast PascalCase, obiekty Java File zamiast standardowych ciagów znaków .NET i jawne wywołania close() zamiast schemató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.
Zależności JVM
Porty oparte na IKVM (Pdfbox-IKVM, Pdfbox) zawierają ponowne wykonanie LLVM, podczas gdy MASES.NetPDF wywołuje prawdziwy JVM za pośrednictwem JCOBridge. W każdym przypadku wdrożenie obciąża Java runtime, którego idiomatyczne biblioteki .NET unikają.
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ę | Natywna biblioteka .NET |
| Styl API | Konwencje Javy (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 |
| Wsparcie | Tylko dla społeczności | Dostępne wsparcie komercyjne |
| Porządkowanie zasobów | Jawne 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 licencyjny IronPDF(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 "org.apache.pdfbox\|Org.Apache.Pdfbox\|PDDocument\|PDFTextStripper" --include="*.cs" .
grep -rE "Pdfbox|Pdfbox-IKVM|PdfBox_DotNet_Version|MASES\.NetPDF" --include="*.csproj" .
grep -r "org.apache.pdfbox\|Org.Apache.Pdfbox\|PDDocument\|PDFTextStripper" --include="*.cs" .
grep -rE "Pdfbox|Pdfbox-IKVM|PdfBox_DotNet_Version|MASES\.NetPDF" --include="*.csproj" .
Zmiany wymagające dostosowania
| Kategoria | Apache PDFBox Port .NET | 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() |
Instrukcje using |
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 | Klasa PDFTextStripper |
pdf.ExtractAllText() |
Prostsze API |
Proces migracji krok po kroku
Krok 1: Zaktualizuj pakiety NuGet
Usuń pakiety portu Apache PDFBox .NET i zainstaluj IronPDF:
# Remove whichever PDFBox .NET port your project uses
dotnet remove package Pdfbox # built against PDFBox 1.8.2 (2013)
dotnet remove package Pdfbox-IKVM # IKVM wrapper, last update 2017
dotnet remove package PdfBox_DotNet_Version # last update 2019
dotnet remove package MASES.NetPDF # JCOBridge wrapper, requires JVM
# Install IronPDF
dotnet add package IronPdf
# Remove whichever PDFBox .NET port your project uses
dotnet remove package Pdfbox # built against PDFBox 1.8.2 (2013)
dotnet remove package Pdfbox-IKVM # IKVM wrapper, last update 2017
dotnet remove package PdfBox_DotNet_Version # last update 2019
dotnet remove package MASES.NetPDF # JCOBridge wrapper, requires JVM
# Install IronPDF
dotnet add package IronPdf
Krok 2: Skonfiguruj klucz licencyjny
Dodaj klucz licencyjny IronPDF podczas uruchamiania aplikacji:
// Add at application startup, before any IronPDF operations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup, before any IronPDF operations
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:
Wszystkie porty .NET dla PDFBox odzwierciedlają hierarchię pakietów Java. Porty oparte na IKVM zachowują formę z małymi literami w Javie (org.apache.pdfbox.*); MASES.NetPDF przekształca to w wielką literę dla C# (Org.Apache.Pdfbox.*).
| Znajdź | Zastąp przez |
|---|---|
using org.apache.pdfbox.pdmodel; (porty IKVM) |
using IronPdf; |
using org.apache.pdfbox.text; (porty IKVM) |
using IronPdf; |
using org.apache.pdfbox.multipdf; (porty IKVM) |
using IronPdf; |
using Org.Apache.Pdfbox.Pdmodel; (MASES.NetPDF) |
using IronPdf; |
using Org.Apache.Pdfbox.Text; (MASES.NetPDF) |
using IronPdf; |
Kompletna dokumentacja API
Operacje na dokumentach
| Metoda Apache PDFBox | Metoda IronPDF |
|---|---|
PDDocument.load(path) |
PdfDocument.FromFile(path) |
PDDocument.load(stream) |
PdfDocument.FromStream(stream) |
new PDDocument() |
new ChromePdfRenderer() |
document.save(path) |
pdf.SaveAs(path) |
document.close() |
Instrukcja 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 | Metoda IronPDF |
|---|---|
new PDFTextStripper() |
Nie jest potrzebne |
stripper.getText(document) |
pdf.ExtractAllText() |
stripper.setStartPage(n) |
pdf.Pages[n].Text |
stripper.setSortByPosition(true) |
Automatyczne |
Operacje scałania i dzielenia
| Metoda Apache PDFBox | Metoda IronPDF |
|---|---|
new PDFMergerUtility() |
Nie jest potrzebne |
merger.addSource(file) |
Ładuj za pomocą FromFile() |
merger.mergeDocuments() |
PdfDocument.Merge(pdfs) |
new Splitter() |
Nie jest potrzebne |
splitter.split(document) |
pdf.CopyPages(indices) |
Bezpieczeństwo i szyfrowanie
| Metoda Apache PDFBox | Metoda IronPDF |
|---|---|
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 is a Java library — there is no official .NET port.
// Example uses Pdfbox-IKVM (last published 2017) on NuGet; namespaces
// mirror the Java packages exactly because IKVM exposes the Java API.
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.text;
using java.io;
using System;
class Program
{
static void Main()
{
PDDocument document = PDDocument.load(new File("document.pdf"));
try
{
PDFTextStripper stripper = new PDFTextStripper();
string text = stripper.getText(document);
Console.WriteLine(text);
}
finally
{
document.close();
}
}
}
// Apache PDFBox is a Java library — there is no official .NET port.
// Example uses Pdfbox-IKVM (last published 2017) on NuGet; namespaces
// mirror the Java packages exactly because IKVM exposes the Java API.
using org.apache.pdfbox.pdmodel;
using org.apache.pdfbox.text;
using java.io;
using System;
class Program
{
static void Main()
{
PDDocument document = PDDocument.load(new File("document.pdf"));
try
{
PDFTextStripper stripper = new PDFTextStripper();
string text = stripper.getText(document);
Console.WriteLine(text);
}
finally
{
document.close();
}
}
}
Imports org.apache.pdfbox.pdmodel
Imports org.apache.pdfbox.text
Imports java.io
Imports System
Module Program
Sub Main()
Dim document As PDDocument = PDDocument.load(New File("document.pdf"))
Try
Dim stripper As New PDFTextStripper()
Dim text As String = stripper.getText(document)
Console.WriteLine(text)
Finally
document.close()
End Try
End Sub
End Module
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 wydobywanie jednym 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ący IronPDF oparty 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 via a .NET port (e.g. Pdfbox-IKVM on nuget.org).
// The Java class org.apache.pdfbox.multipdf.PDFMergerUtility is exposed
// directly through IKVM, so method names stay Java-style (camelCase).
using org.apache.pdfbox.multipdf;
using org.apache.pdfbox.io;
using System;
class Program
{
static void Main()
{
PDFMergerUtility merger = new PDFMergerUtility();
merger.addSource("document1.pdf");
merger.addSource("document2.pdf");
merger.setDestinationFileName("merged.pdf");
// MemoryUsageSetting governs heap vs temp-file buffering
merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
Console.WriteLine("PDFs merged");
}
}
// Apache PDFBox via a .NET port (e.g. Pdfbox-IKVM on nuget.org).
// The Java class org.apache.pdfbox.multipdf.PDFMergerUtility is exposed
// directly through IKVM, so method names stay Java-style (camelCase).
using org.apache.pdfbox.multipdf;
using org.apache.pdfbox.io;
using System;
class Program
{
static void Main()
{
PDFMergerUtility merger = new PDFMergerUtility();
merger.addSource("document1.pdf");
merger.addSource("document2.pdf");
merger.setDestinationFileName("merged.pdf");
// MemoryUsageSetting governs heap vs temp-file buffering
merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
Console.WriteLine("PDFs merged");
}
}
Imports org.apache.pdfbox.multipdf
Imports org.apache.pdfbox.io
Imports System
Module Program
Sub Main()
Dim merger As New PDFMergerUtility()
merger.addSource("document1.pdf")
merger.addSource("document2.pdf")
merger.setDestinationFileName("merged.pdf")
' MemoryUsageSetting governs heap vs temp-file buffering
merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly())
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 w IronPDF akceptuje bezpośrednio wiele dokumentów, eliminując wzorzec klasy pomocniczej.
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 firmy IronPDF eliminuje iterację stron i obliczenia macierzowe.
Konwersja adresów URL do formatu PDF
Apache PDFBox nie obsługuje konwersji adresów URL do formatu PDF.IronPDF zapewnia 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.IronPDF zapewnia 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.IronPDF zapewnia 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 Port .NET | 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żywaj 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 równoważnikami .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 równoważnika 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żywaj statycznej metody Merge:
//IronPDF uses static Merge
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
//IronPDF uses 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
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 na IronPDF przekształ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.

