GetTableData.vb
'' 
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' Copyright (c) GrapeCity inc. All rights reserved.
'' 
Imports System
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

' 表形式のデータを抽出
Public Class GetTableData
    Function CreatePDF(ByVal stream As Stream) As Integer
        Const DPI = 72.0F
        Const margin = 36.0F
        Dim doc = New GcPdfDocument()

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

        Using fs As New FileStream(Path.Combine("Resources", "PDFs", "zugferd-invoice.pdf"), FileMode.Open, FileAccess.Read)
            ' 大体の表の範囲を指定
            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(
                "このサンプルでは、表形式のデータを含むPDF(請求書のサンプル)を読み込み、" +
                "Page.GetTable()メソッドを使用しPDFから表形式のデータを抽出します。" +
                "抽出されたデータは、行とセルのリストとして出力されます。" +
                "表形式のデータを含む元のPDFは、参考として出力されるPDFにも追加されています。",
                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($"指定した座標に表は見つかりませんでした。", tfRed)
            Else
                tl.Append(vbCrLf + $"表には {itable.Cols.Count} つの列と {itable.Rows.Count} つの行があります。データは以下のとおりです。", 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("<セルなし>", tfRed)
                        Else
                            tl.Append(cell.Text, tfmt)
                        End If
                    Next
                    tl.AppendLine()
                Next
            End If

            Dim tso As TextSplitOptions = New TextSplitOptions(tl) With {.RestMarginTop = margin, .MinLinesInFirstParagraph = 2, .MinLinesInLastParagraph = 2}
            tl.PerformLayout(True)
            While True
                Dim rest As TextLayout = Nothing
                Dim SplitResult = tl.Split(tso, 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

            ' 参考のため元のドキュメントを追加
            doc.MergeWithDocument(docSrc)

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