VB.Net, как определить конец страницы и продолжить запись на следующей странице

У меня есть программа VB.NET, которая использует PDF Sharp для выгрузки информации в файл PDF. Проблема у меня в том, что я не могу понять, как перейти на следующую страницу, если ypoint (длина страницы) имеет определенное значение. Обозначается ** перед if ** в конце if. Ниже раздел моего резкого дампа PDF. Я подумал, что мог бы использовать оператор if then, чтобы увеличить счетчик и добавить переменную в конец pdf-страницы... например

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 ответа

Решение

Вы как бы подобрали себе идею массивов. Похоже, что вы действительно хотите, это способ начать новую страницу и перерисовать заголовок на лету, когда 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, которая является просто процедурой управления, проходит по данным, просто передавая текущую точку данных (элемент списка в моем, элемент ds в вашем) PrintLine, Эта процедура контроля сама по себе не принесет вам пользы. Он существует главным образом, чтобы показать, как организовать вызовы локальных методов, описанных для получения результата.

Когда он видит CurrentY находится за пределами определенной точки, это делает паузу от кормящих линий, чтобы позвонить StartNewPageзатем продолжается. Данные теста не имеют значения, но вызвать их одним нажатием кнопки просто:

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

Вывод / разрыв страницы в потоке:

Работает на моей машинеТМ

ссылка на увеличенное изображение

В вашем заявлении, если вы установите ypoint=20 вам также нужно позвонить pdf.AddPage а также XGraphics.FromPdfPage(pdfPage1) продолжить рисование на следующей странице.

Другие вопросы по тегам