VB.Net,如何检测页面结尾并继续在下一页上书写

时间:2014-11-15 17:01:20

标签: arrays vb.net pdf for-loop pdfsharp

我有一个VB.NET程序,它使用PDF Sharp将信息转储到PDF文件。我遇到的问题是,如果ypoint(页面长度)处于某个值,我无法弄清楚如何跳转到下一页。如果**在结尾之前**表示**。下面是我的pdf sharp dump的一部分。我以为我可以使用if then语句来增加计数器并将变量添加到pdfpage的末尾...例如

pdfpage(ypointcounter)....

这不起作用。你会看到我尝试将顶部(我的标题)分开,因为我不想在下一页重复这一点,并且不是我循环从多个数据集中转储信息的一部分。我知道我可以插入一个新页面,而且我也知道如何写入第二页。我想要做的是在我的循环中设置程序,以自动创建下一页,如果我在页面的末尾开始写入它。我假设我必须设置某种数组?

任何帮助?

我的代码是:

Try
yPoint = 0

Dim pdf As PdfDocument = New PdfDocument
pdf.Info.Title = "Last Hour Comparison"
Dim pdfPage As PdfPage = pdf.AddPage
Dim pdfPage1 As PdfPage = pdf.AddPage
Dim graph As XGraphics = XGraphics.FromPdfPage(pdfPage1)
Dim fontheader As XFont = New XFont("Arial", 12, XFontStyle.Bold) ' I used this as a header.  Basically-
'Just made the font bigger and style is BOLD
Dim font As XFont = New XFont("Arial", 11, XFontStyle.Regular)

'This sets the Header----------------------------------------------------------------------------

