首页 文章

如何在使用iTextSharp生成的动态生成的PDF中的某些页面上执行不同的操作?

提问于
浏览
1

我正在使用iTextSharp动态生成PDF文档 . 我不知道它将包含多少页面 . 我已经设法通过覆盖PdfPageEventHelper上的OnStartPage和OnEndPage来在所有页面上创建页眉和页脚 . 但是,使用这种方法,所有页面上的 Headers 都相同,并且所有页面上的页脚都相同 . 我需要更有活力:我需要在最后一页显示不同的页脚 .

当我在OnEndPage方法中时,我知道页面的页面编号,但我不知道它是否是最后一个 . 当我在OnCloseDocument方法中时,我知道总页数,但我不能从这里“删除”或“删除”或更改OnEndPage添加到最后一页的页脚 .

2 回答

  • 0

    所以你've got a main loop of code that'创建页面和添加内容,对吧?一旦该内容完成,您可以设置 OnEndPage 寻找的全局标志吗?

    下面的代码(在VB.Net中,抱歉)用一个布尔变量创建一个类(所以我们可以通过引用传递它),一旦我们完成主处理循环,我们设置为 true ,以便 OnEndPage 知道做一些不同的事情 . 对于详细 IPdfPageEvent 抱歉,VB要求声明所有方法,即使您不使用它们 .

    Option Explicit On
    Option Strict On
    
    Imports iTextSharp.text
    Imports iTextSharp.text.pdf
    Imports System.IO
    
    Public Class Form1
        ''//Holds our state information
        Private PageState As CustomPageState
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ''//Create a new document
            Dim Doc As New iTextSharp.text.Document(PageSize.LETTER)
    
            ''//Write it to a memory stream
            Using FS As New FileStream(Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "Output.pdf"), FileMode.Create, FileAccess.Write, FileShare.Read)
                ''//Grab the writer
                Dim writer = PdfWriter.GetInstance(Doc, FS)
                ''//Create an object that we can pass by reference around to store the page state
                Me.PageState = New CustomPageState()
                ''//Wire our event handler and pass in the page state
                writer.PageEvent = New MyCustomPdfEvent(Me.PageState)
                ''//Open the PDF for writing
                Doc.Open()
    
                ''//Main loop, create a bunch of pages
                For I = 1 To 10
                    Doc.NewPage()
                    Doc.Add(New Phrase("Hello"))
    
                    ''//This code goes at the very end of our main loop
                    If I = 10 Then Me.PageState.IsLastPage = True
                Next
                ''//Close the PDF
                Doc.Close()
    
            End Using
        End Sub
        ''//This is our state container. Its just has a boolean value but its wrapped in a class so that we can pass it around by reference
        Public Class CustomPageState
            Public Property IsLastPage As Boolean = False
        End Class
    
        Public Class MyCustomPdfEvent
            Implements IPdfPageEvent
            ''//Reference to the state container
            Private PageState As CustomPageState
    
            Public Sub New(ByRef pageState As CustomPageState)
                Me.PageState = pageState
            End Sub
    
            Public Sub OnEndPage(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document) Implements iTextSharp.text.pdf.IPdfPageEvent.OnEndPage
                If Me.PageState.IsLastPage Then
                    ''//Last page, do something different
                Else
                    ''//Do normal page footer
                End If
            End Sub
    
            Public Sub OnChapter(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal paragraphPosition As Single, ByVal title As iTextSharp.text.Paragraph) Implements iTextSharp.text.pdf.IPdfPageEvent.OnChapter
    
            End Sub
    
            Public Sub OnChapterEnd(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal paragraphPosition As Single) Implements iTextSharp.text.pdf.IPdfPageEvent.OnChapterEnd
    
            End Sub
    
            Public Sub OnCloseDocument(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document) Implements iTextSharp.text.pdf.IPdfPageEvent.OnCloseDocument
    
            End Sub
    
            Public Sub OnGenericTag(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal rect As iTextSharp.text.Rectangle, ByVal text As String) Implements iTextSharp.text.pdf.IPdfPageEvent.OnGenericTag
    
            End Sub
    
            Public Sub OnOpenDocument(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document) Implements iTextSharp.text.pdf.IPdfPageEvent.OnOpenDocument
    
            End Sub
    
            Public Sub OnParagraph(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal paragraphPosition As Single) Implements iTextSharp.text.pdf.IPdfPageEvent.OnParagraph
    
            End Sub
    
            Public Sub OnParagraphEnd(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal paragraphPosition As Single) Implements iTextSharp.text.pdf.IPdfPageEvent.OnParagraphEnd
    
            End Sub
    
            Public Sub OnSection(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal paragraphPosition As Single, ByVal depth As Integer, ByVal title As iTextSharp.text.Paragraph) Implements iTextSharp.text.pdf.IPdfPageEvent.OnSection
    
            End Sub
    
            Public Sub OnSectionEnd(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document, ByVal paragraphPosition As Single) Implements iTextSharp.text.pdf.IPdfPageEvent.OnSectionEnd
    
            End Sub
    
            Public Sub OnStartPage(ByVal writer As iTextSharp.text.pdf.PdfWriter, ByVal document As iTextSharp.text.Document) Implements iTextSharp.text.pdf.IPdfPageEvent.OnStartPage
    
            End Sub
        End Class
    End Class
    
  • 0

    我相信你可以修改 PdfTemplate 的实例,直到你调用 document.close() .

    • 更改页眉/页脚代码以在 PdfTemplate 中绘制所有内容 .

    • 保存页面之间的最后 PdfTemplate .

    • 在调用 document.close() 之前,重置最后一个页眉和页脚,并按照最后一页所需的方式绘制它 .

    PS:在为多个页面绘制完全相同的东西时,使用 PdfTemplate 非常有效 . 您只需构建一次模板,然后在需要它的每个页面上重复使用它 . 然而,在这种特殊情况下,它实际上增加了一点开销,因为你必须为每个页面创建一个,这样你就可以在事后改变最后一个 .

    OTOH,如果你在每个页面上都有相同的东西,加上最后一个上面的一些额外的东西,你可以嵌套模板 . 一个具有Unchanging Stuff,另一个模板只是将所有页面包装在所有页面上,而不是最后一个 . 在最后一页上,您可以简单地添加它,而不是重置现有内容 .

    PPS:IIRC,这就是你 Build "page x of y"页脚的方式 . 所有页面都包含"page x of "的一些直接内容 . 在 close() 之前渲染完所有页面后,您将使用页数填写该模板 .

相关问题