Table Export and Serialization#
TableItem is a Pydantic model (defined at line 2413) in docling_core/types/doc/document.py that holds a data: TableData field containing the full cell grid. It inherits standard Pydantic model_dump() / model_dump_json() for full serialization of the document structure, and exposes four dedicated export methods for structured downstream use.
Core Data Model#
TableCell stores per-cell semantics:
text— the cell's plain-text contentcolumn_header,row_header,row_section— boolean flags encoding semantic rolestart_row_offset_idx/end_row_offset_idx/start_col_offset_idx/end_col_offset_idx— span indicesrow_span,col_span— merge extentbbox— optional bounding box for page-level provenance
TableData.grid is a @computed_field that reconstructs the full 2-D num_rows × num_cols grid from the flat table_cells list, filling in span cells at every covered position.
RichTableCell is a subclass that holds a RefItem pointing to an arbitrary DocItem (e.g., a nested TableItem or PictureItem). Its _get_text() delegates to MarkdownDocSerializer when a document context is available, enabling rich cell content in all export paths.
Export Methods#
All export methods are on TableItem in document.py.
1. Pydantic model_dump / model_dump_json#
Standard Pydantic serialization — roundtrippable JSON-Schema-validated output. Used for persisting the full DoclingDocument including all TableCell metadata . The grid computed field is also serialized, so consumers receive both the flat table_cells list and the 2-D grid in one call .
2. export_to_dataframe(doc=...) → pd.DataFrame#
Converts the table into a pandas DataFrame. The implementation:
- Walks rows from top until it finds the first row with no
column_header=Truecells, treating all prior rows as header rows . - Concatenates multi-level header names with
.(e.g.,"native backend.TTS") . - Returns data rows as the DataFrame body; column names are
Noneif no header rows are detected . - Calling without
docis deprecated; passdocto resolveRichTableCellcontent correctly.
3. export_to_markdown(doc=...) → str#
When doc is provided, delegates to MarkdownDocSerializer. Without doc (deprecated), falls back to tabulate with GitHub-flavoured markdown, auto-detecting numeric columns for right-alignment . The first row is used as the header row in the fallback path; the serializer path preserves column_header semantics.
Current limitation:
MarkdownTableSerializerignoresimage_mode— table images are never embedded even whengenerate_table_images=Trueis set. This is an open feature request;PictureItemalready supports embedded/referenced image modes.
4. export_to_html(doc=...) → str#
Delegates to HTMLDocSerializer. Returns an empty string and logs an error if called without doc. Useful for complex or nested tables that can't be faithfully represented in markdown.
5. export_to_otsl(doc, ...) → str#
Produces OTSL (Open Table Serialization Language) token strings used by DocTags/OCR training pipelines. Maps each cell to a typed token :
ched— column header cellrhed— row header cellsrow— section rowfcel/ecel— full / empty cellucel/lcel/xcel— span cells (up / left / cross)nl— row terminator
Cell bounding-box locations are optionally embedded inline with add_cell_location=True.
6. export_to_doctags(doc, ...) → str#
Delegates to DocTagsDocSerializer. Supports add_location, add_cell_location, add_cell_text, and add_caption flags. The deprecated export_to_document_tokens forwards here .
HybridChunker Table Serialization#
By default, HybridChunker uses a triplet flat-text format that loses cell-to-header bindings:
**Use case**, 1 = Least-leaking devices. **Persona**, 1 = Marketing analyst.
The maintainers' recommended approach for switching to markdown format is to use a custom ChunkingSerializerProvider (see the advanced chunking docs) . This avoids the fragility of post-processing workarounds: once a chunk is persisted to a vector store, its meta.doc_items provenance link may be lost, making export_to_markdown() unreachable. Serializing at chunk-creation time bakes the format into the chunk .
For RAG pipelines where over half of chunks may be tables, the serialization choice is the dominant factor in embedding quality — flat triplet serialization destroys cell-to-column-header bindings that are the core semantic payload of structured tables .
Key Source Files#
| File | Purpose |
|---|---|
docling_core/types/doc/document.py | TableCell, TableData, TableItem with all export methods |
docling_core/transforms/serializer/markdown.py | MarkdownTableSerializer (markdown export path) |
docling_core/transforms/serializer/html.py | HTMLDocSerializer (HTML export path) |
docling_core/transforms/serializer/doctags.py | DocTagsDocSerializer (OTSL / DocTags export) |
docling_core/transforms/chunker/ | HybridChunker, ChunkingSerializerProvider |
Note on table image export: A workaround for embedding table images (e.g., for scanned/complex tables) is to crop the page image using the table's bounding box from
TableItem.prov[0].bboxand the page image fromdoc.pages. See issue #2820 and the discussion in for reference code.