graph.DrawString("Test Last Hour Comparison for week of " & Weekstart, fontheader, XBrushes.Black, _
   New XRect(20, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft)
yPoint = yPoint + 40

'---------------------------------
'This is for building the Report ---------------------------------------------------------

'If ds.Tables(0).Rows.Count > 0 Then
graph.DrawString("Location", font, XBrushes.Black, _
    New XRect(20, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft)

graph.DrawString("Date", font, XBrushes.Black, _
    New XRect(120, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft)

graph.DrawString("# 6-7 Visits ", font, XBrushes.Black, _
New XRect(280, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft)

graph.DrawString("# 7-8 Visits ", font, XBrushes.Black, _
    New XRect(340, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft)

graph.DrawString("% Change ", font, XBrushes.Black, _
    New XRect(410, yPoint, pdfPage.Width.Point, pdfPage.Height.Point), XStringFormats.TopLeft)
Dim x As Integer
x = 0
LocationCounter = 1
ypointcounter = 0
**For i = 0 To 3
    GetLocation()
    yPoint = yPoint + 20
    If yPoint > 840 Then
        yPoint = 20
        ypointcounter = ypointcounter + 1


    End If**

    graph.DrawString(LocationName, font, XBrushes.Black, _
    New XRect(20, yPoint, pdfPage(ypointcounter).Width.Point, pdfPage(ypointcounter).Height.Point), XStringFormats.TopLeft)
    dtstartdate = Today.AddDays(-6)
    firsthourweektotal = 0
    secondhourweektotal = 0
    For z = 0 To 6
        firsthour = ds.Tables(0).Rows(x).Item(0)
        secondhour = ds2.Tables(0).Rows(x).Item(0)
        firsthourweektotal = firsthourweektotal + ds.Tables(0).Rows(x).Item(0)
        secondhourweektotal = secondhourweektotal + ds2.Tables(0).Rows(x).Item(0)
        If ds.Tables(0).Rows(x).Item(0) = 0 Then
            Percentage = 0
        Else
            Percentage = Math.Round(ds2.Tables(0).Rows(x).Item(0) / ds.Tables(0).Rows(x).Item(0) * 100, 2)
        End If

        graph.DrawString(dtstartdate.DayOfWeek.ToString & ", " & dtstartdate.Month & "/" & dtstartdate.Day, font, XBrushes.Black, _
        New XRect(110, yPoint, pdfPage(ypointcounter).Width.Point, pdfPage(ypointcounter).Height.Point), XStringFormats.TopLeft)

        graph.DrawString(firsthour, font, XBrushes.Black, _
        New XRect(288, yPoint, pdfPage(ypointcounter).Width.Point, pdfPage(ypointcounter).Height.Point), XStringFormats.TopLeft)

        graph.DrawString(secondhour, font, XBrushes.Black, _
        New XRect(352, yPoint, pdfPage(ypointcounter).Width.Point, pdfPage(ypointcounter).Height.Point), XStringFormats.TopLeft)

        graph.DrawString(Percentage, font, XBrushes.Black, _
        New XRect(418, yPoint, pdfPage(ypointcounter).Width.Point, pdfPage(ypointcounter).Height.Point), XStringFormats.TopLeft)
        dtstartdate = dtstartdate.AddDays(1)
        yPoint = yPoint + 20
        x = x + 1
    Next

2 个答案:

答案 0 :(得分:3)

你有点自己装入阵列的想法。听起来你真正想要的是一种开始新页面的方法,并在YPosition到达某一点时动态重绘标题。 注意:有了这样的问题,我们就会根据代码所做的看起来像来猜测结果,格式,布局和分组。例如,报告是按位置或日期分组还不完全清楚。这应该没关系,因为概念是相同的。

为此,我编写了一类基元来管理循环中的打印,并在需要时创建新页面。我的测试数据是Dictionary(Of String, List(of VisitInfo)),但正如我所说的,我认为我内心深处(根据标题中的“比较”)。我还将代码清理到Dispose资源,例如泄露在您身上的XGraphics个对象。

Public Class PDFReport

Private filePath As String
Private pdf As PdfDocument              ' this also needs to be disposed of
Private hFont As XFont
Private tFont As XFont

' the current page, current Y
Private pdfPage As PdfPage
Private CurrentY As Integer

Public Sub New(fPath As String)
    filePath = fPath

    pdf = New PdfDocument()
    pdf.Info.Title = "Last Hour Comparison"

    hFont = New XFont("Arial", 14, XFontStyle.Bold)
    tFont = New XFont("Arial", 11, XFontStyle.Regular)
End Sub

' this is specialized to print the dictionary of data
Public Sub WriteDoc(col As Dictionary(Of String, List(Of Visit)))

    ' skip page  ??  in OP
    pdf.AddPage()

    Dim vl As List(Of Visit)

    ' the string key is the location name
    For Each kvp As KeyValuePair(Of String, List(Of Visit)) In col    

        vl = kvp.Value

        ' this always starts a new page when the location
        ' changes even if there is room.
        ' otherwise, you could just call DrawHeader
        StartNewPage(vl(0).Location, vl(0).VDate.ToShortDateString)

        For Each v As Visit In vl

            If CurrentY >= 780 Then
                StartNewPage(v.Location, v.VDate.ToShortDateString)

            End If
            PrintLine(v)
        Next

    Next

    pdf.Save(filePath)
    pdf.Dispose()        ' dispose of resource

End Sub

' prints one line of data, increments Y 
Private Sub PrintLine(v As Visit)
    Using g As XGraphics = XGraphics.FromPdfPage(pdfPage)

        g.DrawString(String.Format("{0}, {1}/{2}",
                                   v.VDate.DayOfWeek.ToString,
                                   v.VDate.Month, v.VDate.Day),
                     tFont, XBrushes.Black,
                     New XRect(110, CurrentY, pdfPage.Width.Point,
                               pdfPage.Height.Point),
                     XStringFormats.TopLeft)

        g.DrawString(v.Foo.ToString, tFont, XBrushes.Black,
        New XRect(288, CurrentY, pdfPage.Width.Point, pdfPage.Height.Point),
        XStringFormats.TopLeft)

        g.DrawString(v.Bar.ToString, tFont, XBrushes.Black,
        New XRect(352, CurrentY, pdfPage.Width.Point, pdfPage.Height.Point),
        XStringFormats.TopLeft)

        CurrentY += 20
    End Using         ' dispose of XGraphic object


End Sub

' called when a new page is needed
' updates the pdf object var, Resets CurrentY to top of page
' and draws the header
Private Sub StartNewPage(loc As String, dt As String)
    pdfPage = pdf.AddPage()
    CurrentY = 20
    DrawHeader(loc, dt)
End Sub

Private Sub DrawHeader(loc As String, WeekStart As String)

    Using g As XGraphics = XGraphics.FromPdfPage(pdfPage)

        g.DrawString("Test Last Hour Comparison for week of " & WeekStart, hFont,
                     XBrushes.Black,
                     New XRect(20, CurrentY, pdfPage.Width.Point, 
                               pdfPage.Height.Point),
                     XStringFormats.TopLeft)

        CurrentY += 40
        g.DrawString(loc, tFont, XBrushes.Black,
            New XRect(20, CurrentY, pdfPage.Width.Point,
                      pdfPage.Height.Point),
            XStringFormats.TopLeft)

        g.DrawString("Date", tFont, XBrushes.Black,
            New XRect(120, CurrentY, pdfPage.Width.Point,
                      pdfPage.Height.Point),
            XStringFormats.TopLeft)

        g.DrawString("# 6-7 Visits ", tFont, XBrushes.Black,
        New XRect(280, CurrentY, pdfPage.Width.Point,
                  pdfPage.Height.Point),
        XStringFormats.TopLeft)

        g.DrawString("# 7-8 Visits ", tFont, XBrushes.Black,
            New XRect(340, CurrentY, pdfPage.Width.Point,
                      pdfPage.Height.Point),
            XStringFormats.TopLeft)

        g.DrawString("% Change ", tFont, XBrushes.Black, _
            New XRect(410, CurrentY, pdfPage.Width.Point,
                      pdfPage.Height.Point),
            XStringFormats.TopLeft)

    End Using        ' dispose of XGraphic object

    CurrentY += 20

End Sub

End Class

简而言之,绘制标题/标题被封装在一个过程中,在另一个过程中开始一个新页面并在另一个过程中打印一行数据。 WriteDoc,这只是一个控制程序,循环通过数据简单地将当前数据点(我的一个List项,你的ds项)提供给PrintLine。那个控制程序本身对你没什么好处。它的存在主要是为了展示如何协调对所描述的本地方法的调用以获得结果。

当它看到CurrentY超出某一点时,它会从馈线停止调用StartNewPage,然后继续。测试数据无关紧要,但通过点击按钮调用它很简单:

Dim pdf As New PDFReport("C:\Temp\Visits.pdf")
pdf.WriteDoc(col)     ' col is my dictionary of fake data

流程中的输出/分页符:

enter image description here

适用于我的机器 TM

link to larger image

答案 1 :(得分:0)

在您设置ypoint=20的if语句中,您还必须致电pdf.AddPageXGraphics.FromPdfPage(pdfPage1)继续绘制下一页。