GetTablePages.vb
C# VB
'''' This code is part of Document Solutions for PDF .NET demos.'' Copyright (c) MESCIUS inc. All rights reserved.''Imports System.IOImports System.DrawingImports System.LinqImports System.Collections.GenericImports GrapeCity.Documents.PdfImports GrapeCity.Documents.Pdf.RecognitionImports GrapeCity.Documents.TextImports GCTEXT = GrapeCity.Documents.Text
Public Class GetTablePages 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", "product-list.pdf")) Dim page = doc.NewPage() page.Landscape = True Dim g = page.Graphics
Dim rc = Util.AddNote( "This sample loads a PDF that contains a table split between several pages (a product price list), " & "and extracts the tables on all pages using the Page.GetTable() method. " & "The extracted data is printed as a list of rows and cells. " & "The source product list PDF is appended to the generated document 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 = 165
Dim docSrc = New GcPdfDocument() docSrc.Load(fs)
For i = 0 To docSrc.Pages.Count - 1 ' TableExtractOptions allow you to fine-tune table recognition accounting for ' specifics of the table formatting: Dim teo = New TableExtractOptions() Dim GetMinimumDistanceBetweenRows = teo.GetMinimumDistanceBetweenRows ' In this particular case, we slightly increase the minimum distance between rows ' to make sure cells with wrapped text are not mistaken for two cells: teo.GetMinimumDistanceBetweenRows = Function(list) Dim res = GetMinimumDistanceBetweenRows(list) Return res * 1.2F End Function Dim top = If(i = 0, DPI * 2, DPI) ' Get the table at the specified bounds: Dim itable = docSrc.Pages(i).GetTable(New RectangleF(DPI * 0.25F, top, DPI * 8, DPI * 10.5F - top), teo)
' Add table data to the text layout: tl.Append($"{vbLf}Table on page {i + 1} of the source document 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 Next
' Print the extracted data: 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 FunctionEnd Class