2014-11-15 1 views
-2

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

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 
+0

Будете ли вы награждать бу nty для этого? – Plutonix

ответ

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

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

link to larger image

1

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

+0

Да, я вызываю страницу выше. И я знаю, как писать на вторую страницу. Моя проблема в том, как я программно переключаюсь на pdfPage1, так как это цикл? Я сбрасываю 20 различных запросов на страницу pdf в цикле, поэтому, возможно, после 4-го запроса, я хочу, чтобы он перешел на следующую страницу. Вот почему я думал о (ypointcounter), как и в случае, если он «2», он перейдет на страницу pdfpage (2) или pdfpage2. Имеет ли это смысл? – Shmewnix

+1

PdfDocument хранит все страницы, поэтому нет необходимости создавать еще один «массив» для страниц. И, как правило, вам нужна только текущая страница. У меня есть опыт работы с PDFsharp, но практически никакой опыт работы с VB. Поэтому, если у вас нет проблемы с PDFsharp и просто хочу знать, как хорошо писать в VB, я ухожу. –