GetTableData.vb
''
'' This code is part of Document Solutions for PDF .NET demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports System.Collections.Generic
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.Recognition
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Common
Imports GCTEXT = GrapeCity.Documents.Text

Public Class GetTableData
    Public Function CreatePDF(ByVal stream As Stream) As Integer
        Const DPI As Single = 72
        Const margin As Single = 36
        Dim doc = New GcPdfDocument()

        Dim tf = New TextFormat() With {
            .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Regular.ttf")),
            .FontSize = 9,
            .ForeColor = Color.Black
        }
        Dim tfHdr = New TextFormat(tf) With {
            .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Bold.ttf")),
            .FontSize = 11,
            .ForeColor = Color.DarkBlue
        }
        Dim tfRed = New TextFormat(tf) With {.ForeColor = Color.Red}

        Using fs = File.OpenRead(Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf"))
            ' The approx table bounds:
            Dim tableBounds = New RectangleF(0, 3 * DPI, 8.5F * DPI, 3.75F * DPI)

            Dim page = doc.NewPage()
            page.Landscape = True
            Dim g = page.Graphics

            Dim rc = Util.AddNote(
                "This sample loads a PDF that contains a table (a sample invoice), " &
                "and extracts the table from the PDF using the Page.GetTable() method. " &
                "The extracted data is printed as a list of rows and cells. " &
                "The sample invoice with the table is appended to the generated PDF for reference.",
                page,
                New RectangleF(margin, margin, page.Bounds.Width - margin * 2, page.Bounds.Height - margin * 2))

            Dim tl = g.CreateTextLayout()
            tl.MaxWidth = page.Bounds.Width
            tl.MaxHeight = page.Bounds.Height
            tl.MarginAll = margin
            tl.MarginTop = rc.Bottom
            tl.DefaultTabStops = 150
            tl.LineSpacingScaleFactor = 1.2F

            Dim docSrc = New GcPdfDocument()
            docSrc.Load(fs)

            Dim itable = docSrc.Pages(0).GetTable(tableBounds)

            If itable Is Nothing Then
                tl.AppendLine($"No table was found at the specified coordinates.", tfRed)
            Else
                tl.Append($"{vbLf}The table has {itable.Cols.Count} column(s) and {itable.Rows.Count} row(s), table data is:", tfHdr)
                tl.AppendParagraphBreak()
                For row = 0 To itable.Rows.Count - 1
                    Dim tfmt = If(row = 0, tfHdr, tf)
                    For col = 0 To itable.Cols.Count - 1
                        Dim cell = itable.GetCell(row, col)
                        If col > 0 Then
                            tl.Append(vbTab, tfmt)
                        End If
                        If cell Is Nothing Then
                            tl.Append("<no cell>", tfRed)
                        Else
                            tl.Append(cell.Text, tfmt)
                        End If
                    Next
                    tl.AppendLine()
                Next
            End If

            Dim to_ = New TextSplitOptions(tl) With {.RestMarginTop = margin, .MinLinesInFirstParagraph = 2, .MinLinesInLastParagraph = 2}
            tl.PerformLayout(True)
            While True
                Dim rest As TextLayout = Nothing
                Dim splitResult = tl.Split(to_, rest)
                doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty)
                If splitResult <> SplitResult.Split Then
                    Exit While
                End If
                tl = rest
                doc.NewPage().Landscape = True
            End While

            ' Append the original document for reference:
            doc.MergeWithDocument(docSrc)

            doc.Save(stream)
            Return doc.Pages.Count
        End Using
    End Function
End Class