跳至頁尾內容
影片

如何在 PDF 上畫文字和位圖

Apache PDFBox是一個備受尊敬的開源Java程式庫,用於處理PDF。 然而,對於.NET開發者來說,現有的選擇是非官方的社群驅動移植,這帶來了重大挑戰—Java風格的API、不完整的功能覆蓋以及有限的.NET社群支援。 本指南提供了從Apache PDFBox .NET移植到IronPDF的詳細遷移路徑,這是一個專為.NET生態系統構建的原生.NET PDF程式庫。

為什麼考慮從Apache PDFBox .NET移植遷移?

雖然Apache PDFBox在Java生態系統中表現傑出,但其非官方的.NET移植存在多種挑戰,影響.NET開發團隊的工作。

非官方移植狀態

Apache PDFBox主要是Java程式庫(當前版本3.0.7,遺留版本2.0.36,Apache License 2.0)。 所有.NET選項都是社群驅動的移植,其中大多數已被遺棄:Pdfbox 1.1.1(最後發布於2013年,基於PDFBox 1.8.2構建),Pdfbox-IKVM 1.8.9(最後發布於2017年3月),PdfBox_DotNet_Version 2.0.15(最後發布於2019年7月)。 唯一積極維護的選項是MASES.NetPDF(3.0.x版本,跟踪PDFBox 3.0.x),這是一個JCOBridge包裝,需要在運行時與CLR一起使用JVM。 這些移植通常落後於Java的版本,可能缺少關鍵功能、錯誤修復或安全更新—這是值得權衡的長期.NET專案風險。

Java首選API設計

移植的API保留了Java慣例,這在.NET程式碼中顯得不熟悉。 開發者會遇到PascalCase,Java IDisposable模式。 這種認知開銷影響開發速度和程式碼的可維護性。

不支援HTML渲染功能

Apache PDFBox的設計是為了進行PDF操作,不是HTML到PDF轉換。 建立PDF需要手動構建頁面並進行精確的座標定位—這是一個乏味且易出錯的過程,無法適應現代文件生成的需求。

有限的.NET社群支援

圍繞Apache PDFBox移植的.NET生態系統非常稀少。 相比於擁有活躍.NET社群的程式庫,尋求針對.NET特定問題的幫助、範例或最佳實踐顯得困難。

JVM相依性

基於IKVM的移植(Pdfbox-IKVM, Pdfbox)捆綁了一個.NET JVM的重新實現,而MASES.NetPDF通過JCOBridge調用一個真正的JVM。 無論哪種方式,部署都攜帶Java運行時包袱,這是典型的.NET程式庫所避免的。

Apache PDFBox vs. IronPDF: 主要差異

了解這些程式庫之間的基本差異,有助於制定有效的遷移策略。

方面 Apache PDFBox .NET移植 IronPDF
原生設計 以Java為中心,非官方.NET移植 原生.NET程式庫
API風格 Java慣例(camelCase, close() 典型的C#(PascalCase, using
HTML渲染 不支援(手動頁面構建) 完整的基於Chromium的HTML/CSS/JS
PDF建立 手動坐標定位 基於 CSS 的佈局
社群 以Java為中心,稀少的.NET資源 活躍的.NET社群
支援 僅限社群支援 提供商業支援
資源清理 顯式close()調用 IDiposable與using語句

遷移前準備

前提條件

確保您的環境符合以下要求:

  • .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
  • Visual Studio 2019+ or JetBrains Rider
  • NuGet包管理器存取 -IronPDF許可證金鑰(免費試用可在 ironpdf.com 獲得)

審核Apache PDFBox使用情況

在您的解決方案目錄中運行這些命令,以識別所有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" .
SHELL

預期的中斷變更

類別 Apache PDFBox .NET移植 IronPDF 遷移動作
物件模型 PDDocument, PDPage PdfDocument, ChromePdfRenderer 不同的類層次結構
PDF建立 手動頁面/內容流 HTML渲染 重寫建立邏輯
方法風格 camelCase()(Java風格) PascalCase()(.NET風格) 更新方法名稱
資源清理 document.close() using語句 更換處理模式
文件存取 Java File物件 標準.NET字串/流 使用.NET型別
文字提取 PDFTextStripper pdf.ExtractAllText() 更簡單的API

逐步遷移過程

步驟1:更新NuGet包

移除Apache PDFBox .NET移植包並安裝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
SHELL

步驟 2:配置許可證金鑰

在應用程式啟動時新增IronPDF授權金鑰:

// 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"
$vbLabelText   $csharpLabel

步驟 3:更新命名空間參考

在您的解決方案中執行全域查找和替換:

所有PDFBox .NET移植都影射了Java包層次結構。 基於IKVM的移植保留了Java的小寫形式(org.apache.pdfbox.*); Org.Apache.Pdfbox.*)。

查找 替換為
using org.apache.pdfbox.pdmodel;(IKVM移植) using IronPdf;
using org.apache.pdfbox.text;(IKVM移植) using IronPdf;
using org.apache.pdfbox.multipdf;(IKVM移植) using IronPdf;
using Org.Apache.Pdfbox.Pdmodel;(MASES.NetPDF) using IronPdf;
using Org.Apache.Pdfbox.Text;(MASES.NetPDF) using IronPdf;

完整 API 遷移參考

文件操作

Apache PDFBox方法 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() Dispose()
document.getNumberOfPages() pdf.PageCount
document.getPage(index) pdf.Pages[index]
document.removePage(index) pdf.RemovePages(index)

文字提取

