跳至頁尾內容
PDF工具

發現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.

View Full Comparison

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
SHELL

安裝後,在應用程式啟動時新增一次性授權金鑰調用:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"
$vbLabelText   $csharpLabel

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

當處理不同的頁面方向、自訂紙張尺寸或不同的邊距需求時,這種手動定位方法變得更加複雜。 對於需要PDF/A合規數位簽名的生產系統來說,手動方法增加了大量的維護開銷。

具有基本標題的輸出是什麼樣的?

PDF文件顯示公司報告,標題包含標題文字,頁腳顯示頁碼,展示了PDF生成中基本的標題和頁腳實現

上述程式碼展示了所需的手動工作——您必須計算精確的坐標、單獨管理字體,並通過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")
$vbLabelText   $csharpLabel

IronPDF中的渲染選項提供了對PDF生成的精細控制,同時保持程式碼的可讀性。 這種基於屬性的方法使得維護和修改標題和頁腳變得容易,而不需深入到低級PDF操作。

IronPDF如何處理專業格式?

兩頁PDF文件展示了IronPDF的標題和頁腳能力,具有公司品牌、頁碼和時間戳,跨多頁保持一致的格式

差異立顯——IronPDF自動處理定位、邊距和渲染,並提供動態內容的內建占位符。 這個程式庫的Chrome渲染引擎確保像素級完美的輸出匹配您的HTML預覽。

對於生產系統,哪些功能最重要?

功能比較:iText vs IronPDF對於標題和頁腳
功能 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
$vbLabelText   $csharpLabel

這個模式需要建立一個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)
$vbLabelText   $csharpLabel

內建佔位符支援{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 &amp; 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 &amp; 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 &amp; 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")
$vbLabelText   $csharpLabel

複雜的標題在實踐中是如何渲染的?

PDF文件具有專業標題,帶有公司標誌和年度報告品牌,展示了IronPDF的高級HTML標題渲染能力,具有一致的多頁格式

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

此方法使得標題定義保持在一個地方,便於同時更新封面和內頁標題。 您還可以探索異步PDF渲染以應對高吞吐量的情況。

哪種方法提供更好的性能和靈活性?

當生成大型文件或同時處理多個PDF時,性能變得至關重要。 IronPDF的Chrome渲染引擎為生產工作負載提供數個優勢:

  1. 渲染性能:IronPDF快取渲染的標題和頁腳,提高了多頁文件的吞吐量
  2. 記憶體效率:該程式庫自動處理記憶體管理,避免手動PdfContentByte操作可能出現的記憶體洩漏
  3. 並行處理:支援異步操作,使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
$vbLabelText   $csharpLabel

關於生產使用的授權考慮是什麼?

與iText的AGPL授權相比,IronPDF的授權模式提供了商業友好的條款,AGPL要求開源您的應用程式程式碼,除非購買單獨的商業iText授權。 對於生產系統,IronPDF提供:

  • 永久授權,無需定期費用
  • Deployment support across Windows, Linux, macOS, and Azure
  • 為授權使用者提供支援
  • 生產輸出中無水印

對團隊來說學習曲線有多陡峭?

對於熟悉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")
$vbLabelText   $csharpLabel

與iText的基於坐標的方法相比,您需要計算相對於頁面邊界的位置,並手動確認內容不與標題或頁腳重疊。

您的下一步是什麼?

將標題和頁腳新增到PDF文件不必涉及複雜的事件處理和坐標計算。 雖然iText的方法通過頁面事件和直接內容操作提供了精細控制,但IronPDF提供了一種更加直觀的解決方案,具有基於屬性的配置和原生的HTML支援。

在考慮開發速度、可維護性和製作專業外觀文件的簡便性時,選擇變得顯而易見。 IronPDF對標題和頁腳的方法體現了現代PDF生成——強大且易於接觸。 對於優先考慮乾淨架構和可維護程式碼的團隊來說,IronPDF的API與.NET開發實踐非常契合。

生產系統的主要優勢包括:

  • 縮短開發時間:基於屬性的配置vs.複雜的事件處理器
  • 更好的可維護性:HTML/CSS用於佈局而不是坐標計算
  • 增強的靈活性:原生支援響應式設計網路字體
  • 高性能:優化渲染,具有快取和並行處理支持
  • 專業效果:符合現代網路標準的像素完美輸出

首先通過NuGet安裝IronPDF,然後按照快速啟動指南完成您的第一個標題和頁腳建構,僅需幾分鐘。 當您準備好進入生產環境時,請查看授權選項以找到適合您部署需求的計畫。 如果在整合過程中遇到了任何問題,支援團隊隨時可提供幫助。

請注意iText是其各自所有者的註冊商標。 此站點與iText無關,未由其背書或贊助。 所有產品名稱、徽標和品牌均為其各自所有者的財產。 比較僅供資訊參考,並反映了撰寫時的公開可用資訊。

常見問題

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頁眉,這使它非常適合發票生成。

Curtis Chau
技術作家

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

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

Iron 支援團隊

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