gpt4 book ai didi

vb.net - iTextSharp 对不同的页面应用不同的边距

转载 作者:行者123 更新时间:2023-12-04 04:34:33 28 4
gpt4 key购买 nike

(使用 itextsharp 5.4.3)

我创建了一个应用程序,用户可以在其中创建围绕页面主要内容的自定义 xhtml 页眉和页脚。所以生成的pdf看起来像这样:

------------------------
| xhtml parsed Header |
------------------------
| |
| xhtml parsed content |
| |
------------------------
| xhtml parsed Footer |
------------------------

我已经正确生成了 pdf,但是我只希望标题出现在第一页上,并且能够(重新)设置剩余页面的边距。目前它仅在第一页上显示标题(正确),但保留剩余页面的边距(不正确)而不显示标题(正确)。
所以一个 3 页生成的 pdf 看起来像
------------------------
| xhtml parsed Header |
------------------------
| |
| xhtml parsed content |
| |
------------------------
| Page 1 |
------------------------
------------------------
| |
------------------------
| |
| xhtml parsed content |
| |
------------------------
| Page 2 |
------------------------
------------------------
| |
------------------------
| |
| xhtml parsed content |
| |
------------------------
| Page 3 |
------------------------

内容使用 XML Parser 和 PageEvents 进行解析
(生成按钮的代码)
Protected Sub btnPreview_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPreview.Click
Dim bytes As Byte()
Dim replaced As String = HttpUtility.HtmlDecode(letterRadEdit.Content.Replace("<br>", "<br />"))
Dim replaced2 As String = HttpUtility.UrlDecode(replaced)
bytes = System.Text.Encoding.UTF8.GetBytes(letterRadEdit.Content)
Dim tagProcessor As tool.xml.html.DefaultTagProcessorFactory()

Using input As New MemoryStream(bytes, False)
Dim ms As New MemoryStream()
Dim document As New iTextSharp.text.Document(iTextSharp.text.PageSize.LETTER, 36.0F, 36.0F, 52.0F, 52.0F)
Dim headerFooter As New iTextSharpHeaderFooter()

If Not String.IsNullOrEmpty(ddlHeaders.SelectedValue) Or Not String.IsNullOrEmpty(ddlFooters.SelectedValue) Then
Using db As New dbEntities()
If Not String.IsNullOrEmpty(ddlHeaders.SelectedValue) Then
'Get header content
Dim headerGuid As Guid = New Guid(ddlHeaders.SelectedValue)
Dim selectedheader As New LetterHeaderFooter()
selectedheader = (From hf In db.LetterHeaderFooters
Where hf.HeadFootID = headerGuid And hf.HeadFootType = 1
Select hf).FirstOrDefault()
Dim headerbytes As Byte()
headerbytes = System.Text.Encoding.UTF8.GetBytes(HttpUtility.HtmlDecode(selectedheader.HeadFootContent.Replace("<br>", "<br />").Trim()))
headerFooter.HeaderHTML = HttpUtility.HtmlDecode(selectedheader.HeadFootContent.Replace("<br>", "<br />").Trim())
headerFooter.HeaderContent = headerbytes

'Start building header into table
Dim page As New Rectangle(document.PageSize.Width - 72.0F, document.PageSize.Height)
Dim cellHeight As Single = document.TopMargin
Dim header As New PdfPTable(1)

header.TotalWidth = page.Width
Dim c As New PdfPCell()
c.HorizontalAlignment = Element.ALIGN_LEFT
c.Border = PdfPCell.BOTTOM_BORDER

Dim mh As SampleHandler = New SampleHandler()
Using sr As TextReader = New StringReader(headerFooter.HeaderHTML)
XMLWorkerHelper.GetInstance().ParseXHtml(mh, sr)
End Using
For Each el As IElement In mh.elements
c.AddElement(el)
Next

header.AddCell(c)
Dim startingMargin As Single = (header.TotalHeight + document.TopMargin)
document.SetMargins(document.LeftMargin, document.RightMargin, startingMargin, document.BottomMargin)
headerFooter.PageHeader = header

End If

End Using
End If

Dim writer As PdfWriter = PdfWriter.GetInstance(document, ms)
writer.PageEvent = headerFooter
writer.CloseStream = False
document.Open()

Dim htmlContext As HtmlPipelineContext = New HtmlPipelineContext(Nothing)
htmlContext.SetAcceptUnknown(True)
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory())
Dim cssResolver As ICSSResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(True)
cssResolver.AddCssFile(HttpContext.Current.Server.MapPath("~/assets/css/pdf.css"), True)

Dim pipeline As New CssResolverPipeline(cssResolver, New HtmlPipeline(htmlContext, New PdfWriterPipeline(document, writer)))
Dim pdfworker As New XMLWorker(pipeline, True)

Dim p As New XMLParser(True, pdfworker, New System.Text.UTF8Encoding)

Try
p.Parse(input)
Catch

Finally
pdfworker.Close()

End Try

document.Close()
ms.Position = 0

Response.ContentType = "application/pdf"
Response.AppendHeader("Expires", "0")
Response.AppendHeader(
"Cache-Control",
"must-revalidate, post-check=0, pre-check=0"
)
Response.AppendHeader("Pragma", "public")
Response.AppendHeader("content-disposition", "attachment; filename=preview.pdf")
Response.BinaryWrite(ms.ToArray())
ms.Flush()
End Using
End Sub

iTextSharpHeaderFooter 类在下面
Public Class iTextSharpHeaderFooter
Inherits PdfPageEventHelper

