發現2025年最好的Mac PDF編輯器
Full Comparison
Looking for a detailed feature-by-feature breakdown? See how IronPDF stacks up against Itext on pricing, HTML support, and licensing.
IronPDF透過基於屬性的配置和原生的HTML支援簡化了PDF標題和頁腳的建立,而iText則需要實現PdfPageEventHelper並手動計算坐標以準確定位。
在製作專業的PDF文件時——如商業報告、發票、技術文件——一致的標題和頁腳代表了質量並加強了品牌形象。 曾使用過iText的開發者知道這個挑戰:新增標題和頁腳意味著必須撰寫頁面事件處理器、計算坐標,並在低層次處理字體。 IronPDF採取了一種根本不同的方法,讓您描述想要的內容,而不是指定每個像素。 本指南並排比較了這兩個程式庫,以便您為下一個專案做出明智的決定。
如何安裝IronPDF?
在深入比較之前,這是如何在.NET 10專案中新增IronPDF的方法。 使用.NET CLI或Visual Studio中的NuGet包管理器主控台:
dotnet add package IronPdf
# Or in the NuGet Package Manager Console:
# Install-Package IronPdf
dotnet add package IronPdf
# Or in the NuGet Package Manager Console:
# Install-Package IronPdf
安裝後,在應用程式啟動時新增一次性授權金鑰調用:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"
IronPDF NuGet package針對.NET 8+,並附帶一個捆綁的Chromium引擎,因此不需要額外的運行時依賴。 您可以獲得免費試用授權以便在承擔之前評估IronPDF在您的環境中的運行情況。
iText標題和頁腳實現面臨的挑戰是什麼?
使用iText需要實現OnEndPage方法以新增標題和頁腳。 這種方法涉及直接操作PdfContentByte物件及精確的坐標計算。 與現代HTML到PDF解決方案不同,iText的事件驅動架構需要深入了解PDF結構和坐標系統。
坐標系統從頁面左下角開始,這與大多數開發者對佈局的思考方式相悖。 這直接源於PDF規範如何定義頁面坐標空間。 任何時候頁面大小改變——比如從A4切換到Letter——每個坐標值都需要重新計算。 在標題下新增下劃線、居中文字或將頁腳對齊右邊緣都需要明確的數字偏移量。
public class HeaderFooterEvent : PdfPageEventHelper
{
private readonly Font headerFont = new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD);
private readonly Font footerFont = new Font(Font.FontFamily.HELVETICA, 10);
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfContentByte cb = writer.DirectContent;
// Add header text -- requires precise Y coordinate calculation
float headerY = document.PageSize.Height - 30;
ColumnText.ShowTextAligned(cb, Element.ALIGN_CENTER,
new Phrase("Company Report", headerFont),
document.PageSize.Width / 2, headerY, 0);
// Draw underline manually
cb.MoveTo(40, headerY - 5);
cb.LineTo(document.PageSize.Width - 40, headerY - 5);
cb.Stroke();
// Add footer with page number
string footerText = $"Page {writer.PageNumber}";
ColumnText.ShowTextAligned(cb, Element.ALIGN_RIGHT,
new Phrase(footerText, footerFont),
document.PageSize.Width - 40, 30, 0);
// Add date on left side
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
new Phrase(DateTime.Now.ToString("MM/dd/yyyy"), footerFont),
40, 30, 0);
}
}
// Usage
PdfWriter writer = PdfWriter.GetInstance(document, stream);
writer.PageEvent = new HeaderFooterEvent();
public class HeaderFooterEvent : PdfPageEventHelper
{
private readonly Font headerFont = new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD);
private readonly Font footerFont = new Font(Font.FontFamily.HELVETICA, 10);
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfContentByte cb = writer.DirectContent;
// Add header text -- requires precise Y coordinate calculation
float headerY = document.PageSize.Height - 30;
ColumnText.ShowTextAligned(cb, Element.ALIGN_CENTER,
new Phrase("Company Report", headerFont),
document.PageSize.Width / 2, headerY, 0);
// Draw underline manually
cb.MoveTo(40, headerY - 5);
cb.LineTo(document.PageSize.Width - 40, headerY - 5);
cb.Stroke();
// Add footer with page number
string footerText = $"Page {writer.PageNumber}";
ColumnText.ShowTextAligned(cb, Element.ALIGN_RIGHT,
new Phrase(footerText, footerFont),
document.PageSize.Width - 40, 30, 0);
// Add date on left side
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
new Phrase(DateTime.Now.ToString("MM/dd/yyyy"), footerFont),
40, 30, 0);
}
}
// Usage
PdfWriter writer = PdfWriter.GetInstance(document, stream);
writer.PageEvent = new HeaderFooterEvent();
Imports iTextSharp.text
Imports iTextSharp.text.pdf
Public Class HeaderFooterEvent
Inherits PdfPageEventHelper
Private ReadOnly headerFont As Font = New Font(Font.FontFamily.HELVETICA, 12, Font.BOLD)
Private ReadOnly footerFont As Font = New Font(Font.FontFamily.HELVETICA, 10)
Public Overrides Sub OnEndPage(writer As PdfWriter, document As Document)
Dim cb As PdfContentByte = writer.DirectContent
' Add header text -- requires precise Y coordinate calculation
Dim headerY As Single = document.PageSize.Height - 30
ColumnText.ShowTextAligned(cb, Element.ALIGN_CENTER,
New Phrase("Company Report", headerFont),
document.PageSize.Width / 2, headerY, 0)
' Draw underline manually
cb.MoveTo(40, headerY - 5)
cb.LineTo(document.PageSize.Width - 40, headerY - 5)
cb.Stroke()
' Add footer with page number
Dim footerText As String = $"Page {writer.PageNumber}"
ColumnText.ShowTextAligned(cb, Element.ALIGN_RIGHT,
New Phrase(footerText, footerFont),
document.PageSize.Width - 40, 30, 0)
' Add date on left side
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
New Phrase(DateTime.Now.ToString("MM/dd/yyyy"), footerFont),
40, 30, 0)
End Sub
End Class
' Usage
Dim writer As PdfWriter = PdfWriter.GetInstance(document, stream)
writer.PageEvent = New HeaderFooterEvent()
當處理不同的頁面方向、自訂紙張尺寸或不同的邊距需求時,這種手動定位方法變得更加複雜。 對於需要PDF/A合規或數位簽名的生產系統來說,手動方法增加了大量的維護開銷。
具有基本標題的輸出是什麼樣的?