Apache PDFBox方法 IronPDF方法
new PDFTextStripper() 不需要
stripper.getText(document) pdf.ExtractAllText()
stripper.setStartPage(n) pdf.Pages[n].Text
stripper.setSortByPosition(true) 自動

合併和分割操作

Apache PDFBox方法 IronPDF方法
new PDFMergerUtility() 不需要
merger.addSource(file) 使用FromFile()載入
merger.mergeDocuments() PdfDocument.Merge(pdfs)
new Splitter() 不需要
splitter.split(document) pdf.CopyPages(indices)

安全和加密

Apache PDFBox方法 IronPDF方法
StandardProtectionPolicy pdf.SecuritySettings
policy.setUserPassword() pdf.SecuritySettings.UserPassword
policy.setOwnerPassword() pdf.SecuritySettings.OwnerPassword
policy.setPermissions() pdf.SecuritySettings.AllowUserXxx

程式碼遷移範例

文字提取

最常見的Apache PDFBox操作演示了IronPDF提供的API簡化。

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

IronPDF完全消除了PDFTextStripper類,將多步提取替換為單一方法調用。

HTML到PDF轉換

Apache PDFBox本身不支援HTML到PDF轉換—這代表著一個基本的能力差距。

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
$vbLabelText   $csharpLabel

IronPDF的基於Chromium的渲染引擎提供了完整的HTML、CSS和JavaScript支援。 對於高級場景,請參見HTML 到 PDF 文件

合併多個 PDF

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

IronPDF的靜態Merge方法直接接受多個文件,消除了實用類模式。

從頭開始建立PDF

在建立PDF時,最明顯的差異出現了。 Apache PDFBox需要手動坐標定位。

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

基於HTML/CSS的建立消除了坐標計算、字體管理和內容流處理。

新增密碼保護

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

IronPDF使用強型別的屬性,而不是單獨的許可和政策物件。

新增水印

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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

IronPDF的基於HTML的浮水印消除了頁面迭代和矩陣計算。

URL 到 PDF 轉換

Apache PDFBox不支援URL到PDF轉換。IronPDF提供原生支持:

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
$vbLabelText   $csharpLabel

有關完整的 URL 轉換選項,請參見URL 到 PDF 文件

頭部和尾部

Apache PDFBox要求在每個頁面上進行手動定位,且不支持內建的頁眉/頁腳。 IronPDF提供了聲明式配置:

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
$vbLabelText   $csharpLabel

有關高級佈局,請查看頁眉和頁腳文件

ASP.NET Core 整合

IronPDF自然地與現代.NET web應用程式整合:

[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
$vbLabelText   $csharpLabel

異步支持

Apache PDFBox移植不支援非同步操作。 IronPDF提供了完整的非同步/等待功能:

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
$vbLabelText   $csharpLabel

依賴注入配置

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
$vbLabelText   $csharpLabel

性能優化

記憶體使用比較

場景 Apache PDFBox .NET移植 IronPDF
文字提取 ~80 MB ~50 MB
PDF建立 ~100 MB ~60 MB
批次(100 PDFs) 高(手動清理) ~100 MB

優化提示

使用using語句:

//自動cleanup with IDisposable pattern
using var pdf = PdfDocument.FromFile(path);
//自動cleanup with IDisposable pattern
using var pdf = PdfDocument.FromFile(path);
$vbLabelText   $csharpLabel

重用渲染器進行批量操作:

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
$vbLabelText   $csharpLabel

在 Web 應用中使用異步:

using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
$vbLabelText   $csharpLabel

故障排除常見的遷移問題

問題:未找到Java風格的方法名稱

camelCase Java方法替換為PascalCase .NET等效方法:

// 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
$vbLabelText   $csharpLabel

問題:沒有close()方法

IronPDF使用IDisposable模式:

// PDFBox
document.close();

// IronPDF
using var pdf = PdfDocument.FromFile(path);
//自動disposal at end of scope
// PDFBox
document.close();

// IronPDF
using var pdf = PdfDocument.FromFile(path);
//自動disposal at end of scope
' PDFBox
document.Close()

' IronPDF
Using pdf = PdfDocument.FromFile(path)
    ' 自動disposal at end of scope
End Using
$vbLabelText   $csharpLabel

問題:沒有PDFTextStripper等效

文字提取簡化為單一方法:

// 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
$vbLabelText   $csharpLabel

問題:PDFMergerUtility 未找到

使用靜態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)
$vbLabelText   $csharpLabel

後遷移檢查清單

完成程式碼遷移後,請驗證以下內容:

  • 運行所有現有的單元和整合測試
  • 將 PDF 輸出與以前的版本進行視覺比較
  • 測試文字提取準確性
  • 驗證授權是否正常工作(IronPdf.License.IsLicensed
  • 性能與以前的實施做基準比較
  • 更新CI/CD管道依賴性
  • 記錄新的模式以供開發團隊參考

其他資源


從Apache PDFBox .NET移植到IronPDF,將您的PDF程式碼庫從Java風格模式轉換為典型的C#。 從手動坐標定位到HTML/CSS渲染的轉變,結合原生的非同步支援和現代.NET整合,提供了更乾淨、可維護的程式碼,以及在您生產應用程式背後的專業支援。

請注意Apache PDFBox是其各自所有者的註冊商標。 本網站與Apache Software Foundation無關,並未獲得其認可或贊助。 所有產品名稱、標誌和品牌均為其各自所有者的財產。 比較僅供參考,反映撰寫時公開可用的資訊。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話