Private _HeaderStream As Byte()
Private _FooterStream As Byte()
Private _HeaderHTML As String
Private _FooterHTML As String
Private _headerPdf As Document
Private _footerPdf As Document
Private _usesHeader As Boolean
Private _pageHeader, _pageFooter As PdfPTable

'This is the contentbyte object of the writer
Dim cb As PdfContentByte

' we will put the final number of pages in a template
Dim template As PdfTemplate

' this is the BaseFont we are going to use for the header / footer
Dim bf As BaseFont = Nothing

' This keeps track of the creation time
Dim PrintTime As DateTime = DateTime.Now

Public Property HeaderContent() As Byte()
Get
Return _HeaderStream
End Get
Set(ByVal value As Byte())
_HeaderStream = value
End Set
End Property
Public Property FooterContent() As Byte()
Get
Return _FooterStream
End Get
Set(ByVal value As Byte())
_FooterStream = value
End Set
End Property

Public Property HeaderHTML() As String
Get
Return _HeaderHTML
End Get
Set(ByVal value As String)
_HeaderHTML = value
End Set
End Property
Public Property FooterHTML() As String
Get
Return _FooterHTML
End Get
Set(ByVal value As String)
_FooterHTML = value
End Set
End Property

Public Property letterHeader() As Document
Get
Return _headerPdf
End Get
Set(ByVal value As Document)
_headerPdf = value
End Set
End Property
Public Property letterFooter() As Document
Get
Return _footerPdf
End Get
Set(ByVal value As Document)
_footerPdf = value
End Set
End Property

Public Property UsesHeader() As Boolean
Get
Return _usesHeader
End Get
Set(ByVal value As Boolean)
_usesHeader = value
End Set
End Property

Public Property PageHeader() As PdfPTable
Get
Return _pageHeader
End Get
Set(ByVal value As PdfPTable)
_pageHeader = value
End Set
End Property

Public Property PageFooter() As PdfPTable
Get
Return _pageFooter
End Get
Set(ByVal value As PdfPTable)
_pageFooter = value
End Set
End Property


' we override the onOpenDocument method
Public Overrides Sub OnOpenDocument(ByVal writer As PdfWriter, ByVal document As Document)
MyBase.OnOpenDocument(writer, document)
Try
PrintTime = DateTime.Now
Catch de As DocumentException
Catch ioe As System.IO.IOException
End Try

End Sub

Public Overrides Sub OnStartPage(ByVal writer As PdfWriter, ByVal document As Document)
MyBase.OnStartPage(writer, document)
End Sub


Public Overrides Sub OnEndPage(ByVal writer As PdfWriter, ByVal document As Document)
MyBase.OnEndPage(writer, document)

Dim pageSize As Rectangle = document.PageSize

Dim htmlContext As HtmlPipelineContext = New HtmlPipelineContext(Nothing)
htmlContext.SetAcceptUnknown(True)
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory())

If Not HeaderContent Is Nothing And HeaderContent.Length > 0 And writer.PageNumber < 2 Then
Dim page As New Rectangle(document.PageSize.Width - 72.0F, document.PageSize.Height)
PageHeader.WriteSelectedRows(0, -1, 0, -1, document.LeftMargin, page.Height, writer.DirectContent)
End If
If writer.PageNumber > 1 Then
document.SetPageSize(New Rectangle(36.0F, 36.0F, 52.0F, PageFooter.TotalHeight))
End If


If Not FooterContent Is Nothing And FooterContent.Length > 0 Then
Dim page As New Rectangle(document.PageSize.Width - 72.0F, document.PageSize.Height)
PageFooter.WriteSelectedRows(0, -1, 0, -1, document.LeftMargin, PageFooter.TotalHeight, writer.DirectContent)
End If


Dim fontSize As Integer = 160
Dim xPosition As Integer = 300
Dim yPosition As Integer = 400
Dim angle As Integer = 45
Dim under As PdfContentByte = writer.DirectContentUnder
Dim baseFont As BaseFont = baseFont.CreateFont(baseFont.HELVETICA, baseFont.WINANSI, baseFont.EMBEDDED)
under.BeginText()
under.SetColorFill(BaseColor.LIGHT_GRAY)
under.SetFontAndSize(baseFont, fontSize)
under.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Preview", xPosition, yPosition, angle)
under.EndText()


End Sub


Public Overrides Sub OnCloseDocument(ByVal writer As PdfWriter, ByVal document As Document)
MyBase.OnCloseDocument(writer, document)
End Sub
End Class

我曾尝试更改 OnEndPage 和 OnStartPage 中的页边距,但都没有任何结果。我查看了上一个问题“ How do I change the margin for the second page in a PDF using iTextsharp?”,但看不到我将(或应该)添加 page.NewPage() 页面事件中 NewPage 的位置?

(同样作为一个子问题,在 Acrobat Reader X 中关闭时,我的 pdf 一直在说“您要保存更改吗”,我查看了之前的一个 SO 问题,它说使用 ToArray() 而不是 ToBuffer() ,我是否遗漏了什么?)

最佳答案

我相信我已经解决了这个问题,OnEndPage 函数的部分:

If writer.PageNumber > 1 Then

应该是
If writer.PageNumber = 1 Then

因为,根据我的阅读,任何页边距都会应用于后续页面。这意味着第 3 页的边距将更改,因为页码为 2,因此我需要在第 1 页而不是第 2 页的末尾设置边距。

关于vb.net - iTextSharp 对不同的页面应用不同的边距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19974620/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com