Table Extraction
A PDF has no table structure to read back: a table is just text and lines placed at coordinates. The extractor infers the grid from those positions, so table extraction is a best-effort reconstruction rather than a lookup.
Tables come off the PageText, not the extractor directly:
ex, err := extractor.New(page)
if err != nil {
return err
}
pageText, _, _, err := ex.ExtractPageText()
if err != nil {
return err
}
for _, table := range pageText.Tables() {
for _, row := range table.Cells {
for _, cell := range row {
fmt.Print(cell.Text, "\t")
}
fmt.Println()
}
}A TextTable carries its bounding box, its width and height in cells as W and H,
and Cells as a row-major slice of slices. Each TableCell has the extracted Text
plus its own bounding box, which is what lets you match a cell back to a position on
the page.
Extraction mode matters here
Tables() returns results only in ExtractionModeLayout, the default, because table
detection is part of what that mode does. In ExtractionModeGrid it returns an empty
slice, and plain mode skips table building altogether. If Tables() comes back empty
on a document that visibly has tables, check the mode before anything else.
For a table whose columns you only need visually aligned rather than as cells,
PageText.GridText() is often a better fit and works from any mode. See
text extraction for the mode comparison.
Run the example
The example converts the tables of each page to CSV. extractPageTables does the
extraction, asStringTable flattens a TextTable into strings, and
normalizeTable tidies whitespace before writing. The remaining helpers deal with
command line paths and output directories.
git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/extract
go run pdf_tables.go input.pdfIf this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.