exstruct 0.3.6__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {exstruct-0.3.6 → exstruct-0.4.0}/PKG-INFO +34 -2
- {exstruct-0.3.6 → exstruct-0.4.0}/README.md +25 -1
- {exstruct-0.3.6 → exstruct-0.4.0}/pyproject.toml +26 -20
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/__init__.py +7 -19
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/backends/base.py +9 -1
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/backends/com_backend.py +33 -8
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/backends/openpyxl_backend.py +32 -6
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/cells.py +432 -33
- exstruct-0.4.0/src/exstruct/core/integrate.py +62 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/modeling.py +3 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/pipeline.py +260 -61
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/shapes.py +1 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/workbook.py +9 -6
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/engine.py +43 -8
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/io/__init__.py +20 -1
- exstruct-0.4.0/src/exstruct/mcp/__init__.py +59 -0
- exstruct-0.4.0/src/exstruct/mcp/chunk_reader.py +413 -0
- exstruct-0.4.0/src/exstruct/mcp/extract_runner.py +309 -0
- exstruct-0.4.0/src/exstruct/mcp/io.py +61 -0
- exstruct-0.4.0/src/exstruct/mcp/server.py +312 -0
- exstruct-0.4.0/src/exstruct/mcp/tools.py +203 -0
- exstruct-0.4.0/src/exstruct/mcp/validate_input.py +76 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/models/__init__.py +7 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/models/maps.py +13 -13
- exstruct-0.4.0/src/exstruct/render/__init__.py +636 -0
- exstruct-0.3.6/src/exstruct/core/integrate.py +0 -58
- exstruct-0.3.6/src/exstruct/render/__init__.py +0 -239
- {exstruct-0.3.6 → exstruct-0.4.0}/LICENSE +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/cli/availability.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/cli/main.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/__init__.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/backends/__init__.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/charts.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/logging_utils.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/core/ranges.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/errors.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/io/serialize.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/models/types.py +0 -0
- {exstruct-0.3.6 → exstruct-0.4.0}/src/exstruct/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: exstruct
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Excel to structured JSON (tables, shapes, charts) for LLM/RAG pipelines
|
|
5
5
|
Keywords: excel,structure,data,exstruct
|
|
6
6
|
Author: harumiWeb
|
|
@@ -39,6 +39,12 @@ Requires-Dist: pandas>=2.3.3
|
|
|
39
39
|
Requires-Dist: pydantic>=2.12.5
|
|
40
40
|
Requires-Dist: scipy>=1.16.3
|
|
41
41
|
Requires-Dist: xlwings>=0.33.16
|
|
42
|
+
Requires-Dist: pyyaml>=6.0.3 ; extra == 'all'
|
|
43
|
+
Requires-Dist: python-toon>=0.1.3 ; extra == 'all'
|
|
44
|
+
Requires-Dist: pypdfium2>=5.1.0 ; extra == 'all'
|
|
45
|
+
Requires-Dist: pillow>=12.0.0 ; extra == 'all'
|
|
46
|
+
Requires-Dist: mcp>=1.6.0,<2.0.0 ; extra == 'all'
|
|
47
|
+
Requires-Dist: mcp>=1.6.0,<2.0.0 ; extra == 'mcp'
|
|
42
48
|
Requires-Dist: pypdfium2>=5.1.0 ; extra == 'render'
|
|
43
49
|
Requires-Dist: pillow>=12.0.0 ; extra == 'render'
|
|
44
50
|
Requires-Dist: python-toon>=0.1.3 ; extra == 'toon'
|
|
@@ -48,6 +54,8 @@ Project-URL: Documentation, https://harumiweb.github.io/exstruct/
|
|
|
48
54
|
Project-URL: Homepage, https://harumiweb.github.io/exstruct/
|
|
49
55
|
Project-URL: Issues, https://github.com/harumiWeb/exstruct/issues
|
|
50
56
|
Project-URL: Repository, https://github.com/harumiWeb/exstruct
|
|
57
|
+
Provides-Extra: all
|
|
58
|
+
Provides-Extra: mcp
|
|
51
59
|
Provides-Extra: render
|
|
52
60
|
Provides-Extra: toon
|
|
53
61
|
Provides-Extra: yaml
|
|
@@ -67,6 +75,7 @@ ExStruct reads Excel workbooks and outputs structured data (cells, table candida
|
|
|
67
75
|
|
|
68
76
|
- **Excel → Structured JSON**: cells, shapes, charts, smartart, table candidates, print areas/views, and auto page-break areas per sheet.
|
|
69
77
|
- **Output modes**: `light` (cells + table candidates + print areas; no COM, shapes/charts empty), `standard` (texted shapes + arrows, charts, smartart, merged cell ranges, print areas), `verbose` (all shapes with width/height, charts with size, merged cell ranges, print areas). Verbose also emits cell hyperlinks and `colors_map`. Size output is flag-controlled.
|
|
78
|
+
- **Formula map extraction**: emits `formulas_map` (formula string -> cell coordinates) via openpyxl/COM; enabled by default in `verbose` or via `include_formulas_map`.
|
|
70
79
|
- **Auto page-break export (COM only)**: capture Excel-computed auto page breaks and write per-area JSON/YAML/TOON when requested (CLI option appears only when COM is available).
|
|
71
80
|
- **Formats**: JSON (compact by default, `--pretty` available), YAML, TOON (optional dependencies).
|
|
72
81
|
- **Table detection tuning**: adjust heuristics at runtime via API.
|
|
@@ -106,6 +115,30 @@ exstruct input.xlsx --pdf --image # PDF and PNGs (Excel required)
|
|
|
106
115
|
|
|
107
116
|
Auto page-break exports are available via API and CLI when Excel/COM is available; the CLI exposes `--auto-page-breaks-dir` only in COM-capable environments.
|
|
108
117
|
|
|
118
|
+
## MCP Server (stdio)
|
|
119
|
+
|
|
120
|
+
Install the MCP extras and run the stdio server:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
pip install exstruct[mcp]
|
|
124
|
+
exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict rename
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Available tools:
|
|
128
|
+
|
|
129
|
+
- `exstruct.extract`
|
|
130
|
+
- `exstruct.read_json_chunk`
|
|
131
|
+
- `exstruct.validate_input`
|
|
132
|
+
|
|
133
|
+
Notes:
|
|
134
|
+
|
|
135
|
+
- Logs go to stderr (and optionally `--log-file`) to avoid contaminating stdio responses.
|
|
136
|
+
- On Windows with Excel, standard/verbose can use COM for richer extraction. On non-Windows, COM is unavailable and extraction uses openpyxl-based fallbacks.
|
|
137
|
+
|
|
138
|
+
MCP Setup Guide for Each AI Agent:
|
|
139
|
+
|
|
140
|
+
[MCP Server](https://harumiweb.github.io/exstruct/mcp/)
|
|
141
|
+
|
|
109
142
|
## Quick Start (Python)
|
|
110
143
|
|
|
111
144
|
```python
|
|
@@ -391,7 +424,6 @@ flowchart TD
|
|
|
391
424
|
```
|
|
392
425
|
````
|
|
393
426
|
|
|
394
|
-
|
|
395
427
|
## Example 2: General Application Form
|
|
396
428
|
|
|
397
429
|
### Excel Sheet
|
|
@@ -12,6 +12,7 @@ ExStruct reads Excel workbooks and outputs structured data (cells, table candida
|
|
|
12
12
|
|
|
13
13
|
- **Excel → Structured JSON**: cells, shapes, charts, smartart, table candidates, print areas/views, and auto page-break areas per sheet.
|
|
14
14
|
- **Output modes**: `light` (cells + table candidates + print areas; no COM, shapes/charts empty), `standard` (texted shapes + arrows, charts, smartart, merged cell ranges, print areas), `verbose` (all shapes with width/height, charts with size, merged cell ranges, print areas). Verbose also emits cell hyperlinks and `colors_map`. Size output is flag-controlled.
|
|
15
|
+
- **Formula map extraction**: emits `formulas_map` (formula string -> cell coordinates) via openpyxl/COM; enabled by default in `verbose` or via `include_formulas_map`.
|
|
15
16
|
- **Auto page-break export (COM only)**: capture Excel-computed auto page breaks and write per-area JSON/YAML/TOON when requested (CLI option appears only when COM is available).
|
|
16
17
|
- **Formats**: JSON (compact by default, `--pretty` available), YAML, TOON (optional dependencies).
|
|
17
18
|
- **Table detection tuning**: adjust heuristics at runtime via API.
|
|
@@ -51,6 +52,30 @@ exstruct input.xlsx --pdf --image # PDF and PNGs (Excel required)
|
|
|
51
52
|
|
|
52
53
|
Auto page-break exports are available via API and CLI when Excel/COM is available; the CLI exposes `--auto-page-breaks-dir` only in COM-capable environments.
|
|
53
54
|
|
|
55
|
+
## MCP Server (stdio)
|
|
56
|
+
|
|
57
|
+
Install the MCP extras and run the stdio server:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install exstruct[mcp]
|
|
61
|
+
exstruct-mcp --root C:\data --log-file C:\logs\exstruct-mcp.log --on-conflict rename
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Available tools:
|
|
65
|
+
|
|
66
|
+
- `exstruct.extract`
|
|
67
|
+
- `exstruct.read_json_chunk`
|
|
68
|
+
- `exstruct.validate_input`
|
|
69
|
+
|
|
70
|
+
Notes:
|
|
71
|
+
|
|
72
|
+
- Logs go to stderr (and optionally `--log-file`) to avoid contaminating stdio responses.
|
|
73
|
+
- On Windows with Excel, standard/verbose can use COM for richer extraction. On non-Windows, COM is unavailable and extraction uses openpyxl-based fallbacks.
|
|
74
|
+
|
|
75
|
+
MCP Setup Guide for Each AI Agent:
|
|
76
|
+
|
|
77
|
+
[MCP Server](https://harumiweb.github.io/exstruct/mcp/)
|
|
78
|
+
|
|
54
79
|
## Quick Start (Python)
|
|
55
80
|
|
|
56
81
|
```python
|
|
@@ -336,7 +361,6 @@ flowchart TD
|
|
|
336
361
|
```
|
|
337
362
|
````
|
|
338
363
|
|
|
339
|
-
|
|
340
364
|
## Example 2: General Application Form
|
|
341
365
|
|
|
342
366
|
### Excel Sheet
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "exstruct"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
description = "Excel to structured JSON (tables, shapes, charts) for LLM/RAG pipelines"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { file = "LICENSE" }
|
|
@@ -37,12 +37,21 @@ dev = [
|
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
[project.optional-dependencies]
|
|
40
|
+
all = [
|
|
41
|
+
"pyyaml>=6.0.3",
|
|
42
|
+
"python-toon>=0.1.3",
|
|
43
|
+
"pypdfium2>=5.1.0",
|
|
44
|
+
"Pillow>=12.0.0",
|
|
45
|
+
"mcp>=1.6.0,<2.0.0",
|
|
46
|
+
]
|
|
40
47
|
yaml = ["pyyaml>=6.0.3"]
|
|
41
48
|
toon = ["python-toon>=0.1.3"]
|
|
42
49
|
render = ["pypdfium2>=5.1.0", "Pillow>=12.0.0"]
|
|
50
|
+
mcp = ["mcp>=1.6.0,<2.0.0"]
|
|
43
51
|
|
|
44
52
|
[project.scripts]
|
|
45
53
|
exstruct = "exstruct.cli.main:main"
|
|
54
|
+
exstruct-mcp = "exstruct.mcp.server:main"
|
|
46
55
|
|
|
47
56
|
[project.urls]
|
|
48
57
|
Homepage = "https://harumiweb.github.io/exstruct/"
|
|
@@ -60,7 +69,10 @@ omit = [
|
|
|
60
69
|
[tool.ruff]
|
|
61
70
|
target-version = "py311"
|
|
62
71
|
src = ["exstruct"]
|
|
72
|
+
fix = true
|
|
63
73
|
|
|
74
|
+
# 静的解析ルール
|
|
75
|
+
[tool.ruff.lint]
|
|
64
76
|
select = [
|
|
65
77
|
"E", # pycodestyle errors
|
|
66
78
|
"W", # pycodestyle warnings
|
|
@@ -75,43 +87,36 @@ select = [
|
|
|
75
87
|
]
|
|
76
88
|
|
|
77
89
|
ignore = [
|
|
78
|
-
"E501", #
|
|
79
|
-
"B008", # Pydantic の default_factory
|
|
80
|
-
"ANN101", # self
|
|
81
|
-
"ANN102", # cls
|
|
90
|
+
"E501", # 長い行は許容(Excel JSON は長くなりがち)
|
|
91
|
+
"B008", # Pydantic の default_factory を使用するため
|
|
92
|
+
"ANN101", # self の型注釈は省略可能
|
|
93
|
+
"ANN102", # cls の型注釈は省略可能
|
|
82
94
|
]
|
|
83
95
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
# 型ヒントのスタイル
|
|
87
|
-
[tool.ruff.lint]
|
|
88
|
-
extend-select = ["ANN"]
|
|
89
|
-
|
|
90
|
-
# import の並び替え設定
|
|
91
|
-
[tool.ruff.isort]
|
|
96
|
+
# import の並び順
|
|
97
|
+
[tool.ruff.lint.isort]
|
|
92
98
|
combine-as-imports = true
|
|
93
99
|
known-first-party = ["exstruct"]
|
|
94
100
|
force-sort-within-sections = true
|
|
95
101
|
|
|
96
|
-
#
|
|
97
|
-
[tool.ruff.mccabe]
|
|
102
|
+
# 複雑度の最大値
|
|
103
|
+
[tool.ruff.lint.mccabe]
|
|
98
104
|
max-complexity = 12
|
|
99
105
|
|
|
100
|
-
[tool.ruff.per-file-ignores]
|
|
106
|
+
[tool.ruff.lint.per-file-ignores]
|
|
101
107
|
"tests/**/*.py" = ["N802", "N803", "N806"]
|
|
102
108
|
|
|
103
|
-
|
|
104
109
|
[tool.mypy]
|
|
105
110
|
packages = ["exstruct"]
|
|
106
111
|
python_version = "3.11"
|
|
107
112
|
|
|
108
|
-
#
|
|
113
|
+
# 外部ライブラリの型情報がない場合は無視
|
|
109
114
|
ignore_missing_imports = true
|
|
110
115
|
|
|
111
|
-
#
|
|
116
|
+
# 厳格モードを有効化
|
|
112
117
|
strict = true
|
|
113
118
|
|
|
114
|
-
# Pydantic v2
|
|
119
|
+
# Pydantic v2 対応
|
|
115
120
|
plugins = ["pydantic.mypy"]
|
|
116
121
|
|
|
117
122
|
[tool.pytest.ini_options]
|
|
@@ -124,6 +129,7 @@ markers = [
|
|
|
124
129
|
ruff = "ruff check ."
|
|
125
130
|
ruff-fix = "ruff check . --fix"
|
|
126
131
|
mypy = "mypy src/exstruct --strict"
|
|
132
|
+
precommit-run = "pre-commit run -a"
|
|
127
133
|
test = "pytest -vv --cov=exstruct --cov-report=term-missing --cov-report=xml" # uv sync --extra render --extra toon
|
|
128
134
|
test-unit = "pytest -vv -m \"not com and not render\" --cov=exstruct --cov-report=term-missing --cov-report=xml"
|
|
129
135
|
test-com = "pytest -vv -m \"com\" --cov=exstruct --cov-report=term-missing --cov-report=xml"
|
|
@@ -90,36 +90,24 @@ ExtractionMode = Literal["light", "standard", "verbose"]
|
|
|
90
90
|
|
|
91
91
|
def extract(file_path: str | Path, mode: ExtractionMode = "standard") -> WorkbookData:
|
|
92
92
|
"""
|
|
93
|
-
|
|
93
|
+
Extracts an Excel workbook into a WorkbookData structure.
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
file_path: Path to .xlsx
|
|
97
|
-
mode: "light" / "standard"
|
|
98
|
-
- light: cells + table detection only (no COM, shapes/charts empty). Print areas via openpyxl.
|
|
99
|
-
- standard: texted shapes + arrows + charts (COM if available), print areas included. Shape/chart size is kept but hidden by default in output.
|
|
100
|
-
- verbose: all shapes (including textless) with size, charts with size, and colors_map.
|
|
95
|
+
Parameters:
|
|
96
|
+
file_path (str | Path): Path to the workbook file (.xlsx, .xlsm, .xls).
|
|
97
|
+
mode (ExtractionMode): Extraction detail level. "light" includes cells and table detection only (no COM, shapes/charts empty; print areas via openpyxl). "standard" includes texted shapes, arrows, charts (COM if available) and print areas. "verbose" also includes shape/chart sizes, cell link map, colors map, and formulas map.
|
|
101
98
|
|
|
102
99
|
Returns:
|
|
103
|
-
WorkbookData containing sheets, rows, shapes, charts, and print areas.
|
|
104
|
-
|
|
105
|
-
Raises:
|
|
106
|
-
ValueError: If an invalid mode is provided.
|
|
107
|
-
|
|
108
|
-
Examples:
|
|
109
|
-
Extract with hyperlinks (verbose) and inspect table candidates:
|
|
110
|
-
|
|
111
|
-
>>> from exstruct import extract
|
|
112
|
-
>>> wb = extract("input.xlsx", mode="verbose")
|
|
113
|
-
>>> wb.sheets["Sheet1"].table_candidates
|
|
114
|
-
['A1:B5']
|
|
100
|
+
WorkbookData: Parsed workbook representation containing sheets, rows, shapes, charts, and print areas.
|
|
115
101
|
"""
|
|
116
102
|
include_links = True if mode == "verbose" else False
|
|
117
103
|
include_colors_map = True if mode == "verbose" else None
|
|
104
|
+
include_formulas_map = True if mode == "verbose" else None
|
|
118
105
|
engine = ExStructEngine(
|
|
119
106
|
options=StructOptions(
|
|
120
107
|
mode=mode,
|
|
121
108
|
include_cell_links=include_links,
|
|
122
109
|
include_colors_map=include_colors_map,
|
|
110
|
+
include_formulas_map=include_formulas_map,
|
|
123
111
|
)
|
|
124
112
|
)
|
|
125
113
|
return engine.extract(file_path, mode=mode)
|
|
@@ -4,7 +4,7 @@ from dataclasses import dataclass
|
|
|
4
4
|
from typing import Protocol
|
|
5
5
|
|
|
6
6
|
from ...models import CellRow, PrintArea
|
|
7
|
-
from ..cells import MergedCellRange, WorkbookColorsMap
|
|
7
|
+
from ..cells import MergedCellRange, WorkbookColorsMap, WorkbookFormulasMap
|
|
8
8
|
|
|
9
9
|
CellData = dict[str, list[CellRow]]
|
|
10
10
|
PrintAreaData = dict[str, list[PrintArea]]
|
|
@@ -40,3 +40,11 @@ class Backend(Protocol):
|
|
|
40
40
|
|
|
41
41
|
def extract_merged_cells(self) -> MergedCellData:
|
|
42
42
|
"""Extract merged cell ranges from the workbook."""
|
|
43
|
+
|
|
44
|
+
def extract_formulas_map(self) -> WorkbookFormulasMap | None:
|
|
45
|
+
"""
|
|
46
|
+
Retrieve the workbook's formulas organized by worksheet.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
WorkbookFormulasMap | None: A mapping of worksheet identifiers to their formulas, or `None` if the backend cannot provide a formulas map.
|
|
50
|
+
"""
|
|
@@ -9,7 +9,12 @@ from typing import Any, cast
|
|
|
9
9
|
import xlwings as xw
|
|
10
10
|
|
|
11
11
|
from ...models import PrintArea
|
|
12
|
-
from ..cells import
|
|
12
|
+
from ..cells import (
|
|
13
|
+
WorkbookColorsMap,
|
|
14
|
+
WorkbookFormulasMap,
|
|
15
|
+
extract_sheet_colors_map_com,
|
|
16
|
+
extract_sheet_formulas_map_com,
|
|
17
|
+
)
|
|
13
18
|
from ..ranges import parse_range_zero_based
|
|
14
19
|
from .base import MergedCellData, PrintAreaData
|
|
15
20
|
|
|
@@ -58,14 +63,15 @@ class ComBackend:
|
|
|
58
63
|
def extract_colors_map(
|
|
59
64
|
self, *, include_default_background: bool, ignore_colors: set[str] | None
|
|
60
65
|
) -> WorkbookColorsMap | None:
|
|
61
|
-
"""
|
|
66
|
+
"""
|
|
67
|
+
Extract a workbook colors map using the Excel COM API.
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
include_default_background:
|
|
65
|
-
ignore_colors: Optional set of color keys to
|
|
69
|
+
Parameters:
|
|
70
|
+
include_default_background (bool): Include the workbook's default background color in the resulting map.
|
|
71
|
+
ignore_colors (set[str] | None): Optional set of color keys to exclude from the map.
|
|
66
72
|
|
|
67
73
|
Returns:
|
|
68
|
-
WorkbookColorsMap
|
|
74
|
+
WorkbookColorsMap | None: A mapping of workbook color definitions when extraction succeeds, or `None` if COM extraction fails.
|
|
69
75
|
"""
|
|
70
76
|
try:
|
|
71
77
|
return extract_sheet_colors_map_com(
|
|
@@ -80,11 +86,30 @@ class ComBackend:
|
|
|
80
86
|
)
|
|
81
87
|
return None
|
|
82
88
|
|
|
89
|
+
def extract_formulas_map(self) -> WorkbookFormulasMap | None:
|
|
90
|
+
"""
|
|
91
|
+
Extracts the workbook's formulas map using COM.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
WorkbookFormulasMap or None: The extracted formulas map, or `None` if extraction failed.
|
|
95
|
+
"""
|
|
96
|
+
try:
|
|
97
|
+
return extract_sheet_formulas_map_com(self.workbook)
|
|
98
|
+
except Exception as exc:
|
|
99
|
+
logger.warning(
|
|
100
|
+
"COM formula map extraction failed; skipping formulas_map. (%r)",
|
|
101
|
+
exc,
|
|
102
|
+
)
|
|
103
|
+
return None
|
|
104
|
+
|
|
83
105
|
def extract_auto_page_breaks(self) -> PrintAreaData:
|
|
84
|
-
"""
|
|
106
|
+
"""
|
|
107
|
+
Compute auto page-break rectangles for each worksheet using Excel COM.
|
|
108
|
+
|
|
109
|
+
For each sheet, determine the sheet's print area (PageSetup.PrintArea or the used range) and split it into sub-rectangles along Excel's horizontal and vertical page breaks; parts that reference a different sheet are ignored. If extraction for a sheet fails, the sheet is skipped and a warning is logged.
|
|
85
110
|
|
|
86
111
|
Returns:
|
|
87
|
-
Mapping
|
|
112
|
+
Mapping from sheet name to a list of PrintArea entries. Each PrintArea describes a rectangular region with `r1` and `r2` as 1-based row indices and `c1` and `c2` as 0-based column indices.
|
|
88
113
|
"""
|
|
89
114
|
results: PrintAreaData = {}
|
|
90
115
|
for sheet in self.workbook.sheets:
|
|
@@ -5,14 +5,17 @@ from __future__ import annotations
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
import logging
|
|
7
7
|
from pathlib import Path
|
|
8
|
+
from typing import Literal
|
|
8
9
|
|
|
9
10
|
from ...models import PrintArea
|
|
10
11
|
from ..cells import (
|
|
11
12
|
WorkbookColorsMap,
|
|
13
|
+
WorkbookFormulasMap,
|
|
12
14
|
detect_tables_openpyxl,
|
|
13
15
|
extract_sheet_cells,
|
|
14
16
|
extract_sheet_cells_with_links,
|
|
15
17
|
extract_sheet_colors_map,
|
|
18
|
+
extract_sheet_formulas_map,
|
|
16
19
|
extract_sheet_merged_cells,
|
|
17
20
|
)
|
|
18
21
|
from ..ranges import parse_range_zero_based
|
|
@@ -99,17 +102,40 @@ class OpenpyxlBackend:
|
|
|
99
102
|
except Exception:
|
|
100
103
|
return {}
|
|
101
104
|
|
|
102
|
-
def
|
|
103
|
-
"""
|
|
105
|
+
def extract_formulas_map(self) -> WorkbookFormulasMap | None:
|
|
106
|
+
"""
|
|
107
|
+
Extract a mapping of workbook formulas for each sheet.
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
Returns:
|
|
110
|
+
WorkbookFormulasMap | None: A mapping from sheet name to its formulas, or `None` if extraction fails.
|
|
111
|
+
"""
|
|
112
|
+
try:
|
|
113
|
+
return extract_sheet_formulas_map(self.file_path)
|
|
114
|
+
except Exception as exc:
|
|
115
|
+
logger.warning(
|
|
116
|
+
"Formula map extraction failed; skipping formulas_map. (%r)", exc
|
|
117
|
+
)
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
def detect_tables(
|
|
121
|
+
self,
|
|
122
|
+
sheet_name: str,
|
|
123
|
+
*,
|
|
124
|
+
mode: Literal["light", "standard", "verbose"] = "standard",
|
|
125
|
+
) -> list[str]:
|
|
126
|
+
"""
|
|
127
|
+
Detects table candidate ranges within the specified worksheet.
|
|
128
|
+
|
|
129
|
+
Parameters:
|
|
130
|
+
sheet_name (str): Name of the worksheet to analyze for table candidates.
|
|
131
|
+
mode (Literal["light", "standard", "verbose"]): Extraction mode, used to
|
|
132
|
+
adjust scan limits in openpyxl-based detection.
|
|
107
133
|
|
|
108
134
|
Returns:
|
|
109
|
-
|
|
135
|
+
list[str]: Detected table candidate ranges as A1-style range strings; empty list if none are found or detection fails.
|
|
110
136
|
"""
|
|
111
137
|
try:
|
|
112
|
-
return detect_tables_openpyxl(self.file_path, sheet_name)
|
|
138
|
+
return detect_tables_openpyxl(self.file_path, sheet_name, mode=mode)
|
|
113
139
|
except Exception:
|
|
114
140
|
return []
|
|
115
141
|
|