The gap Markdown tables hide

export_to_markdown() has produced a clean pipe table for quarterly_report.pdf since Lesson 2, but a Markdown table is still a string, getting "the North/Hardware growth number" out of it means re-parsing pipes and whitespace. TableFormer, docling's dedicated table-structure model, already did the real work of understanding rows, columns, and headers, export_to_dataframe() exposes that structure directly as a pandas DataFrame, no re-parsing required.

TableFormerMode.FAST vs ACCURATE

from docling.datamodel.pipeline_options import TableFormerMode
options = PdfPipelineOptions()
options.table_structure_options.mode = TableFormerMode.ACCURATE # the default

ACCURATE is what every earlier lesson has been using implicitly, it's the default. TableFormerMode.FAST trades some structural precision (particularly on tables with merged or spanning cells) for speed, worth reaching for on a large batch of simple, regularly-shaped tables where ACCURATE's extra care doesn't change the outcome.

export_to_dataframe()

table = result.document.tables[0]
df = table.export_to_dataframe(result.document)

Recent docling versions want the owning DoclingDocument passed in (a deprecation warning appears if you omit it), since a table item's cell references are resolved against the document it belongs to. The result is an ordinary pandas DataFrame: filter it, join it, feed it to pandas.read_sql-shaped code, anything you'd do with tabular data that didn't come from a PDF.

Checkpoint

  • TableFormer: docling's dedicated table-structure model, the thing actually producing correct rows and columns, not just text in a grid-shaped region.
  • TableFormerMode.ACCURATE vs FAST: ACCURATE is the default, FAST trades precision on complex tables for throughput.
  • export_to_dataframe(doc): a table's structure as a real pandas DataFrame, filterable and joinable, not a Markdown string to re-parse.

If anything here still feels unclear, ask before moving to Lesson 9.