'''' This code is part of Document Solutions for PDF .NET demos.'' Copyright (c) MESCIUS inc. All rights reserved.''ImportsSystem.IOImportsSystem.DrawingImportsSystem.LinqImportsSystem.Collections.GenericImportsGrapeCity.Documents.PdfImportsGrapeCity.Documents.Pdf.RecognitionImportsGrapeCity.Documents.TextImports GCTEXT = GrapeCity.Documents.Text PublicClassGetTablePagesPublicFunctionCreatePDF(ByVal stream AsStream) AsIntegerConstDPIAsSingle = 72ConstmarginAsSingle = 36Dim doc = NewGcPdfDocument() Dim tf = NewTextFormat() With { .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Regular.ttf")), .FontSize = 9, .ForeColor = Color.Black }Dim tfHdr = NewTextFormat(tf) With { .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Bold.ttf")), .FontSize = 11, .ForeColor = Color.DarkBlue }Dim tfRed = NewTextFormat(tf) With {.ForeColor = Color.Red} Using fs = File.OpenRead(Path.Combine("Resources", "PDFs", "product-list.pdf"))Dim page = doc.NewPage() page.Landscape = TrueDim 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,NewRectangleF(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 = NewGcPdfDocument() docSrc.Load(fs) For i = 0To docSrc.Pages.Count - 1' TableExtractOptions allow you to fine-tune table recognition accounting for' specifics of the table formatting:Dim teo = NewTableExtractOptions()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.2FEndFunctionDim top = If(i = 0, DPI * 2, DPI)' Get the table at the specified bounds:Dim itable = docSrc.Pages(i).GetTable(NewRectangleF(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 = 0To itable.Rows.Count - 1Dim tfmt = If(row = 0, tfHdr, tf)For col = 0To itable.Cols.Count - 1Dim cell = itable.GetCell(row, col)If col > 0Then tl.Append(vbTab, tfmt)EndIfIf cell IsNothingThen tl.Append("<no cell>", tfRed)Else tl.Append(cell.Text, tfmt)EndIfNext tl.AppendLine()NextNext ' Print the extracted data:Dim to_ = NewTextSplitOptions(tl) With {.RestMarginTop = margin, .MinLinesInFirstParagraph = 2, .MinLinesInLastParagraph = 2} tl.PerformLayout(True)WhileTrueDim rest AsTextLayout = NothingDim splitResult = tl.Split(to_, rest) doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty)If splitResult <> SplitResult.SplitThenExitWhileEndIf tl = rest doc.NewPage().Landscape = TrueEndWhile ' Append the original document for reference: doc.MergeWithDocument(docSrc) doc.Save(stream)Return doc.Pages.CountEndUsingEndFunctionEndClass