VB.NET使用iText7为PDF所有页面添加图片页眉页脚的技术求助
VB.NET + iText7:为动态页数PDF自动添加图片页眉页脚
我来帮你把iText7事件处理器的逻辑转换成VB.NET,并且完美整合到你的现有代码里,实现每页自动添加图片页眉和页码页脚的功能。核心思路是通过实现IEventHandler接口监听页面结束事件,在每一页生成完成后自动绘制页眉页脚。
第一步:创建自定义页眉页脚事件处理器
首先我们要写一个专门处理页面事件的类,它会实现IEventHandler接口,负责在每一页绘制页眉图片和页脚内容:
Imports iText.Kernel.Events Imports iText.Kernel.Pdf Imports iText.Kernel.Geom Imports iText.IO.Image Imports iText.Layout.Element Imports iText.Layout Imports iText.Kernel.Font Public Class HeaderFooterEventHandler Implements IEventHandler ' 存储页眉图片路径和要使用的字体 Private ReadOnly _headerImagePath As String Private ReadOnly _font As PdfFont ' 构造函数:初始化页眉图片路径和字体 Public Sub New(headerImagePath As String, font As PdfFont) _headerImagePath = headerImagePath _font = font End Sub ' 核心事件处理方法:每一页结束时自动调用 Public Sub HandleEvent([event] As Event) Implements IEventHandler.HandleEvent ' 将通用事件转换为PDF文档事件 Dim docEvent As PdfDocumentEvent = DirectCast([event], PdfDocumentEvent) Dim pdfDoc As PdfDocument = docEvent.GetDocument() Dim currentPage As PdfPage = docEvent.GetPage() Dim pageSize As Rectangle = currentPage.GetPageSize() ' 创建画布,用于绘制页眉页脚(NewContentStreamBefore确保内容在文档下方,不会被覆盖) Dim canvas As New PdfCanvas(currentPage.NewContentStreamBefore(), currentPage.GetResources(), pdfDoc) Dim document As New Document(pdfDoc) ' -------------------------- 绘制图片页眉 -------------------------- Dim headerImageData = ImageDataFactory.Create(_headerImagePath) Dim headerImage As New Image(headerImageData) ' 设置页眉图片宽度适配页面(减去左右边距),高度自动按比例缩放 Dim headerWidth = pageSize.GetWidth() - document.GetLeftMargin() - document.GetRightMargin() headerImage.SetWidth(headerWidth) headerImage.SetAutoScaleHeight(True) ' 定位页眉:顶部减去上边距和图片高度,水平对齐左边距 Dim headerX = document.GetLeftMargin() Dim headerY = pageSize.GetTop() - document.GetTopMargin() - headerImage.GetImageHeight() canvas.AddXObjectAt(headerImage.GetXObject(), headerX, headerY) ' -------------------------- 绘制页码页脚 -------------------------- Dim pageText As String = $"Pagina {pdfDoc.GetPageNumber(currentPage)} van {pdfDoc.GetNumberOfPages()}" ' 计算页码居中位置:页面宽度减去文字宽度后除以2 Dim footerX = (pageSize.GetWidth() - _font.GetWidth(pageText, 8)) / 2 ' 定位页脚:底部边距下方10像素 Dim footerY = document.GetBottomMargin() - 10 ' 开始绘制文字 canvas.BeginText() canvas.SetFontAndSize(_font, 8) canvas.MoveText(footerX, footerY) canvas.ShowText(pageText) canvas.EndText() ' 释放画布资源 canvas.Release() End Sub End Class
第二步:修改你的PDF生成主代码
现在把事件处理器整合到你现有的NewiText7PdfCreation方法里,注意要调整文档边距(避免内容和页眉页脚重叠),并移除之前手动添加的页眉代码:
Imports System.IO Imports MySql.Data.MySqlClient Imports iText.Kernel Imports iText.Kernel.Pdf Imports iText.Kernel.Font Imports iText.Kernel.Font.PdfFont Imports iText.Kernel.Font.PdfFontFactory Imports iText.IO.Image Imports iText.IO.Image.ImageData Imports iText.IO.Image.ImageDataFactory Imports iText.Layout.Element.Image Imports iText.Layout Imports iText.Layout.Element Imports iText.Layout.Element.Table Imports iText.Kernel.Events.Event Imports iText.Kernel.Events.PdfDocumentEvent Imports iText.Kernel.Geom.PageSize Imports iText.Kernel.Geom.Rectangle Imports iText.Kernel.Pdf.PdfDocument Imports iText.Kernel.Pdf.PdfWriter Imports iText.Kernel.Pdf.Canvas.PdfCanvas Imports iText.Layout.Style Public Sub NewiText7PdfCreation() Dim dest As String = "iText7Test.pdf" Dim writer As PdfWriter = New PdfWriter(dest) Dim pdf As PdfDocument = New PdfDocument(writer) ' 设置页面大小为A4,同时创建文档对象 Dim doc As Document = New Document(pdf, PageSize.A4) ' -------------------------- 关键:设置文档边距,给页眉页脚留空间 -------------------------- doc.SetTopMargin(60) ' 页眉高度+边距,避免内容顶到页眉 doc.SetBottomMargin(30) ' 页脚高度+边距,避免内容压到页脚 doc.SetLeftMargin(30) doc.SetRightMargin(30) Dim font As PdfFont = PdfFontFactory.CreateFont("C:\\Windows\\Fonts\\calibri.ttf") ' -------------------------- 注册页眉页脚事件处理器 -------------------------- Dim headerImagePath As String = "Resources\\Offerte-NL.png" Dim eventHandler As New HeaderFooterEventHandler(headerImagePath, font) ' 监听页面结束事件,每一页生成后自动触发 pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, eventHandler) ' -------------------------- 你的原有内容部分 -------------------------- ' 注意:移除之前手动添加headerimage2的代码,事件处理器会自动处理所有页的页眉 doc.Add(New Paragraph("Debiteur gegevens").SetFont(font)) Dim debnr As String = TextBox1.Text Dim bn As String = TextBox2.Text Dim adr As String = TextBox3.Text Dim pcwp As String = TextBox4.Text Dim cp As String = TextBox5.Text Dim km As String = TextBox6.Text Dim klanttable As New Table(2) klanttable.SetMaxWidth(350) klanttable.SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.LEFT) klanttable.SetFont(font) klanttable.SetFontSize(8) klanttable.SetWidth(350) klanttable.SetMinWidth(120) klanttable.AddCell("Debiteur nr.: ") klanttable.AddCell(debnr) klanttable.AddCell("(Bedrijfs)naam:") klanttable.AddCell(bn) klanttable.AddCell("Adres:") klanttable.AddCell(adr) klanttable.AddCell("Postcode & woonplaats:") klanttable.AddCell(pcwp) klanttable.AddCell("Contactpersoon:") klanttable.AddCell(cp) klanttable.AddCell("Kenmerk:") klanttable.AddCell(km) klanttable.SetMarginTop(10) klanttable.SetMarginBottom(10) doc.Add(klanttable) ' 可以添加更多测试内容,验证多页时页眉页脚是否正常显示 For i As Integer = 1 To 20 doc.Add(New Paragraph($"测试内容 {i},用来生成多页PDF...").SetFont(font).SetMarginTop(5)) Next doc.Close() End Sub
关键注意事项
- 边距设置:必须设置足够的上下边距,否则文档内容会和页眉页脚重叠,这是新手最容易忽略的点。
- 图片路径:确保页眉图片的路径正确,建议用绝对路径或者项目资源的正确相对路径。
- 页码准确性:iText7会在文档关闭时自动更新总页数,所以最终PDF里的页码会是正确的。
- 自定义扩展:如果需要更复杂的页脚(比如公司信息、额外logo),可以在
HandleEvent方法里继续添加绘制逻辑。
内容的提问来源于stack exchange,提问作者Jeffrey Lionel van Houdt
相关产品推荐
相关产品推荐