上述程式碼展示了所需的手動工作——您必須計算精確的坐標、單獨管理字體,並通過DirectContent處理渲染。 每次設計變更意味著編輯分散在整個事件處理器中的數字常量。
為什麼基於坐標的佈局會引發維護問題?
當設計變更到來——移動logo,調整字體大小,將日期移到中心——開發人員必須追蹤像素偏移來理解要更改的內容。 沒有可視層; 程式碼本身是唯一的佈局規格。 這使得開發者之間的交接容易出錯,並增加了即使是微小視覺修訂所需的時間。
IronPDF如何簡化標題和頁腳的建立?
IronPDF通過直觀的API改變了標題和頁腳的建立過程。 您不需要實現事件處理器,而是通過簡單的屬性設置在ChromePdfRenderer上配置標題和頁腳。 這種方法符合現代.NET開發的實踐,並大大降低了學習難度。
using IronPdf;
var renderer = new ChromePdfRenderer();
// Configure text header with multiple properties
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Company Report",
LeftText = "CONFIDENTIAL",
RightText = DateTime.Now.ToString("MMMM yyyy"),
DrawDividerLine = true,
FontSize = 12,
FontFamily = "Arial",
Spacing = 5
};
// Configure text footer with dynamic placeholders
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
LeftText = "{date} {time}",
CenterText = "© 2024 Company Name",
RightText = "Page {page} of {total-pages}",
DrawDividerLine = true,
FontSize = 10,
Spacing = 10
};
// Set margins to ensure proper spacing
renderer.RenderingOptions.MarginTop = 30;
renderer.RenderingOptions.MarginBottom = 25;
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("report.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
// Configure text header with multiple properties
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Company Report",
LeftText = "CONFIDENTIAL",
RightText = DateTime.Now.ToString("MMMM yyyy"),
DrawDividerLine = true,
FontSize = 12,
FontFamily = "Arial",
Spacing = 5
};
// Configure text footer with dynamic placeholders
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
LeftText = "{date} {time}",
CenterText = "© 2024 Company Name",
RightText = "Page {page} of {total-pages}",
DrawDividerLine = true,
FontSize = 10,
Spacing = 10
};
// Set margins to ensure proper spacing
renderer.RenderingOptions.MarginTop = 30;
renderer.RenderingOptions.MarginBottom = 25;
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("report.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' Configure text header with multiple properties
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Company Report",
.LeftText = "CONFIDENTIAL",
.RightText = DateTime.Now.ToString("MMMM yyyy"),
.DrawDividerLine = True,
.FontSize = 12,
.FontFamily = "Arial",
.Spacing = 5
}
' Configure text footer with dynamic placeholders
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.LeftText = "{date} {time}",
.CenterText = "© 2024 Company Name",
.RightText = "Page {page} of {total-pages}",
.DrawDividerLine = True,
.FontSize = 10,
.Spacing = 10
}
' Set margins to ensure proper spacing
renderer.RenderingOptions.MarginTop = 30
renderer.RenderingOptions.MarginBottom = 25
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("report.pdf")
IronPDF中的渲染選項提供了對PDF生成的精細控制,同時保持程式碼的可讀性。 這種基於屬性的方法使得維護和修改標題和頁腳變得容易,而不需深入到低級PDF操作。
IronPDF如何處理專業格式?

