產品比較 IronPDF與ITextPDF之比較 Curtis Chau 更新:7月 28, 2025 下載 IronPDF NuGet 下載 DLL 下載 Windows 安裝程式 開始免費試用 法學碩士副本 法學碩士副本 將頁面複製為 Markdown 格式,用於 LLMs 在 ChatGPT 中打開 請向 ChatGPT 諮詢此頁面 在雙子座打開 請向 Gemini 詢問此頁面 在雙子座打開 請向 Gemini 詢問此頁面 打開困惑 向 Perplexity 詢問有關此頁面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 複製連結 電子郵件文章 對於使用 PDF 的開發人員而言,擁有一個可靠的 PDF 產生與處理函式庫是非常重要的。 在 .NET 生態系統中,有兩個廣受歡迎的 PDF 函式庫脫穎而出 - IronPDF 和 iTextPdf - 每個函式庫都提供強大的工具來建立、編輯和管理 PDF 文件。 本文將根據這些函式庫的功能能力、文件品質和定價政策,對這些函式庫進行深入的比較。 IronPDF 和 iTextPdf 的概述 IronPDF。 IronPDF 是用於 PDF 管理的強大 .NET 函式庫,相容於各種 .NET 環境 (Core 8、7、6、Framework 等)。 它提供了全面的功能集,包括 HTML 到 PDF 的轉換、合併 PDF、加密和數位簽章。 IronPDF 的說明文件簡單明瞭,使用者可以獲得可靠的技術支援。 開發人員通常會透過 Stack Overflow 討論和其他原始碼分享平台找到常見問題的解決方案。 iTextPdf iTextPdf 是 iText 圖書館的 Java 和 .NET (C#) 的進階 PDF 圖書館,著重於企業級的文件處理。 本手冊同時提供 AGPL 與商業授權,為各種專案提供彈性。 iText 軟體(例如 iTextPdf)具有高度的客製化能力,使其成為複雜 PDF 任務(例如文件加密、數位簽署和表單建立)的理想選擇。 跨平台相容性 IronPDF 和 iTextPdf 均支援跨平台功能,使其能滿足 .NET 內各種應用程式的需求。 以下是每個函式庫的相容性細目。 IronPDF。 .NET版本:相容於 .NET Core (8、7、6、5、3.1+)、.NET Standard (2.0+) 及 .NET Framework (4.6.2+)。 應用環境:可在 Windows、Linux、Mac、Docker、Azure 和 AWS 環境中無縫運作。 支援的 IDE:與 Microsoft Visual Studio 和 JetBrains Rider & ReSharper 搭配使用。 作業系統與處理器:支援 Windows、Mac、Linux、x64、x86、ARM。 iTextPdf .NET版本:支援 .NET Core (2.x, 3.x)、.NET Framework (4.6.1+) 及 .NET 5+。 應用環境:相容於 Windows、macOS、Linux 和 Docker。 主要功能比較:IronPDF vs. iTextPdf 以下是每個函式庫所提供的主要功能的詳細比較。 IronPDF。 HTML 至 PDF 轉檔:支援 HTML、CSS、JavaScript 及圖片。 PDF Manipulation:分割、合併和編輯 PDF 文件。 安全性:PDF 加密和解密功能。 編輯:允許註解、書籤和大綱。 範本:套用頁眉、頁腳和頁碼。 水印:支援使用 HTML/CSS 進行控制的文字和影像水印。 PDF 印章:在 PDF 檔案上新增圖片和文字戳記。 如需瞭解 IronPDF 所提供的廣泛功能的詳細資訊,請造訪 IronPDF功能頁面。 iTextPdf PDF 創建:支援從頭開始建立 PDF 文件。 表格:提供 PDF 表單的建立與編輯。 數位簽名:簽署 PDF 文件。 壓縮:優化 PDF 檔案大小。 內容萃取:從 PDF 中萃取文字和影像。 自訂性:複雜專案的高度自訂性。 PDF 功能比較:IronPDF vs. iTextPdf HTML 至 PDF 轉換 這兩個函式庫都支援 HTML 至 PDF 的轉換,但在方法和易用性上有所不同。 IronPDF using IronPdf; // Instantiate the renderer var renderer = new ChromePdfRenderer(); // Create a PDF from an HTML string var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>"); pdf.SaveAs("output.pdf"); // Advanced example with external assets var myAdvancedPdf = renderer.RenderHtmlAsPdf("<img src='icons/iron.png'>", @"C:\site\assets\"); myAdvancedPdf.SaveAs("html-with-assets.pdf"); using IronPdf; // Instantiate the renderer var renderer = new ChromePdfRenderer(); // Create a PDF from an HTML string var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>"); pdf.SaveAs("output.pdf"); // Advanced example with external assets var myAdvancedPdf = renderer.RenderHtmlAsPdf("<img src='icons/iron.png'>", @"C:\site\assets\"); myAdvancedPdf.SaveAs("html-with-assets.pdf"); Imports IronPdf ' Instantiate the renderer Private renderer = New ChromePdfRenderer() ' Create a PDF from an HTML string Private pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>") pdf.SaveAs("output.pdf") ' Advanced example with external assets Dim myAdvancedPdf = renderer.RenderHtmlAsPdf("<img src='icons/iron.png'>", "C:\site\assets\") myAdvancedPdf.SaveAs("html-with-assets.pdf") $vbLabelText $csharpLabel iTextPdf using iText.Html2pdf; using System.IO; public class HtmlToPdf { public static void ConvertHtmlToPdf() { using (FileStream htmlSource = File.Open("input.html", FileMode.Open)) using (FileStream pdfDest = File.Open("output.pdf", FileMode.Create)) { ConverterProperties converterProperties = new ConverterProperties(); HtmlConverter.ConvertToPdf(htmlSource, pdfDest, converterProperties); } } } using iText.Html2pdf; using System.IO; public class HtmlToPdf { public static void ConvertHtmlToPdf() { using (FileStream htmlSource = File.Open("input.html", FileMode.Open)) using (FileStream pdfDest = File.Open("output.pdf", FileMode.Create)) { ConverterProperties converterProperties = new ConverterProperties(); HtmlConverter.ConvertToPdf(htmlSource, pdfDest, converterProperties); } } } Imports iText.Html2pdf Imports System.IO Public Class HtmlToPdf Public Shared Sub ConvertHtmlToPdf() Using htmlSource As FileStream = File.Open("input.html", FileMode.Open) Using pdfDest As FileStream = File.Open("output.pdf", FileMode.Create) Dim converterProperties As New ConverterProperties() HtmlConverter.ConvertToPdf(htmlSource, pdfDest, converterProperties) End Using End Using End Sub End Class $vbLabelText $csharpLabel IronPDF 提供了直接的 HTML 至 PDF 轉換方法,包括對 HTML、CSS 和 JavaScript 的支援。 它允許使用者直接從 HTML 字串轉換,或包含具有可選基本路徑的資產。 iTextPdf 雖然有效,但需要較多的設定,更側重於以檔案為基礎的轉換。 加密 PDF 檔案 在安全性極為重要的情況下,加密是不可或缺的。 以下是每個圖書館的處理方式。 IronPDF using IronPdf; // Load an encrypted PDF or create a new one var pdf = PdfDocument.FromFile("encrypted.pdf", "password"); // Set document security settings pdf.SecuritySettings.MakePdfDocumentReadOnly("secret-key"); pdf.SecuritySettings.AllowUserCopyPasteContent = false; pdf.Password = "my-password"; pdf.SaveAs("secured.pdf"); using IronPdf; // Load an encrypted PDF or create a new one var pdf = PdfDocument.FromFile("encrypted.pdf", "password"); // Set document security settings pdf.SecuritySettings.MakePdfDocumentReadOnly("secret-key"); pdf.SecuritySettings.AllowUserCopyPasteContent = false; pdf.Password = "my-password"; pdf.SaveAs("secured.pdf"); Imports IronPdf ' Load an encrypted PDF or create a new one Private pdf = PdfDocument.FromFile("encrypted.pdf", "password") ' Set document security settings pdf.SecuritySettings.MakePdfDocumentReadOnly("secret-key") pdf.SecuritySettings.AllowUserCopyPasteContent = False pdf.Password = "my-password" pdf.SaveAs("secured.pdf") $vbLabelText $csharpLabel iTextPdf using iText.Kernel.Pdf; using System.Text; public class EncryptPdf { public static readonly string DEST = "encrypt_pdf.pdf"; public static readonly string OWNER_PASSWORD = "World"; public static readonly string USER_PASSWORD = "Hello"; protected void ManipulatePdf(string dest) { PdfDocument document = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter(dest, new WriterProperties().SetStandardEncryption( Encoding.UTF8.GetBytes(USER_PASSWORD), Encoding.UTF8.GetBytes(OWNER_PASSWORD), EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128))); document.Close(); } } using iText.Kernel.Pdf; using System.Text; public class EncryptPdf { public static readonly string DEST = "encrypt_pdf.pdf"; public static readonly string OWNER_PASSWORD = "World"; public static readonly string USER_PASSWORD = "Hello"; protected void ManipulatePdf(string dest) { PdfDocument document = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter(dest, new WriterProperties().SetStandardEncryption( Encoding.UTF8.GetBytes(USER_PASSWORD), Encoding.UTF8.GetBytes(OWNER_PASSWORD), EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128))); document.Close(); } } Imports iText.Kernel.Pdf Imports System.Text Public Class EncryptPdf Public Shared ReadOnly DEST As String = "encrypt_pdf.pdf" Public Shared ReadOnly OWNER_PASSWORD As String = "World" Public Shared ReadOnly USER_PASSWORD As String = "Hello" Protected Sub ManipulatePdf(ByVal dest As String) Dim document As New PdfDocument(New PdfReader("input.pdf"), New PdfWriter(dest, (New WriterProperties()).SetStandardEncryption(Encoding.UTF8.GetBytes(USER_PASSWORD), Encoding.UTF8.GetBytes(OWNER_PASSWORD), EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128))) document.Close() End Sub End Class $vbLabelText $csharpLabel IronPDF 的方法對使用者較為友善,提供直接的 加密和文件權限控制。 iTextPdf 雖然有效,但需要詳細設定,並注重加密標準。 重製 PDF 內容 對 PDF 檔案中的資訊進行隱藏處理對於隱私權和安全性而言至關重要。 以下是每個函式庫如何支援此功能。 IronPDF using IronPdf; PdfDocument pdf = PdfDocument.FromFile("novel.pdf"); // Redact 'are' from all pages pdf.RedactTextOnAllPages("are"); pdf.SaveAs("redacted.pdf"); using IronPdf; PdfDocument pdf = PdfDocument.FromFile("novel.pdf"); // Redact 'are' from all pages pdf.RedactTextOnAllPages("are"); pdf.SaveAs("redacted.pdf"); Imports IronPdf Private pdf As PdfDocument = PdfDocument.FromFile("novel.pdf") ' Redact 'are' from all pages pdf.RedactTextOnAllPages("are") pdf.SaveAs("redacted.pdf") $vbLabelText $csharpLabel iTextPdf using iText.Kernel.Pdf; using iText.Kernel.Colors; // Define areas to redact on each page Rectangle[] rectanglesToRedact = { new Rectangle(100, 100, 200, 50) }; // Draw black rectangles to cover sensitive areas using (PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter("output_redacted.pdf"))) { for (int pageNum = 1; pageNum <= pdfDoc.GetNumberOfPages(); pageNum++) { PdfPage page = pdfDoc.GetPage(pageNum); PdfCanvas canvas = new PdfCanvas(page); foreach (Rectangle rect in rectanglesToRedact) { canvas.SetFillColor(ColorConstants.BLACK) .Rectangle(rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight()) .Fill(); } } } using iText.Kernel.Pdf; using iText.Kernel.Colors; // Define areas to redact on each page Rectangle[] rectanglesToRedact = { new Rectangle(100, 100, 200, 50) }; // Draw black rectangles to cover sensitive areas using (PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter("output_redacted.pdf"))) { for (int pageNum = 1; pageNum <= pdfDoc.GetNumberOfPages(); pageNum++) { PdfPage page = pdfDoc.GetPage(pageNum); PdfCanvas canvas = new PdfCanvas(page); foreach (Rectangle rect in rectanglesToRedact) { canvas.SetFillColor(ColorConstants.BLACK) .Rectangle(rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight()) .Fill(); } } } Imports iText.Kernel.Pdf Imports iText.Kernel.Colors ' Define areas to redact on each page Private rectanglesToRedact() As Rectangle = { New Rectangle(100, 100, 200, 50) } ' Draw black rectangles to cover sensitive areas Using pdfDoc As New PdfDocument(New PdfReader("input.pdf"), New PdfWriter("output_redacted.pdf")) Dim pageNum As Integer = 1 Do While pageNum <= pdfDoc.GetNumberOfPages() Dim page As PdfPage = pdfDoc.GetPage(pageNum) Dim canvas As New PdfCanvas(page) For Each rect As Rectangle In rectanglesToRedact canvas.SetFillColor(ColorConstants.BLACK).Rectangle(rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight()).Fill() Next rect pageNum += 1 Loop End Using $vbLabelText $csharpLabel IronPdf 提供方便的 刪除工具,可輕鬆隱藏所有頁面中的敏感文字。 相較之下,iTextPdf 則需要使用者手動定義並套用黑色矩形以覆蓋敏感區域。 簽署 PDF 文件 自動簽署 PDF 文件可以大幅節省時間。以下是 IronPDF 和 iTextPdf 處理數位簽章的並列比較。 IronPDF using IronPdf; using IronPdf.Signing; using System.Security.Cryptography.X509Certificates; // Create X509Certificate2 object with X509KeyStorageFlags set to Exportable X509Certificate2 cert = new X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable); // Create PdfSignature object var sig = new PdfSignature(cert); // Sign PDF document PdfDocument pdf = PdfDocument.FromFile("document.pdf"); pdf.Sign(sig); pdf.SaveAs("signed.pdf"); using IronPdf; using IronPdf.Signing; using System.Security.Cryptography.X509Certificates; // Create X509Certificate2 object with X509KeyStorageFlags set to Exportable X509Certificate2 cert = new X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable); // Create PdfSignature object var sig = new PdfSignature(cert); // Sign PDF document PdfDocument pdf = PdfDocument.FromFile("document.pdf"); pdf.Sign(sig); pdf.SaveAs("signed.pdf"); Imports IronPdf Imports IronPdf.Signing Imports System.Security.Cryptography.X509Certificates ' Create X509Certificate2 object with X509KeyStorageFlags set to Exportable Private cert As New X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable) ' Create PdfSignature object Private sig = New PdfSignature(cert) ' Sign PDF document Private pdf As PdfDocument = PdfDocument.FromFile("document.pdf") pdf.Sign(sig) pdf.SaveAs("signed.pdf") $vbLabelText $csharpLabel iTextPdf using System; using System.IO; using iText.Kernel.Pdf; using iText.Signatures; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.X509; class Program { static void Main(string[] args) { string src = "input.pdf"; string dest = "output_signed.pdf"; string pfxFile = "your_certificate.pfx"; string pfxPassword = "your_password"; try { // Load your certificate Pkcs12Store ks = new Pkcs12Store(new FileStream(pfxFile, FileMode.Open), pfxPassword.ToCharArray()); string alias = null; foreach (string al in ks.Aliases) { if (ks.IsKeyEntry(al)) { alias = al; break; } } ICipherParameters pk = ks.GetKey(alias).Key; X509CertificateEntry[] chain = ks.GetCertificateChain(alias); X509Certificate2 cert = new X509Certificate2(chain[0].Certificate.GetEncoded()); // Create output PDF with signed content using (PdfReader reader = new PdfReader(src)) { using (PdfWriter writer = new PdfWriter(dest)) { using (PdfDocument pdfDoc = new PdfDocument(reader, writer)) { // Create the signer PdfSigner signer = new PdfSigner(pdfDoc, writer, new StampingProperties().UseAppendMode()); // Configure signature appearance PdfSignatureAppearance appearance = signer.GetSignatureAppearance(); appearance.SetReason("Digital Signature"); appearance.SetLocation("Your Location"); appearance.SetContact("Your Contact"); // Create signature IExternalSignature pks = new PrivateKeySignature(pk, "SHA-256"); signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS); } } } Console.WriteLine($"PDF digitally signed successfully: {dest}"); } catch (Exception ex) { Console.WriteLine($"Error signing PDF: {ex.Message}"); } } } using System; using System.IO; using iText.Kernel.Pdf; using iText.Signatures; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.X509; class Program { static void Main(string[] args) { string src = "input.pdf"; string dest = "output_signed.pdf"; string pfxFile = "your_certificate.pfx"; string pfxPassword = "your_password"; try { // Load your certificate Pkcs12Store ks = new Pkcs12Store(new FileStream(pfxFile, FileMode.Open), pfxPassword.ToCharArray()); string alias = null; foreach (string al in ks.Aliases) { if (ks.IsKeyEntry(al)) { alias = al; break; } } ICipherParameters pk = ks.GetKey(alias).Key; X509CertificateEntry[] chain = ks.GetCertificateChain(alias); X509Certificate2 cert = new X509Certificate2(chain[0].Certificate.GetEncoded()); // Create output PDF with signed content using (PdfReader reader = new PdfReader(src)) { using (PdfWriter writer = new PdfWriter(dest)) { using (PdfDocument pdfDoc = new PdfDocument(reader, writer)) { // Create the signer PdfSigner signer = new PdfSigner(pdfDoc, writer, new StampingProperties().UseAppendMode()); // Configure signature appearance PdfSignatureAppearance appearance = signer.GetSignatureAppearance(); appearance.SetReason("Digital Signature"); appearance.SetLocation("Your Location"); appearance.SetContact("Your Contact"); // Create signature IExternalSignature pks = new PrivateKeySignature(pk, "SHA-256"); signer.SignDetached(pks, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS); } } } Console.WriteLine($"PDF digitally signed successfully: {dest}"); } catch (Exception ex) { Console.WriteLine($"Error signing PDF: {ex.Message}"); } } } Imports System Imports System.IO Imports iText.Kernel.Pdf Imports iText.Signatures Imports Org.BouncyCastle.Crypto Imports Org.BouncyCastle.Pkcs Imports Org.BouncyCastle.X509 Friend Class Program Shared Sub Main(ByVal args() As String) Dim src As String = "input.pdf" Dim dest As String = "output_signed.pdf" Dim pfxFile As String = "your_certificate.pfx" Dim pfxPassword As String = "your_password" Try ' Load your certificate Dim ks As New Pkcs12Store(New FileStream(pfxFile, FileMode.Open), pfxPassword.ToCharArray()) Dim [alias] As String = Nothing For Each al As String In ks.Aliases If ks.IsKeyEntry(al) Then [alias] = al Exit For End If Next al Dim pk As ICipherParameters = ks.GetKey([alias]).Key Dim chain() As X509CertificateEntry = ks.GetCertificateChain([alias]) Dim cert As New X509Certificate2(chain(0).Certificate.GetEncoded()) ' Create output PDF with signed content Using reader As New PdfReader(src) Using writer As New PdfWriter(dest) Using pdfDoc As New PdfDocument(reader, writer) ' Create the signer Dim signer As New PdfSigner(pdfDoc, writer, (New StampingProperties()).UseAppendMode()) ' Configure signature appearance Dim appearance As PdfSignatureAppearance = signer.GetSignatureAppearance() appearance.SetReason("Digital Signature") appearance.SetLocation("Your Location") appearance.SetContact("Your Contact") ' Create signature Dim pks As IExternalSignature = New PrivateKeySignature(pk, "SHA-256") signer.SignDetached(pks, chain, Nothing, Nothing, Nothing, 0, PdfSigner.CryptoStandard.CMS) End Using End Using End Using Console.WriteLine($"PDF digitally signed successfully: {dest}") Catch ex As Exception Console.WriteLine($"Error signing PDF: {ex.Message}") End Try End Sub End Class $vbLabelText $csharpLabel 當提到要將 數位簽章套用至 PDF 檔案時,IronPDF 提供了直接有效的方式,利用 X509 憑證來完成這項工作。 其 API 簡化了流程,使其容易整合到工作流程中,而不會犧牲對簽章安全性的控制。 相較之下,iTextPDF 簽署文件的流程設定較為複雜,但提供額外的客製化選項。 開發人員擁有更細緻的控制權,儘管他們在瀏覽 iTextPDF 的簽章設定和憑證處理時,可能會面臨較陡峭的學習曲線。 將水印套用至 PDF 文件 PDF 的水印對於品牌、機密性和版權保護來說是不可或缺的。 以下是 IronPDF 和 iTextPDF 如何將水印套用至 PDF 文件。 IronPDF using IronPdf; // Stamps a Watermark onto a new or existing PDF var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderUrlAsPdf("https://www.nuget.org/packages/IronPdf"); pdf.ApplyWatermark("<h2 style='color:red'>SAMPLE</h2>", 30, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center); pdf.SaveAs(@"C:\Path\To\Watermarked.pdf"); using IronPdf; // Stamps a Watermark onto a new or existing PDF var renderer = new ChromePdfRenderer(); var pdf = renderer.RenderUrlAsPdf("https://www.nuget.org/packages/IronPdf"); pdf.ApplyWatermark("<h2 style='color:red'>SAMPLE</h2>", 30, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center); pdf.SaveAs(@"C:\Path\To\Watermarked.pdf"); Imports IronPdf ' Stamps a Watermark onto a new or existing PDF Private renderer = New ChromePdfRenderer() Private pdf = renderer.RenderUrlAsPdf("https://www.nuget.org/packages/IronPdf") pdf.ApplyWatermark("<h2 style='color:red'>SAMPLE</h2>", 30, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center) pdf.SaveAs("C:\Path\To\Watermarked.pdf") $vbLabelText $csharpLabel iTextPdf using iText.IO.Font; using iText.IO.Font.Constants; using iText.Kernel.Colors; using iText.Kernel.Font; using iText.Kernel.Pdf; using iText.Kernel.Pdf.Canvas; using iText.Kernel.Pdf.Extgstate; using iText.Layout; using iText.Layout.Element; using iText.Layout.Properties; public class TransparentWatermark { public static readonly string DEST = "results/sandbox/stamper/transparent_watermark.pdf"; public static readonly string SRC = "../../../resources/pdfs/hero.pdf"; public static void Main(string[] args) { FileInfo file = new FileInfo(DEST); file.Directory.Create(); new TransparentWatermark().ManipulatePdf(DEST); } protected void ManipulatePdf(string dest) { PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest)); PdfCanvas under = new PdfCanvas(pdfDoc.GetFirstPage().NewContentStreamBefore(), new PdfResources(), pdfDoc); PdfFont font = PdfFontFactory.CreateFont(FontProgramFactory.CreateFont(StandardFonts.HELVETICA)); Paragraph paragraph = new Paragraph("This watermark is added UNDER the existing content") .SetFont(font) .SetFontSize(15); Canvas canvasWatermark1 = new Canvas(under, pdfDoc.GetDefaultPageSize()) .ShowTextAligned(paragraph, 297, 550, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0); canvasWatermark1.Close(); PdfCanvas over = new PdfCanvas(pdfDoc.GetFirstPage()); over.SetFillColor(ColorConstants.BLACK); paragraph = new Paragraph("This watermark is added ON TOP OF the existing content") .SetFont(font) .SetFontSize(15); Canvas canvasWatermark2 = new Canvas(over, pdfDoc.GetDefaultPageSize()) .ShowTextAligned(paragraph, 297, 500, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0); canvasWatermark2.Close(); paragraph = new Paragraph("This TRANSPARENT watermark is added ON TOP OF the existing content") .SetFont(font) .SetFontSize(15); over.SaveState(); PdfExtGState gs1 = new PdfExtGState(); gs1.SetFillOpacity(0.5f); over.SetExtGState(gs1); Canvas canvasWatermark3 = new Canvas(over, pdfDoc.GetDefaultPageSize()) .ShowTextAligned(paragraph, 297, 450, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0); canvasWatermark3.Close(); over.RestoreState(); pdfDoc.Close(); } } using iText.IO.Font; using iText.IO.Font.Constants; using iText.Kernel.Colors; using iText.Kernel.Font; using iText.Kernel.Pdf; using iText.Kernel.Pdf.Canvas; using iText.Kernel.Pdf.Extgstate; using iText.Layout; using iText.Layout.Element; using iText.Layout.Properties; public class TransparentWatermark { public static readonly string DEST = "results/sandbox/stamper/transparent_watermark.pdf"; public static readonly string SRC = "../../../resources/pdfs/hero.pdf"; public static void Main(string[] args) { FileInfo file = new FileInfo(DEST); file.Directory.Create(); new TransparentWatermark().ManipulatePdf(DEST); } protected void ManipulatePdf(string dest) { PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest)); PdfCanvas under = new PdfCanvas(pdfDoc.GetFirstPage().NewContentStreamBefore(), new PdfResources(), pdfDoc); PdfFont font = PdfFontFactory.CreateFont(FontProgramFactory.CreateFont(StandardFonts.HELVETICA)); Paragraph paragraph = new Paragraph("This watermark is added UNDER the existing content") .SetFont(font) .SetFontSize(15); Canvas canvasWatermark1 = new Canvas(under, pdfDoc.GetDefaultPageSize()) .ShowTextAligned(paragraph, 297, 550, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0); canvasWatermark1.Close(); PdfCanvas over = new PdfCanvas(pdfDoc.GetFirstPage()); over.SetFillColor(ColorConstants.BLACK); paragraph = new Paragraph("This watermark is added ON TOP OF the existing content") .SetFont(font) .SetFontSize(15); Canvas canvasWatermark2 = new Canvas(over, pdfDoc.GetDefaultPageSize()) .ShowTextAligned(paragraph, 297, 500, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0); canvasWatermark2.Close(); paragraph = new Paragraph("This TRANSPARENT watermark is added ON TOP OF the existing content") .SetFont(font) .SetFontSize(15); over.SaveState(); PdfExtGState gs1 = new PdfExtGState(); gs1.SetFillOpacity(0.5f); over.SetExtGState(gs1); Canvas canvasWatermark3 = new Canvas(over, pdfDoc.GetDefaultPageSize()) .ShowTextAligned(paragraph, 297, 450, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0); canvasWatermark3.Close(); over.RestoreState(); pdfDoc.Close(); } } Imports iText.IO.Font Imports iText.IO.Font.Constants Imports iText.Kernel.Colors Imports iText.Kernel.Font Imports iText.Kernel.Pdf Imports iText.Kernel.Pdf.Canvas Imports iText.Kernel.Pdf.Extgstate Imports iText.Layout Imports iText.Layout.Element Imports iText.Layout.Properties Public Class TransparentWatermark Public Shared ReadOnly DEST As String = "results/sandbox/stamper/transparent_watermark.pdf" Public Shared ReadOnly SRC As String = "../../../resources/pdfs/hero.pdf" Public Shared Sub Main(ByVal args() As String) Dim file As New FileInfo(DEST) file.Directory.Create() Call (New TransparentWatermark()).ManipulatePdf(DEST) End Sub Protected Sub ManipulatePdf(ByVal dest As String) Dim pdfDoc As New PdfDocument(New PdfReader(SRC), New PdfWriter(dest)) Dim under As New PdfCanvas(pdfDoc.GetFirstPage().NewContentStreamBefore(), New PdfResources(), pdfDoc) Dim font As PdfFont = PdfFontFactory.CreateFont(FontProgramFactory.CreateFont(StandardFonts.HELVETICA)) Dim paragraph As Paragraph = (New Paragraph("This watermark is added UNDER the existing content")).SetFont(font).SetFontSize(15) Dim canvasWatermark1 As Canvas = (New Canvas(under, pdfDoc.GetDefaultPageSize())).ShowTextAligned(paragraph, 297, 550, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0) canvasWatermark1.Close() Dim over As New PdfCanvas(pdfDoc.GetFirstPage()) over.SetFillColor(ColorConstants.BLACK) paragraph = (New Paragraph("This watermark is added ON TOP OF the existing content")).SetFont(font).SetFontSize(15) Dim canvasWatermark2 As Canvas = (New Canvas(over, pdfDoc.GetDefaultPageSize())).ShowTextAligned(paragraph, 297, 500, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0) canvasWatermark2.Close() paragraph = (New Paragraph("This TRANSPARENT watermark is added ON TOP OF the existing content")).SetFont(font).SetFontSize(15) over.SaveState() Dim gs1 As New PdfExtGState() gs1.SetFillOpacity(0.5F) over.SetExtGState(gs1) Dim canvasWatermark3 As Canvas = (New Canvas(over, pdfDoc.GetDefaultPageSize())).ShowTextAligned(paragraph, 297, 450, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0) canvasWatermark3.Close() over.RestoreState() pdfDoc.Close() End Sub End Class $vbLabelText $csharpLabel IronPDF 的 API 可實現快速直觀的 水印應用程式,並可靈活使用 HTML 和 CSS 進行客製化。 另一方面,iTextPDF 可透過其更詳細的設定選項高度自訂水印位置,不過需要更大量的編碼工作。 在 PDF 上標示圖片和文字 在 PDF 上燙印內容與套用水印類似,但更著重於加入特定元素,例如圖片或文字,以達到標籤或品牌的目的。 以下是 IronPdf 和 iTextPDF 如何執行這項任務。 IronPDF using IronPdf; using IronPdf.Editing; ChromePdfRenderer renderer = new ChromePdfRenderer(); PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Example HTML Document!</h1>"); // Create text stamper TextStamper textStamper = new TextStamper() { Text = "Text Stamper!", FontFamily = "Bungee Spice", UseGoogleFont = true, FontSize = 30, IsBold = true, IsItalic = true, VerticalAlignment = VerticalAlignment.Top, }; // Stamp the text stamper pdf.ApplyStamp(textStamper); pdf.SaveAs("stampText.pdf"); // Create image stamper ImageStamper imageStamper = new ImageStamper(new Uri("https://ironpdf.com/img/svgs/iron-pdf-logo.svg")) { VerticalAlignment = VerticalAlignment.Top, }; // Stamp the image stamper pdf.ApplyStamp(imageStamper, 0); pdf.SaveAs("stampImage.pdf"); using IronPdf; using IronPdf.Editing; ChromePdfRenderer renderer = new ChromePdfRenderer(); PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>Example HTML Document!</h1>"); // Create text stamper TextStamper textStamper = new TextStamper() { Text = "Text Stamper!", FontFamily = "Bungee Spice", UseGoogleFont = true, FontSize = 30, IsBold = true, IsItalic = true, VerticalAlignment = VerticalAlignment.Top, }; // Stamp the text stamper pdf.ApplyStamp(textStamper); pdf.SaveAs("stampText.pdf"); // Create image stamper ImageStamper imageStamper = new ImageStamper(new Uri("https://ironpdf.com/img/svgs/iron-pdf-logo.svg")) { VerticalAlignment = VerticalAlignment.Top, }; // Stamp the image stamper pdf.ApplyStamp(imageStamper, 0); pdf.SaveAs("stampImage.pdf"); Imports IronPdf Imports IronPdf.Editing Private renderer As New ChromePdfRenderer() Private pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>Example HTML Document!</h1>") ' Create text stamper Private textStamper As New TextStamper() With { .Text = "Text Stamper!", .FontFamily = "Bungee Spice", .UseGoogleFont = True, .FontSize = 30, .IsBold = True, .IsItalic = True, .VerticalAlignment = VerticalAlignment.Top } ' Stamp the text stamper pdf.ApplyStamp(textStamper) pdf.SaveAs("stampText.pdf") ' Create image stamper Dim imageStamper As New ImageStamper(New Uri("https://ironpdf.com/img/svgs/iron-pdf-logo.svg")) With {.VerticalAlignment = VerticalAlignment.Top} ' Stamp the image stamper pdf.ApplyStamp(imageStamper, 0) pdf.SaveAs("stampImage.pdf") $vbLabelText $csharpLabel iTextPdf using iText.Kernel.Pdf; using iText.Layout; using iText.Layout.Element; public void StampPDF(string inputPdfPath, string outputPdfPath, string stampText) { PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPdfPath), new PdfWriter(outputPdfPath)); Document doc = new Document(pdfDoc); // Add stamp (text) to each page int numPages = pdfDoc.GetNumberOfPages(); for (int i = 1; i <= numPages; i++) { doc.ShowTextAligned(new Paragraph(stampText), 36, 36, i, iText.Layout.Properties.TextAlignment.LEFT, iText.Layout.Properties.VerticalAlignment.TOP, 0); } doc.Close(); } using iText.Kernel.Pdf; using iText.Layout; using iText.Layout.Element; public void StampPDF(string inputPdfPath, string outputPdfPath, string stampText) { PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPdfPath), new PdfWriter(outputPdfPath)); Document doc = new Document(pdfDoc); // Add stamp (text) to each page int numPages = pdfDoc.GetNumberOfPages(); for (int i = 1; i <= numPages; i++) { doc.ShowTextAligned(new Paragraph(stampText), 36, 36, i, iText.Layout.Properties.TextAlignment.LEFT, iText.Layout.Properties.VerticalAlignment.TOP, 0); } doc.Close(); } Imports iText.Kernel.Pdf Imports iText.Layout Imports iText.Layout.Element Public Sub StampPDF(ByVal inputPdfPath As String, ByVal outputPdfPath As String, ByVal stampText As String) Dim pdfDoc As New PdfDocument(New PdfReader(inputPdfPath), New PdfWriter(outputPdfPath)) Dim doc As New Document(pdfDoc) ' Add stamp (text) to each page Dim numPages As Integer = pdfDoc.GetNumberOfPages() For i As Integer = 1 To numPages doc.ShowTextAligned(New Paragraph(stampText), 36, 36, i, iText.Layout.Properties.TextAlignment.LEFT, iText.Layout.Properties.VerticalAlignment.TOP, 0) Next i doc.Close() End Sub $vbLabelText $csharpLabel IronPdf 的 圖像和文字戳記方法簡化且功能多樣,讓開發人員可以輕鬆地在 PDF 頁面上新增品牌內容或標籤。 API 利用熟悉的 HTML/CSS 造型元素,讓客製化變得簡單直接。 iTextPDF 也提供圖片和文字戳記功能,不過其設定需要較多的手動設定和 PDF 排版結構的工作知識。 直接在 PDF 頁面上處理和樣式化內容的能力,為開發人員提供了強大的戳記工具,不過 iTextPDF 的設定可能需要多花一點心思。 將 DOCX 轉換為 PDF。 在某些專案中,需要將 DOCX 檔案轉換為 PDF 格式。 以下是 IronPDF 和 iText 處理這項任務的比較,強調兩者的差異。 IronPDF using IronPdf; // Instantiate Renderer DocxToPdfRenderer renderer = new DocxToPdfRenderer(); // Render from DOCX file PdfDocument pdf = renderer.RenderDocxAsPdf("Modern-chronological-resume.docx"); // Save the PDF pdf.SaveAs("pdfFromDocx.pdf"); using IronPdf; // Instantiate Renderer DocxToPdfRenderer renderer = new DocxToPdfRenderer(); // Render from DOCX file PdfDocument pdf = renderer.RenderDocxAsPdf("Modern-chronological-resume.docx"); // Save the PDF pdf.SaveAs("pdfFromDocx.pdf"); Imports IronPdf ' Instantiate Renderer Private renderer As New DocxToPdfRenderer() ' Render from DOCX file Private pdf As PdfDocument = renderer.RenderDocxAsPdf("Modern-chronological-resume.docx") ' Save the PDF pdf.SaveAs("pdfFromDocx.pdf") $vbLabelText $csharpLabel iTextPDF 與 IronPDF 不同,iTextPDF 沒有內建將 DOCX 轉換為 PDF 的支援。 若要執行此轉換,開發人員必須仰賴 DocX 或 Aspose.Words 等第三方函式庫,先將 DOCX 檔案轉換為 PDF 相容格式,然後再使用 iTextPDF 進行處理或修改。 IronPDF 為 DOCX 到 PDF 的轉換提供了直接、內建的解決方案,不需要額外的函式庫。 這使得它非常適合需要快速整合方法的開發人員。 相較之下,iTextPDF 依賴外部函式庫來轉換 DOCX 檔案,需要額外的設定和依賴,這可能會增加專案的複雜性。 Bootstrap 與現代 CSS 架構支援。 從 Bootstrap 風格的 Web 應用程式產生 PDF 時,完整的框架支援可確保設計的一致性,而不需要平行的 CSS 檔案或版面修改。 IronPDF。:完整的 Bootstrap 框架支援。 IronPDF 的 Chromium 引擎提供完整的支援: Bootstrap 5:完整的 flexbox 布局、CSS Grid、實用類型、所有元件 Bootstrap 4:完整的卡片系統、導航、flex 公用程式、反應式設計 Tailwind CSS:具有瀏覽器精確呈現的所有實用類別 基礎:完整的網格系統和元件庫 現代 CSS3:Flexbox、CSS Grid、自訂屬性、動畫、轉場 真實世界驗證:IronPDF 以像素級的精確度渲染 Bootstrap 首頁和所有 官方範例。 iTextPDF:有限的 Bootstrap 支援 iTextPDF 使用具有選擇性 CSS3 支援的 pdfHTML: 有限的 flexbox 支援:在 7.1.15 版中新增,但不完整 No CSS Grid:不支援基於網格的 Bootstrap 佈局 Bootstrap 3 的限制:現代 Bootstrap 4/5 元件需要解決方案 手動版面轉換:複雜的版面通常需要 PDF 特定的程式碼 iTextPDF 的說明文件明確指出,進階的 CSS 功能可能無法如預期般呈現,因此開發人員必須測試每個 Bootstrap 元件,並經常建立簡化的版面。 開發影響:團隊必須維護用於生成 PDF 的單獨佈局代碼,或者廣泛測試和修改 Bootstrap 元件,從而增加開發時間並減少設計一致性。 如需全面的 Bootstrap 框架指南和 CSS3 渲染功能,請參閱 Bootstrap & Flexbox CSS 指南。 程式碼範例比較摘要 。 如需更詳細的範例,請造訪 IronPDF範例。 定價與授權:IronPDF vs. iTextPdf Library IronPDF。 定價與授權 IronPDF 有不同等級和購買授權的附加功能。 開發人員也可以購買 Iron Suite,以兩件產品的價格即可使用 IronSoftware 的所有產品。 如果您尚未準備好購買授權,IronPDF 提供 免費試用。 永久授權:根據您的團隊規模、專案需求和地點數量,提供一系列永久授權。 每種授權類型都附有電子郵件支援。 Lite License:此授權費用為 $799 並支援一位開發人員、一個地點和一個專案。 Plus License: 支援三位開發人員、三個地點和三個專案,這是 Lite License 的進階版本,費用為 $1,199。 Plus License 除了提供基本的電子郵件支援外,還提供聊天支援和電話支援。 Professional License:此 License 適合較大規模的團隊,可支援十位開發人員、十個地點和十個專案,費用為 $2,399 。 它提供與前幾層相同的聯絡支援管道,但也提供螢幕分享支援。 免版稅再發行: IronPDF 的授權也提供免版稅再發行的保障,只需額外支付 $2,399 即可。 不間斷的產品支援: IronPdf 提供持續的產品更新、安全功能升級,以及工程團隊的支援,費用為 999 美元/年或一次性購買 5 年保障的 1,999 美元。 Iron Suite:只需 $1,498 即可使用所有 Iron Software 產品,包括 IronPDF、IronOCR、IronWord、IronXL、IronBarcode、IronQR、IronZIP、IronPrint 和 IronWebScraper。 。 iTextPDF 授權 AGPL 授權條款:iTextPDF Core 函式庫以 AGPL 授權條款開放原始碼,在符合條件下可自由使用。 開發人員必須以相同的授權釋出任何修改。 商業授權:對於不符合 AGPL 條件的開發人員,iTextPDF 透過引用模式提供商業授權。 文件和支援:IronPDF vs. iTextPdf IronPDF。 全面的說明文件: 涵蓋其所有功能的廣泛且友善的說明文件。 24/5 支援:提供積極的工程師支援。 視訊教學:YouTube 上提供了分步視訊指南。 社群論壇:提供額外支援的參與社群。 定期更新:每月進行產品更新,以確保提供最新的功能和安全修補程式。 iTextPDF iTextPDF 為其廣泛的功能集提供強大的文件和支援。 說明文件:iText PDF 說明文件徹底涵蓋可用的功能。 範例與教學:程式碼範例和教學可幫助開發人員入門。 GitHub 社群:開發人員可以報告問題、提交拉取請求,並與 iTextPDF 團隊互動。 定期更新:iTextPDF 提供頻繁的更新和改進。 有關 IronPDF 文件和支援的詳細資訊,請造訪 IronPDF 文件 和 IronSoftware YouTube 頻道。 結論 在 .NET 的 PDF 操作工具領域中,IronPDF 和 iTextPDF 都為開發人員提供了強大的解決方案。 IronPDF for .NET 以其跨 .NET 平台的簡單整合和人性化功能脫穎而出,例如 DOCX 到 PDF 的轉換,無需外部依賴。 相比之下,iTextPDF 以其多功能性和豐富的功能集著稱,仍然是一個功能強大的選擇,尤其是與其他工具搭配使用時,儘管它需要額外的依賴才能進行 DOCX 轉換。 最終,在 IronPDF 和 iTextPDF 之間做選擇,將取決於您專案的特定需求、授權偏好,以及所需的支援層級。 這兩個函式庫都提供了可靠的方式來簡化 .NET 應用程式中的 PDF 工作流程。 請注意iTextPDF 是其各自擁有者的註冊商標。 本網站與 iTextPDF 無任何關聯、背書或贊助。 所有產品名稱、標誌和品牌均為其各自擁有者的財產。 比較資料僅供參考,並反映撰寫時的公開資訊。 常見問題解答 如何在 C# 中將 HTML 轉換為 PDF? 您可以使用 IronPDF 的 RenderHtmlAsPdf 方法將 HTML 字串轉換成 PDF。您也可以使用 RenderHtmlFileAsPdf 將 HTML 檔案轉換成 PDF。 IronPDF 在 PDF 創建和處理方面提供哪些功能? IronPDF 提供 HTML 至 PDF 轉換、PDF 合併、加密、數位簽名、水印以及 DOCX 至 PDF 轉換等功能。 IronPDF 如何簡化 PDF 簽署? IronPDF 允許您使用 X509 憑證對 PDF 檔案套用數位簽章,提供一種直接的方法來保護您的文件。 IronPDF 可以在不同的作業系統上使用嗎? 是的,IronPDF 支持跨平台兼容性。它可以在 Windows、Linux 和 Mac 上無縫運作,並與 .NET Core、.NET Standard 和 .NET Framework 相容。 在文件加密方面,iTextPDF 與 IronPDF 有何不同? iTextPDF 提供加密標準的詳細設定,而 IronPDF 則透過容易實作的內建加密方法簡化流程。 IronPDF 用戶可獲得哪些支援資源? IronPDF 透過全面的文件、視訊教學、社群論壇和 24/5 工程師支援,提供廣泛的支援。 IronPDF 如何處理 DOCX 至 PDF 的轉換? IronPDF 包含 DOCX 至 PDF 的原生轉換功能,可無縫整合而不需要額外的函式庫。 IronPDF 有哪些授權選項? IronPDF 提供 Lite、Plus、Professional 等不同層級的永久 License,以及免權利金再授權和持續產品支援的選項。 如何使用 IronPDF 為 PDF 套用水印? IronPDF 可讓您使用 HTML 和 CSS 輕鬆套用水印,使您能夠快速新增文字或圖片水印,並根據需要自訂水印。 IronPDF 為什麼適合使用 .NET 應用程式的開發人員? IronPDF 採用簡化的 API 設計,對使用者友善,使其能有效率地執行 HTML 轉換為 PDF、加密和數位簽章等任務,非常適合 .NET 開發人員使用。 Curtis Chau 立即與工程團隊聊天 技術作家 Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。 相關文章 發表日期 12月 18, 2025 哪個 ASP PDF 函式庫能為 .NET Core 開發帶來最大價值? 發現適用於 ASP.NET Core 應用程式的最佳 PDF 庫。比較 IronPDF 的 Chrome 引擎與 Aspose 和 Syncfusion 的替代方案。 閱讀更多 發表日期 12月 3, 2025 IronPDF vs iTextSharp HTML to PDF with Header and Footer in PDF Document 比較 iTextSharp 和 IronPDF 在 PDF 中加入頁首和頁尾的功能。程式碼範例、頁碼和 HTML 標頭實作。 閱讀更多 發表日期 12月 3, 2025 使用 IronPDF 解決 iTextSharp HTML to PDF 中的 「文件無頁 」錯誤 iTextSharp HTML to PDF 在解析失敗時不會發生頁面錯誤。瞭解 XMLWorker 為何會有同樣的問題,並發現 IronPDF 可靠的 HTML 轉換解決方案。 閱讀更多 IronPDF 和 PDFreactor 的比較IronPDF對比GemBox.Pdf:完整.NE...
發表日期 12月 18, 2025 哪個 ASP PDF 函式庫能為 .NET Core 開發帶來最大價值? 發現適用於 ASP.NET Core 應用程式的最佳 PDF 庫。比較 IronPDF 的 Chrome 引擎與 Aspose 和 Syncfusion 的替代方案。 閱讀更多
發表日期 12月 3, 2025 IronPDF vs iTextSharp HTML to PDF with Header and Footer in PDF Document 比較 iTextSharp 和 IronPDF 在 PDF 中加入頁首和頁尾的功能。程式碼範例、頁碼和 HTML 標頭實作。 閱讀更多
發表日期 12月 3, 2025 使用 IronPDF 解決 iTextSharp HTML to PDF 中的 「文件無頁 」錯誤 iTextSharp HTML to PDF 在解析失敗時不會發生頁面錯誤。瞭解 XMLWorker 為何會有同樣的問題,並發現 IronPDF 可靠的 HTML 轉換解決方案。 閱讀更多