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)
продолжить рисование на следующей странице.