差異立顯——IronPDF自動處理定位、邊距和渲染,並提供動態內容的內建占位符。 這個程式庫的Chrome渲染引擎確保像素級完美的輸出匹配您的HTML預覽。
對於生產系統,哪些功能最重要?
| 功能 | iText | IronPDF |
|---|---|---|
| 實現方法 | PdfPageEventHelper類別 |
RenderingOptions屬性 |
| 程式碼複雜性 | 手動坐標計算 | 簡單的屬性分配 |
| 頁碼 | 通過writer.PageNumber手動跟踪 |
內建{page}占位符 |
| HTML支援 | 有限,需要XMLWorker | 原生的HTML標題支援 |
| 邊距管理 | 手動計算 | 自動調整 |
| 動態內容 | 需要自訂實現 | 預定義佔位符 |
| 首頁不同 | 複雜的條件邏輯 | FirstPageNumber屬性 |
| 學習曲線 | 陡峭 | 逐步 |
如何為頁碼新增標題和頁腳?
頁碼是PDF文件的標準要求。 使用iText,您必須手動跟踪當前頁碼和總頁數,通常需要兩次遍歷來獲取準確的總頁數:
// iTextSharp approach with complete page numbering
public class CompleteHeaderFooterEvent : PdfPageEventHelper
{
private readonly PdfTemplate totalPageCount;
private readonly Font normalFont = new Font(Font.FontFamily.HELVETICA, 10);
public CompleteHeaderFooterEvent(PdfWriter writer)
{
// Create placeholder for total page count
totalPageCount = writer.DirectContent.CreateTemplate(30, 16);
}
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfPTable footerTable = new PdfPTable(3);
footerTable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
footerTable.SetWidths(new float[] { 1, 1, 1 });
PdfPCell leftCell = new PdfPCell(new Phrase(DateTime.Now.ToString("dd/MM/yyyy"), normalFont));
leftCell.Border = Rectangle.NO_BORDER;
leftCell.HorizontalAlignment = Element.ALIGN_LEFT;
PdfPCell centerCell = new PdfPCell(new Phrase("Confidential", normalFont));
centerCell.Border = Rectangle.NO_BORDER;
centerCell.HorizontalAlignment = Element.ALIGN_CENTER;
PdfPCell rightCell = new PdfPCell();
rightCell.Border = Rectangle.NO_BORDER;
rightCell.HorizontalAlignment = Element.ALIGN_RIGHT;
Chunk pageNum = new Chunk($"Page {writer.PageNumber} of ", normalFont);
rightCell.AddElement(pageNum);
rightCell.AddElement(Image.GetInstance(totalPageCount));
footerTable.AddCell(leftCell);
footerTable.AddCell(centerCell);
footerTable.AddCell(rightCell);
footerTable.WriteSelectedRows(0, -1, document.LeftMargin,
document.PageSize.GetBottom(document.BottomMargin), writer.DirectContent);
}
public override void OnCloseDocument(PdfWriter writer, Document document)
{
ColumnText.ShowTextAligned(totalPageCount, Element.ALIGN_LEFT,
new Phrase(writer.PageNumber.ToString(), normalFont), 0, 0, 0);
}
}
// iTextSharp approach with complete page numbering
public class CompleteHeaderFooterEvent : PdfPageEventHelper
{
private readonly PdfTemplate totalPageCount;
private readonly Font normalFont = new Font(Font.FontFamily.HELVETICA, 10);
public CompleteHeaderFooterEvent(PdfWriter writer)
{
// Create placeholder for total page count
totalPageCount = writer.DirectContent.CreateTemplate(30, 16);
}
public override void OnEndPage(PdfWriter writer, Document document)
{
PdfPTable footerTable = new PdfPTable(3);
footerTable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
footerTable.SetWidths(new float[] { 1, 1, 1 });
PdfPCell leftCell = new PdfPCell(new Phrase(DateTime.Now.ToString("dd/MM/yyyy"), normalFont));
leftCell.Border = Rectangle.NO_BORDER;
leftCell.HorizontalAlignment = Element.ALIGN_LEFT;
PdfPCell centerCell = new PdfPCell(new Phrase("Confidential", normalFont));
centerCell.Border = Rectangle.NO_BORDER;
centerCell.HorizontalAlignment = Element.ALIGN_CENTER;
PdfPCell rightCell = new PdfPCell();
rightCell.Border = Rectangle.NO_BORDER;
rightCell.HorizontalAlignment = Element.ALIGN_RIGHT;
Chunk pageNum = new Chunk($"Page {writer.PageNumber} of ", normalFont);
rightCell.AddElement(pageNum);
rightCell.AddElement(Image.GetInstance(totalPageCount));
footerTable.AddCell(leftCell);
footerTable.AddCell(centerCell);
footerTable.AddCell(rightCell);
footerTable.WriteSelectedRows(0, -1, document.LeftMargin,
document.PageSize.GetBottom(document.BottomMargin), writer.DirectContent);
}
public override void OnCloseDocument(PdfWriter writer, Document document)
{
ColumnText.ShowTextAligned(totalPageCount, Element.ALIGN_LEFT,
new Phrase(writer.PageNumber.ToString(), normalFont), 0, 0, 0);
}
}
Imports System
Imports iTextSharp.text
Imports iTextSharp.text.pdf
' iTextSharp approach with complete page numbering
Public Class CompleteHeaderFooterEvent
Inherits PdfPageEventHelper
Private ReadOnly totalPageCount As PdfTemplate
Private ReadOnly normalFont As Font = New Font(Font.FontFamily.HELVETICA, 10)
Public Sub New(writer As PdfWriter)
' Create placeholder for total page count
totalPageCount = writer.DirectContent.CreateTemplate(30, 16)
End Sub
Public Overrides Sub OnEndPage(writer As PdfWriter, document As Document)
Dim footerTable As New PdfPTable(3)
footerTable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin
footerTable.SetWidths(New Single() {1, 1, 1})
Dim leftCell As New PdfPCell(New Phrase(DateTime.Now.ToString("dd/MM/yyyy"), normalFont))
leftCell.Border = Rectangle.NO_BORDER
leftCell.HorizontalAlignment = Element.ALIGN_LEFT
Dim centerCell As New PdfPCell(New Phrase("Confidential", normalFont))
centerCell.Border = Rectangle.NO_BORDER
centerCell.HorizontalAlignment = Element.ALIGN_CENTER
Dim rightCell As New PdfPCell()
rightCell.Border = Rectangle.NO_BORDER
rightCell.HorizontalAlignment = Element.ALIGN_RIGHT
Dim pageNum As New Chunk($"Page {writer.PageNumber} of ", normalFont)
rightCell.AddElement(pageNum)
rightCell.AddElement(Image.GetInstance(totalPageCount))
footerTable.AddCell(leftCell)
footerTable.AddCell(centerCell)
footerTable.AddCell(rightCell)
footerTable.WriteSelectedRows(0, -1, document.LeftMargin, document.PageSize.GetBottom(document.BottomMargin), writer.DirectContent)
End Sub
Public Overrides Sub OnCloseDocument(writer As PdfWriter, document As Document)
ColumnText.ShowTextAligned(totalPageCount, Element.ALIGN_LEFT, New Phrase(writer.PageNumber.ToString(), normalFont), 0, 0, 0)
End Sub
End Class
這個模式需要建立一個PDF模板物件作為佔位符,然後在文件關閉後回填總頁數。 該操作的雙遍性對不熟悉iText內部運作的人來說並不明顯,錯誤的操作會導致最終PDF中的頁碼不正確。
為什麼IronPDF的方法更具可維護性?
IronPDF利用內建佔位符和自動頁碼處理處理頁碼:
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
LeftText = "{date} {time}",
CenterText = "Confidential -- Internal Use Only",
RightText = "Page {page} of {total-pages}",
DrawDividerLine = true,
FontSize = 10,
FontFamily = "Calibri",
Spacing = 8
};
// Skip numbering on cover page
renderer.RenderingOptions.FirstPageNumber = 0;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginTop = 30;
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
LeftText = "{date} {time}",
CenterText = "Confidential -- Internal Use Only",
RightText = "Page {page} of {total-pages}",
DrawDividerLine = true,
FontSize = 10,
FontFamily = "Calibri",
Spacing = 8
};
// Skip numbering on cover page
renderer.RenderingOptions.FirstPageNumber = 0;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginTop = 30;
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.LeftText = "{date} {time}",
.CenterText = "Confidential -- Internal Use Only",
.RightText = "Page {page} of {total-pages}",
.DrawDividerLine = True,
.FontSize = 10,
.FontFamily = "Calibri",
.Spacing = 8
}
' Skip numbering on cover page
renderer.RenderingOptions.FirstPageNumber = 0
renderer.RenderingOptions.MarginBottom = 25
renderer.RenderingOptions.MarginTop = 30
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
內建佔位符支援{url}。 不需要複雜的後處理或兩次渲染。 程式庫在內部解析總頁數,並在每個佔位符位置自動插入。
您可以建立具有動態內容的HTML標題嗎?
對於包含公司標誌、樣式化字體或結構化表格的佈局,HTML標題提供了比基於文字的標題更大的靈活性。 IronPDF在此方面表現出色,具有原生的HTML標題和頁腳支援:
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 10px 0;'>
<img src='logo.png' style='height: 40px;'>
<div style='text-align: center;'>
<h2 style='margin: 0; color: #2c3e50;'>Annual Report 2024</h2>
<p style='margin: 0; font-size: 12px; color: #7f8c8d;'>Financial Performance & Strategic Overview</p>
</div>
<div style='text-align: right; font-size: 11px; color: #95a5a6;'>
Document ID: AR-2024-001<br>
Classification: Public
</div>
</div>",
MaxHeight = 80,
DrawDividerLine = true,
BaseUrl = new Uri(System.IO.Path.GetFullPath("assets/")).AbsoluteUri
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<table style='width: 100%; font-size: 10px; color: #34495e;'>
<tr>
<td style='width: 33%; text-align: left;'>Generated: {date} at {time}</td>
<td style='width: 34%; text-align: center;'>Page {page} of {total-pages}</td>
<td style='width: 33%; text-align: right;'>Annual Report 2024</td>
</tr>
</table>",
MaxHeight = 30,
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("annual-report.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 10px 0;'>
<img src='logo.png' style='height: 40px;'>
<div style='text-align: center;'>
<h2 style='margin: 0; color: #2c3e50;'>Annual Report 2024</h2>
<p style='margin: 0; font-size: 12px; color: #7f8c8d;'>Financial Performance & Strategic Overview</p>
</div>
<div style='text-align: right; font-size: 11px; color: #95a5a6;'>
Document ID: AR-2024-001<br>
Classification: Public
</div>
</div>",
MaxHeight = 80,
DrawDividerLine = true,
BaseUrl = new Uri(System.IO.Path.GetFullPath("assets/")).AbsoluteUri
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<table style='width: 100%; font-size: 10px; color: #34495e;'>
<tr>
<td style='width: 33%; text-align: left;'>Generated: {date} at {time}</td>
<td style='width: 34%; text-align: center;'>Page {page} of {total-pages}</td>
<td style='width: 33%; text-align: right;'>Annual Report 2024</td>
</tr>
</table>",
MaxHeight = 30,
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("annual-report.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "
<div style='width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 10px 0;'>
<img src='logo.png' style='height: 40px;'>
<div style='text-align: center;'>
<h2 style='margin: 0; color: #2c3e50;'>Annual Report 2024</h2>
<p style='margin: 0; font-size: 12px; color: #7f8c8d;'>Financial Performance & Strategic Overview</p>
</div>
<div style='text-align: right; font-size: 11px; color: #95a5a6;'>
Document ID: AR-2024-001<br>
Classification: Public
</div>
</div>",
.MaxHeight = 80,
.DrawDividerLine = True,
.BaseUrl = New Uri(System.IO.Path.GetFullPath("assets/")).AbsoluteUri
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "
<table style='width: 100%; font-size: 10px; color: #34495e;'>
<tr>
<td style='width: 33%; text-align: left;'>Generated: {date} at {time}</td>
<td style='width: 34%; text-align: center;'>Page {page} of {total-pages}</td>
<td style='width: 33%; text-align: right;'>Annual Report 2024</td>
</tr>
</table>",
.MaxHeight = 30,
.DrawDividerLine = True
}
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("annual-report.pdf")
複雜的標題在實踐中是如何渲染的?

使用iText,實現HTML標題需要新增XMLWorker擴展並撰寫複雜的解析程式碼。 該程式庫有限的CSS支援使得很難生成可跨不同紙張尺寸可靠運行的現代佈局。 圖像、浮動佈局和網路字體需要大量的程式碼複雜性。
您如何使用不同的首頁標題進行處理?
許多專業文件需要在封面頁上使用不同的標題——標題頁的大標籤,然後是後續頁面的緊湊標題。 IronPDF通過條件HTML和CSS支持此模式:
using IronPdf;
var renderer = new ChromePdfRenderer();
string firstPageHeader = @"
<div style='text-align: center; padding: 20px 0;'>
<img src='logo-large.png' style='height: 80px; margin-bottom: 10px;'>
<h1 style='margin: 0; color: #2c3e50;'>2024 Annual Report</h1>
<h3 style='margin: 5px 0; color: #7f8c8d;'>Fiscal Year Ending December 31, 2024</h3>
</div>";
string subsequentPageHeader = @"
<div style='display: flex; justify-content: space-between; align-items: center;'>
<img src='logo-small.png' style='height: 30px;'>
<span>Annual Report 2024</span>
<span>Page {page}</span>
</div>";
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = $@"
<style>
.first-page {{display: none;}}
.other-pages {{display: block;}}
@page:first {{
.first-page {{display: block;}}
.other-pages {{display: none;}}
}}
</style>
<div class='first-page'>{firstPageHeader}</div>
<div class='other-pages'>{subsequentPageHeader}</div>",
MaxHeight = 100
};
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("report-with-cover.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
string firstPageHeader = @"
<div style='text-align: center; padding: 20px 0;'>
<img src='logo-large.png' style='height: 80px; margin-bottom: 10px;'>
<h1 style='margin: 0; color: #2c3e50;'>2024 Annual Report</h1>
<h3 style='margin: 5px 0; color: #7f8c8d;'>Fiscal Year Ending December 31, 2024</h3>
</div>";
string subsequentPageHeader = @"
<div style='display: flex; justify-content: space-between; align-items: center;'>
<img src='logo-small.png' style='height: 30px;'>
<span>Annual Report 2024</span>
<span>Page {page}</span>
</div>";
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = $@"
<style>
.first-page {{display: none;}}
.other-pages {{display: block;}}
@page:first {{
.first-page {{display: block;}}
.other-pages {{display: none;}}
}}
</style>
<div class='first-page'>{firstPageHeader}</div>
<div class='other-pages'>{subsequentPageHeader}</div>",
MaxHeight = 100
};
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("report-with-cover.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim firstPageHeader As String = "
<div style='text-align: center; padding: 20px 0;'>
<img src='logo-large.png' style='height: 80px; margin-bottom: 10px;'>
<h1 style='margin: 0; color: #2c3e50;'>2024 Annual Report</h1>
<h3 style='margin: 5px 0; color: #7f8c8d;'>Fiscal Year Ending December 31, 2024</h3>
</div>"
Dim subsequentPageHeader As String = "
<div style='display: flex; justify-content: space-between; align-items: center;'>
<img src='logo-small.png' style='height: 30px;'>
<span>Annual Report 2024</span>
<span>Page {page}</span>
</div>"
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = $"
<style>
.first-page {{display: none;}}
.other-pages {{display: block;}}
@page:first {{
.first-page {{display: block;}}
.other-pages {{display: none;}}
}}
</style>
<div class='first-page'>{firstPageHeader}</div>
<div class='other-pages'>{subsequentPageHeader}</div>",
.MaxHeight = 100
}
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("report-with-cover.pdf")
此方法使得標題定義保持在一個地方,便於同時更新封面和內頁標題。 您還可以探索異步PDF渲染以應對高吞吐量的情況。
哪種方法提供更好的性能和靈活性?
當生成大型文件或同時處理多個PDF時,性能變得至關重要。 IronPDF的Chrome渲染引擎為生產工作負載提供數個優勢:
- 渲染性能:IronPDF快取渲染的標題和頁腳,提高了多頁文件的吞吐量
- 記憶體效率:該程式庫自動處理記憶體管理,避免手動
PdfContentByte操作可能出現的記憶體洩漏 - 並行處理:支援異步操作,使Task.WhenAll模式的高效批量生成成為可能
using IronPdf;
public async Task GenerateReportsAsync(List<ReportData> reports)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Monthly Report",
DrawDividerLine = true
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
RightText = "Page {page} of {total-pages}",
DrawDividerLine = true
};
// Disable JavaScript if not required for faster rendering
renderer.RenderingOptions.EnableJavaScript = false;
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
var tasks = reports.Select(async report =>
{
string html = await GenerateHtmlAsync(report);
return await renderer.RenderHtmlAsPdfAsync(html);
});
PdfDocument[] pdfs = await Task.WhenAll(tasks);
}
using IronPdf;
public async Task GenerateReportsAsync(List<ReportData> reports)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Monthly Report",
DrawDividerLine = true
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
RightText = "Page {page} of {total-pages}",
DrawDividerLine = true
};
// Disable JavaScript if not required for faster rendering
renderer.RenderingOptions.EnableJavaScript = false;
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
var tasks = reports.Select(async report =>
{
string html = await GenerateHtmlAsync(report);
return await renderer.RenderHtmlAsPdfAsync(html);
});
PdfDocument[] pdfs = await Task.WhenAll(tasks);
}
Imports IronPdf
Public Async Function GenerateReportsAsync(reports As List(Of ReportData)) As Task
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Monthly Report",
.DrawDividerLine = True
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.RightText = "Page {page} of {total-pages}",
.DrawDividerLine = True
}
' Disable JavaScript if not required for faster rendering
renderer.RenderingOptions.EnableJavaScript = False
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
Dim tasks = reports.Select(Async Function(report)
Dim html As String = Await GenerateHtmlAsync(report)
Return Await renderer.RenderHtmlAsPdfAsync(html)
End Function)
Dim pdfs As PdfDocument() = Await Task.WhenAll(tasks)
End Function
關於生產使用的授權考慮是什麼?
與iText的AGPL授權相比,IronPDF的授權模式提供了商業友好的條款,AGPL要求開源您的應用程式程式碼,除非購買單獨的商業iText授權。 對於生產系統,IronPDF提供:
對團隊來說學習曲線有多陡峭?
對於熟悉iText的頁事件系統的開發者來說,需要一段調整時間,但IronPDF的文件和範例使這一過程可控。 使用CSS來進行樣式化和HTML進行佈局打開了可能性,這在iText中需要大量的自訂程式碼。 文件包括:
邊距和間距計算有什麼不同?
專業文件佈局需要精確的邊距控制。 IronPDF使用毫米作為測量單位簡化了這一點——這是列印布局的一種自然單位:
using IronPdf;
var renderer = new ChromePdfRenderer();
// Set margins in millimeters
renderer.RenderingOptions.MarginTop = 25.4; // 1 inch
renderer.RenderingOptions.MarginBottom = 25.4;
renderer.RenderingOptions.MarginLeft = 19.05; // 0.75 inch
renderer.RenderingOptions.MarginRight = 19.05;
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Internal Report",
DrawDividerLine = true,
Spacing = 5
};
// Use print CSS media type for accurate page layout
// See MDN reference: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/print
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("margin-report.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
// Set margins in millimeters
renderer.RenderingOptions.MarginTop = 25.4; // 1 inch
renderer.RenderingOptions.MarginBottom = 25.4;
renderer.RenderingOptions.MarginLeft = 19.05; // 0.75 inch
renderer.RenderingOptions.MarginRight = 19.05;
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Internal Report",
DrawDividerLine = true,
Spacing = 5
};
// Use print CSS media type for accurate page layout
// See MDN reference: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/print
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("margin-report.pdf");
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
' Set margins in millimeters
renderer.RenderingOptions.MarginTop = 25.4 ' 1 inch
renderer.RenderingOptions.MarginBottom = 25.4
renderer.RenderingOptions.MarginLeft = 19.05 ' 0.75 inch
renderer.RenderingOptions.MarginRight = 19.05
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Internal Report",
.DrawDividerLine = True,
.Spacing = 5
}
' Use print CSS media type for accurate page layout
' See MDN reference: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/print
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("margin-report.pdf")
與iText的基於坐標的方法相比,您需要計算相對於頁面邊界的位置,並手動確認內容不與標題或頁腳重疊。
您的下一步是什麼?
將標題和頁腳新增到PDF文件不必涉及複雜的事件處理和坐標計算。 雖然iText的方法通過頁面事件和直接內容操作提供了精細控制,但IronPDF提供了一種更加直觀的解決方案,具有基於屬性的配置和原生的HTML支援。
在考慮開發速度、可維護性和製作專業外觀文件的簡便性時,選擇變得顯而易見。 IronPDF對標題和頁腳的方法體現了現代PDF生成——強大且易於接觸。 對於優先考慮乾淨架構和可維護程式碼的團隊來說,IronPDF的API與.NET開發實踐非常契合。
生產系統的主要優勢包括:
- 縮短開發時間:基於屬性的配置vs.複雜的事件處理器
- 更好的可維護性:HTML/CSS用於佈局而不是坐標計算
- 增強的靈活性:原生支援響應式設計和網路字體
- 高性能:優化渲染,具有快取和並行處理支持
- 專業效果:符合現代網路標準的像素完美輸出
首先通過NuGet安裝IronPDF,然後按照快速啟動指南完成您的第一個標題和頁腳建構,僅需幾分鐘。 當您準備好進入生產環境時,請查看授權選項以找到適合您部署需求的計畫。 如果在整合過程中遇到了任何問題,支援團隊隨時可提供幫助。
常見問題
IronPDF和iTextSharp在新增頁眉和頁腳上有何主要區別?
IronPDF使用基於屬性的API和原生HTML支持,而iTextSharp需要實現PdfPageEventHelper並手動計算座標。IronPDF還提供內建的頁碼、日期和URL佔位符。
IronPDF如何簡化頁眉的新增?
IronPDF允許您通過ChromePdfRenderer.RenderingOptions中的TextHeaderFooter或HtmlHeaderFooter屬性配置頁眉,省去了處理頁面事件或計算像素位置的需要。
是否可以使用HTML在IronPDF中客製頁眉?
是的,IronPDF通過HtmlHeaderFooter類支持基於HTML的頁眉和頁腳,支持完整的CSS樣式、圖片和動態佔位符,例如{page}和{total-pages}。
使用IronPDF進行商務報告有何好處?
IronPDF通過基於屬性的配置減少了實施時間,支持頁碼和日期的動態佔位符,並使用Chromium引擎以像素完美的準確性呈現頁眉。
IronPDF能夠處理頁眉和頁腳中的頁碼嗎?
是的,IronPDF通過內建佔位符(如{page}和{total-pages})自動處理頁碼,無需進行兩次渲染。
IronPDF在使用便捷性上與iTextSharp相比如何?
IronPDF通常較易使用,因為它用宣告式屬性API替代了基於座標的低層事件處理程式,並支持HTML/CSS進行佈局。
IronPDF是否支持頁眉中的動態內容?
是的,IronPDF通過內建佔位符({page}、{total-pages}、{date}、{time}、{html-title}、{url})支持文字和HTML頁眉中的動態內容。
IronPDF爲何更適合文件項目?
IronPDF的HTML頁眉支持使其非常適合需要一致樣式、公司品牌和易於更新的文件。更改需要編輯HTML而不是數字座標常數。
我可以在IronPDF中對發票使用客製頁眉嗎?
是的,IronPDF支持帶有標誌、樣式化文字和動態欄位的客製HTML頁眉,這使它非常適合發票生成。



