增加docling作为解析器
This commit is contained in:
@@ -6,17 +6,19 @@
|
|||||||
|
|
||||||
该解析器按优先级尝试多种解析方法,确保最大兼容性:
|
该解析器按优先级尝试多种解析方法,确保最大兼容性:
|
||||||
|
|
||||||
1. **pypandoc-binary** (DOCX 专用,内置 Pandoc) - 生成结构化 Markdown
|
1. **Docling** (docling.document_converter) - 通用解析方案,优先覆盖 DOCX/PPTX/XLSX/PDF 并内置 OCR 能力
|
||||||
2. **MarkItDown** (微软官方库) - 推荐使用,格式最规范
|
2. **pypandoc-binary** (DOCX 专用,内置 Pandoc) - 生成结构化 Markdown
|
||||||
3. **python-docx / python-pptx / pandas** (成熟的 Python 库) - 输出最详细
|
3. **MarkItDown** (微软官方库) - 推荐使用,格式规范
|
||||||
4. **unstructured / pypdf** (成熟的 PDF 库) - PDF 专用
|
4. **python-docx / python-pptx / pandas** (成熟的 Python 库) - 输出最详细
|
||||||
5. **XML 原生解析** (备选方案) - 无需依赖
|
5. **unstructured / pypdf** (成熟的 PDF 库) - PDF 专用
|
||||||
|
6. **XML 原生解析** (备选方案) - 无需依赖
|
||||||
|
|
||||||
### 特性
|
### 特性
|
||||||
|
|
||||||
- 支持 DOCX、PPTX、XLSX 和 PDF 格式
|
- 支持 DOCX、PPTX、XLSX 和 PDF 格式
|
||||||
- 自动检测文件类型和有效性
|
- 自动检测文件类型和有效性
|
||||||
- 保留文本格式(粗体、斜体、下划线)
|
- 保留文本格式(粗体、斜体、下划线)
|
||||||
|
- Docling 作为第一优先解析器,单一依赖即可覆盖全部格式并自动调用 OCR
|
||||||
- 提取表格并转换为 Markdown 格式
|
- 提取表格并转换为 Markdown 格式
|
||||||
- 提取列表并保留层级结构
|
- 提取列表并保留层级结构
|
||||||
- 多种输出模式(字数、行数、标题、搜索等)
|
- 多种输出模式(字数、行数、标题、搜索等)
|
||||||
@@ -27,11 +29,11 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
scripts/
|
scripts/
|
||||||
├── common.py # 公共函数和常量
|
├── common.py # 公共函数和常量
|
||||||
├── docx.py # DOCX 文件解析
|
├── docx_parser.py # DOCX 文件解析
|
||||||
├── pptx.py # PPTX 文件解析
|
├── pptx_parser.py # PPTX 文件解析
|
||||||
├── xlsx.py # XLSX 文件解析
|
├── xlsx_parser.py # XLSX 文件解析
|
||||||
├── pdf.py # PDF 文件解析
|
├── pdf_parser.py # PDF 文件解析
|
||||||
├── parser.py # 命令行入口
|
├── parser.py # 命令行入口
|
||||||
└── README.md # 本文档
|
└── README.md # 本文档
|
||||||
```
|
```
|
||||||
@@ -45,6 +47,20 @@ scripts/
|
|||||||
uv run parser.py file.docx
|
uv run parser.py file.docx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 使用 Docling(推荐)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 通用解析方案,覆盖 DOCX/PPTX/XLSX/PDF
|
||||||
|
uv run --with docling parser.py file.docx
|
||||||
|
uv run --with docling parser.py file.pptx
|
||||||
|
uv run --with docling parser.py file.xlsx
|
||||||
|
uv run --with docling parser.py file.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
- Docling 是当前的默认第一优先级解析器,单一依赖即可获得统一输出。
|
||||||
|
- 首次运行会自动下载 OCR/视觉模型到 `uv` 缓存目录,需保持网络连通。
|
||||||
|
- 如果只需要 Docling,可无需安装其他解析依赖,脚本会在 Docling 失败时再回退至其他方案。
|
||||||
|
|
||||||
### 使用 pypandoc-binary(DOCX)
|
### 使用 pypandoc-binary(DOCX)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -92,7 +108,7 @@ pip install pypdf
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装所有解析库
|
# 安装所有解析库
|
||||||
uv run --with pypandoc-binary --with markitdown --with python-docx --with python-pptx --with pandas --with tabulate --with unstructured --with pypdf parser.py file.pdf
|
uv run --with docling --with pypandoc-binary --with markitdown --with python-docx --with python-pptx --with pandas --with tabulate --with unstructured --with pypdf parser.py file.pdf
|
||||||
```
|
```
|
||||||
|
|
||||||
## 命令行用法
|
## 命令行用法
|
||||||
@@ -126,6 +142,10 @@ uv run parser.py <file_path> [options]
|
|||||||
### 1. 输出完整 Markdown 内容
|
### 1. 输出完整 Markdown 内容
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# 推荐:Docling 自动解析
|
||||||
|
uv run --with docling parser.py report.docx
|
||||||
|
uv run --with docling parser.py report.pdf
|
||||||
|
|
||||||
# 使用最佳可用解析器 (DOCX/PPTX/XLSX)
|
# 使用最佳可用解析器 (DOCX/PPTX/XLSX)
|
||||||
uv run parser.py report.docx
|
uv run parser.py report.docx
|
||||||
|
|
||||||
@@ -209,38 +229,49 @@ uv run --with "markitdown[pdf]" parser.py report.pdf -s "重要内容" -n 2
|
|||||||
|
|
||||||
DOCX 文件会按以下优先级依次尝试解析:
|
DOCX 文件会按以下优先级依次尝试解析:
|
||||||
|
|
||||||
1. pypandoc-binary
|
1. Docling
|
||||||
2. MarkItDown
|
2. pypandoc-binary
|
||||||
3. python-docx
|
3. MarkItDown
|
||||||
4. XML 原生
|
4. python-docx
|
||||||
|
5. XML 原生
|
||||||
|
|
||||||
| 解析器 | 优点 | 缺点 | 适用场景 |
|
| 解析器 | 优点 | 缺点 | 适用场景 |
|
||||||
|---------|------|--------|---------|
|
|---------|------|--------|---------|
|
||||||
| **pypandoc-binary** | • 自带 Pandoc,可直接使用<br>• 输出 Markdown 结构整洁<br>• 错误信息清晰易排查 | • 仅适用于 DOCX<br>• 依赖包体积较大 | • 需要标准化 Markdown 输出<br>• 首选解析路径 |
|
| **Docling** | • 单一依赖覆盖所有 Office/PDF 格式<br>• 自动带 OCR,复杂文档召回率高<br>• 输出 Markdown 结构稳定 | • 首次运行需下载较大的模型<br>• 运行时内存占用相对更高 | • 需要“一键完成”解析<br>• 需要 OCR/多模态支持 |
|
||||||
|
| **pypandoc-binary** | • 自带 Pandoc,可直接使用<br>• 输出 Markdown 结构整洁<br>• 错误信息清晰易排查 | • 仅适用于 DOCX<br>• 依赖包体积较大 | • 需要标准化 Markdown 输出<br>• Docling 不可用时的首选 |
|
||||||
| **MarkItDown** | • 格式规范<br>• 微软官方支持<br>• 兼容性好 | • 需要安装<br>• 输出较简洁 | • 需要标准格式输出<br>• 自动化文档处理 |
|
| **MarkItDown** | • 格式规范<br>• 微软官方支持<br>• 兼容性好 | • 需要安装<br>• 输出较简洁 | • 需要标准格式输出<br>• 自动化文档处理 |
|
||||||
| **python-docx** | • 输出最详细<br>• 保留完整结构<br>• 支持复杂样式 | • 需要安装<br>• 可能包含多余空行 | • 需要精确控制输出<br>• 分析文档结构 |
|
| **python-docx** | • 输出最详细<br>• 保留完整结构<br>• 支持复杂样式 | • 需要安装<br>• 可能包含多余空行 | • 需要精确控制输出<br>• 分析文档结构 |
|
||||||
| **XML 原生** | • 无需依赖<br>• 运行速度快<br>• 输出原始内容 | • 格式可能不统一<br>• 样式处理有限 | • 依赖不可用时<br>• 快速提取内容 |
|
| **XML 原生** | • 无需依赖<br>• 运行速度快<br>• 输出原始内容 | • 格式可能不统一<br>• 样式处理有限 | • 依赖不可用时<br>• 快速提取内容 |
|
||||||
|
|
||||||
### PPTX 解析器
|
### PPTX 解析器
|
||||||
|
|
||||||
|
PPTX 文件会按以下优先级依次尝试解析:Docling → MarkItDown → python-pptx → XML 原生。
|
||||||
|
|
||||||
| 解析器 | 优点 | 缺点 | 适用场景 |
|
| 解析器 | 优点 | 缺点 | 适用场景 |
|
||||||
|---------|------|--------|---------|
|
|---------|------|--------|---------|
|
||||||
|
| **Docling** | • 解析幻灯片文本、表格与图片 OCR<br>• 自动生成统一 Markdown,包含分页分隔符 | • 需要下载模型<br>• 细节控制少 | • 需要一次性转换全部幻灯片<br>• 有图片或扫描件的 PPTX |
|
||||||
| **MarkItDown** | • 格式规范<br>• 自动添加 Slide 分隔<br>• 输出简洁 | • 需要安装<br>• 详细度较低 | • 快速预览幻灯片<br>• 提取主要内容 |
|
| **MarkItDown** | • 格式规范<br>• 自动添加 Slide 分隔<br>• 输出简洁 | • 需要安装<br>• 详细度较低 | • 快速预览幻灯片<br>• 提取主要内容 |
|
||||||
| **python-pptx** | • 输出最详细<br>• 保留完整结构<br>• 支持层级列表 | • 需要安装<br>• 依赖私有 API | • 需要完整内容<br>• 分析演示结构 |
|
| **python-pptx** | • 输出最详细<br>• 保留完整结构<br>• 支持层级列表 | • 需要安装<br>• 依赖私有 API | • 需要完整内容<br>• 分析演示结构 |
|
||||||
| **XML 原生** | • 无需依赖<br>• 结构化输出<br>• 运行速度快 | • 格式可能不统一<br>• 幻灯片分组简单 | • 依赖不可用时<br>• 结构化提取 |
|
| **XML 原生** | • 无需依赖<br>• 结构化输出<br>• 运行速度快 | • 格式可能不统一<br>• 幻灯片分组简单 | • 依赖不可用时<br>• 结构化提取 |
|
||||||
|
|
||||||
### XLSX 解析器
|
### XLSX 解析器
|
||||||
|
|
||||||
|
XLSX 文件会按以下优先级依次尝试解析:Docling → MarkItDown → pandas → XML 原生。
|
||||||
|
|
||||||
| 解析器 | 优点 | 缺点 | 适用场景 |
|
| 解析器 | 优点 | 缺点 | 适用场景 |
|
||||||
|---------|------|--------|---------|
|
|---------|------|--------|---------|
|
||||||
|
| **Docling** | • 单次遍历导出全部工作表为 Markdown<br>• 自动处理合并单元格/图像 OCR | • 需要下载模型<br>• 对极大体积表可能较慢 | • 快速完成全表转 Markdown<br>• 含扫描图片的表格 |
|
||||||
| **MarkItDown** | • 格式规范<br>• 支持多工作表<br>• 输出简洁 | • 需要安装<br>• 详细度较低 | • 快速预览表格<br>• 提取主要内容 |
|
| **MarkItDown** | • 格式规范<br>• 支持多工作表<br>• 输出简洁 | • 需要安装<br>• 详细度较低 | • 快速预览表格<br>• 提取主要内容 |
|
||||||
| **pandas** | • 功能强大<br>• 支持复杂表格<br>• 数据处理灵活 | • 需要安装<br>• 依赖较多 | • 数据分析<br>• 复杂表格处理 |
|
| **pandas** | • 功能强大<br>• 支持复杂表格<br>• 数据处理灵活 | • 需要安装<br>• 依赖较多 | • 数据分析<br>• 复杂表格处理 |
|
||||||
| **XML 原生** | • 无需依赖<br>• 运行速度快<br>• 支持所有单元格类型 | • 格式可能不统一<br>• 无数据处理能力 | • 依赖不可用时<br>• 快速提取内容 |
|
| **XML 原生** | • 无需依赖<br>• 运行速度快<br>• 支持所有单元格类型 | • 格式可能不统一<br>• 无数据处理能力 | • 依赖不可用时<br>• 快速提取内容 |
|
||||||
|
|
||||||
### PDF 解析器
|
### PDF 解析器
|
||||||
|
|
||||||
|
PDF 文件会按以下优先级依次尝试解析:Docling → MarkItDown → unstructured → pypdf。
|
||||||
|
|
||||||
| 解析器 | 优点 | 缺点 | 适用场景 |
|
| 解析器 | 优点 | 缺点 | 适用场景 |
|
||||||
|---------|------|--------|---------|
|
|---------|------|--------|---------|
|
||||||
|
| **Docling** | • 内置 RapidOCR,可处理扫描版 PDF<br>• 输出结构化 Markdown,包含表格/图片占位 | • 模型下载体积大<br>• OCR 耗时较长 | • 需要 OCR、表格/图片识别<br>• 多语言 PDF |
|
||||||
| **MarkItDown** | • 格式规范<br>• 微软官方支持<br>• 兼容性好 | • 需要安装 `markitdown[pdf]`<br>• 输出较简洁 | • 需要标准格式输出<br>• 自动化文档处理 |
|
| **MarkItDown** | • 格式规范<br>• 微软官方支持<br>• 兼容性好 | • 需要安装 `markitdown[pdf]`<br>• 输出较简洁 | • 需要标准格式输出<br>• 自动化文档处理 |
|
||||||
| **unstructured** | • 功能强大<br>• 支持表格提取<br>• 文本组织性好 | • 需要安装<br>• 可能包含页码标记 | • 需要完整内容<br>• 分析文档结构 |
|
| **unstructured** | • 功能强大<br>• 支持表格提取<br>• 文本组织性好 | • 需要安装<br>• 可能包含页码标记 | • 需要完整内容<br>• 分析文档结构 |
|
||||||
| **pypdf** | • 轻量级<br>• 速度快<br>• 安装简单 | • 需要安装<br>• 功能相对简单 | • 快速提取内容<br>• 简单文本提取 |
|
| **pypdf** | • 轻量级<br>• 速度快<br>• 安装简单 | • 需要安装<br>• 功能相对简单 | • 快速提取内容<br>• 简单文本提取 |
|
||||||
@@ -500,6 +531,8 @@ A: 大文件建议使用 XML 原生解析(最快),或在脚本外部处理
|
|||||||
|
|
||||||
基于测试文件的参考数据:
|
基于测试文件的参考数据:
|
||||||
|
|
||||||
|
> Docling 作为统一入口时,整体性能受 OCR/模型下载影响:首次运行略慢,缓存后与 MarkItDown 同量级,但在 PDF 场景中由于 OCR 会稍慢一些。
|
||||||
|
|
||||||
### DOCX (test.docx)
|
### DOCX (test.docx)
|
||||||
|
|
||||||
| 解析器 | 字符数 | 行数 | 相对速度 |
|
| 解析器 | 字符数 | 行数 | 相对速度 |
|
||||||
@@ -553,6 +586,7 @@ A: 大文件建议使用 XML 原生解析(最快),或在脚本外部处理
|
|||||||
|
|
||||||
### 最新版本
|
### 最新版本
|
||||||
|
|
||||||
|
- 新增 Docling 解析路径,统一处理 DOCX/PPTX/XLSX/PDF,并自动具备 OCR 能力
|
||||||
- DOCX 解析新增 pypandoc-binary 方案并设置为最高优先级
|
- DOCX 解析新增 pypandoc-binary 方案并设置为最高优先级
|
||||||
- 将单体脚本拆分为模块化结构(common.py, docx.py, pptx.py, xlsx.py, parser.py)
|
- 将单体脚本拆分为模块化结构(common.py, docx.py, pptx.py, xlsx.py, parser.py)
|
||||||
- 添加 XLSX 文件支持
|
- 添加 XLSX 文件支持
|
||||||
|
|||||||
@@ -27,6 +27,24 @@ def parse_with_markitdown(
|
|||||||
return None, f"MarkItDown 解析失败: {str(e)}"
|
return None, f"MarkItDown 解析失败: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
|
def parse_with_docling(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""使用 docling 库解析文件"""
|
||||||
|
try:
|
||||||
|
from docling.document_converter import DocumentConverter
|
||||||
|
except ImportError:
|
||||||
|
return None, "docling 库未安装"
|
||||||
|
|
||||||
|
try:
|
||||||
|
converter = DocumentConverter()
|
||||||
|
result = converter.convert(file_path)
|
||||||
|
markdown_content = result.document.export_to_markdown()
|
||||||
|
if not markdown_content.strip():
|
||||||
|
return None, "文档为空"
|
||||||
|
return markdown_content, None
|
||||||
|
except Exception as e:
|
||||||
|
return None, f"docling 解析失败: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
def build_markdown_table(rows_data: List[List[str]]) -> str:
|
def build_markdown_table(rows_data: List[List[str]]) -> str:
|
||||||
"""将二维列表转换为 Markdown 表格格式"""
|
"""将二维列表转换为 Markdown 表格格式"""
|
||||||
if not rows_data or not rows_data[0]:
|
if not rows_data or not rows_data[0]:
|
||||||
|
|||||||
@@ -5,7 +5,17 @@ import xml.etree.ElementTree as ET
|
|||||||
import zipfile
|
import zipfile
|
||||||
from typing import Any, List, Optional, Tuple
|
from typing import Any, List, Optional, Tuple
|
||||||
|
|
||||||
from common import build_markdown_table, parse_with_markitdown, safe_open_zip
|
from common import (
|
||||||
|
build_markdown_table,
|
||||||
|
parse_with_docling,
|
||||||
|
parse_with_markitdown,
|
||||||
|
safe_open_zip,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_docx_with_docling(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""使用 docling 库解析 DOCX 文件"""
|
||||||
|
return parse_with_docling(file_path)
|
||||||
|
|
||||||
|
|
||||||
def parse_docx_with_pypandoc(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
def parse_docx_with_pypandoc(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ def main() -> None:
|
|||||||
|
|
||||||
if file_type == "docx":
|
if file_type == "docx":
|
||||||
parsers = [
|
parsers = [
|
||||||
|
("docling", docx_parser.parse_docx_with_docling),
|
||||||
("pypandoc-binary", docx_parser.parse_docx_with_pypandoc),
|
("pypandoc-binary", docx_parser.parse_docx_with_pypandoc),
|
||||||
("MarkItDown", docx_parser.parse_docx_with_markitdown),
|
("MarkItDown", docx_parser.parse_docx_with_markitdown),
|
||||||
("python-docx", docx_parser.parse_docx_with_python_docx),
|
("python-docx", docx_parser.parse_docx_with_python_docx),
|
||||||
@@ -71,18 +72,21 @@ def main() -> None:
|
|||||||
]
|
]
|
||||||
elif file_type == "pptx":
|
elif file_type == "pptx":
|
||||||
parsers = [
|
parsers = [
|
||||||
|
("docling", pptx_parser.parse_pptx_with_docling),
|
||||||
("MarkItDown", pptx_parser.parse_pptx_with_markitdown),
|
("MarkItDown", pptx_parser.parse_pptx_with_markitdown),
|
||||||
("python-pptx", pptx_parser.parse_pptx_with_python_pptx),
|
("python-pptx", pptx_parser.parse_pptx_with_python_pptx),
|
||||||
("XML 原生解析", pptx_parser.parse_pptx_with_xml),
|
("XML 原生解析", pptx_parser.parse_pptx_with_xml),
|
||||||
]
|
]
|
||||||
elif file_type == "xlsx":
|
elif file_type == "xlsx":
|
||||||
parsers = [
|
parsers = [
|
||||||
|
("docling", xlsx_parser.parse_xlsx_with_docling),
|
||||||
("MarkItDown", xlsx_parser.parse_xlsx_with_markitdown),
|
("MarkItDown", xlsx_parser.parse_xlsx_with_markitdown),
|
||||||
("pandas", xlsx_parser.parse_xlsx_with_pandas),
|
("pandas", xlsx_parser.parse_xlsx_with_pandas),
|
||||||
("XML 原生解析", xlsx_parser.parse_xlsx_with_xml),
|
("XML 原生解析", xlsx_parser.parse_xlsx_with_xml),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
parsers = [
|
parsers = [
|
||||||
|
("docling", pdf_parser.parse_pdf_with_docling),
|
||||||
("MarkItDown", pdf_parser.parse_pdf_with_markitdown),
|
("MarkItDown", pdf_parser.parse_pdf_with_markitdown),
|
||||||
("unstructured", pdf_parser.parse_pdf_with_unstructured),
|
("unstructured", pdf_parser.parse_pdf_with_unstructured),
|
||||||
("pypdf", pdf_parser.parse_pdf_with_pypdf),
|
("pypdf", pdf_parser.parse_pdf_with_pypdf),
|
||||||
|
|||||||
@@ -3,7 +3,12 @@
|
|||||||
|
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
from common import parse_with_markitdown
|
from common import parse_with_docling, parse_with_markitdown
|
||||||
|
|
||||||
|
|
||||||
|
def parse_pdf_with_docling(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""使用 docling 库解析 PDF 文件"""
|
||||||
|
return parse_with_docling(file_path)
|
||||||
|
|
||||||
|
|
||||||
def parse_pdf_with_markitdown(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
def parse_pdf_with_markitdown(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
|||||||
@@ -6,7 +6,17 @@ import xml.etree.ElementTree as ET
|
|||||||
import zipfile
|
import zipfile
|
||||||
from typing import Any, List, Optional, Tuple
|
from typing import Any, List, Optional, Tuple
|
||||||
|
|
||||||
from common import build_markdown_table, flush_list_stack, parse_with_markitdown
|
from common import (
|
||||||
|
build_markdown_table,
|
||||||
|
flush_list_stack,
|
||||||
|
parse_with_docling,
|
||||||
|
parse_with_markitdown,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_pptx_with_docling(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""使用 docling 库解析 PPTX 文件"""
|
||||||
|
return parse_with_docling(file_path)
|
||||||
|
|
||||||
|
|
||||||
def parse_pptx_with_markitdown(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
def parse_pptx_with_markitdown(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ import xml.etree.ElementTree as ET
|
|||||||
import zipfile
|
import zipfile
|
||||||
from typing import List, Optional, Tuple
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
from common import parse_with_markitdown
|
from common import parse_with_docling, parse_with_markitdown
|
||||||
|
|
||||||
|
|
||||||
|
def parse_xlsx_with_docling(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
"""使用 docling 库解析 XLSX 文件"""
|
||||||
|
return parse_with_docling(file_path)
|
||||||
|
|
||||||
|
|
||||||
def parse_xlsx_with_markitdown(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
def parse_xlsx_with_markitdown(file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||||
|
|||||||
Reference in New Issue
Block a user