# PDF Notes Extractor (Tableta)
Librería Python para extraer tablas desde notas en PDFs de estados financieros.
## 🎯 Versión 0.2.0 - Mejorada con lógica del Playground
Esta versión integra la lógica mejorada y probada del playground, proporcionando:
- **Detección más precisa de notas** mediante análisis de contexto
- **Extracción de tablas más confiable** usando pdfplumber como motor por defecto
- **Validación robusta** que elimina falsos positivos (reduce ~73% de errores)
- **Mejor identificación de subtítulos** vs tabla de contenidos
## 📋 Características
- ✅ Extrae tablas de notas específicas en PDFs
- ✅ Soporta múltiples motores de extracción (PDFPlumber, Camelot, Tabula)
- ✅ **PDFPlumber como motor por defecto** (más preciso y confiable)
- ✅ Exporta a Excel con múltiples hojas
- ✅ Exporta a CSV individuales
- ✅ Interfaz de línea de comandos (CLI)
- ✅ API programática para usar en scripts
- ✅ Detección automática de rangos de páginas por nota
- ✅ Limpieza y normalización de datos
- ✅ Validación estricta para evitar falsos positivos
## 🚀 Instalación
### Instalación básica (solo pdfplumber)
```bash
pip install tableta
```
### Con soporte para Camelot (opcional)
```bash
pip install tableta[camelot]
```
### Con soporte para Tabula (opcional)
```bash
pip install tableta[tabula]
```
### Con todos los extractores (opcional)
```bash
pip install tableta[all]
```
**Nota:** La instalación básica incluye pdfplumber, que es el motor recomendado y por defecto.
### Para desarrollo
```bash
git clone https://github.com/diegonov1/tableta.git
cd tableta
pip install -e ".[dev]"
```
## 💻 Uso
### Línea de comandos (CLI)
#### Extraer notas específicas a Excel
```bash
tableta documento.pdf --notas 1 6 12 --excel resultado.xlsx
```
#### Extraer todas las notas
```bash
tableta documento.pdf --notas all --excel resultado.xlsx
```
#### Extraer rango de notas
```bash
tableta documento.pdf --notas 1-5 --excel resultado.xlsx
```
#### Exportar a CSV
```bash
tableta documento.pdf --notas 1 6 --csv-dir ./tablas
```
#### Usar motor alternativo (Camelot o Tabula)
```bash
# Usar Camelot
tableta documento.pdf --notas 1 6 --excel resultado.xlsx --engine camelot
# Usar Tabula
tableta documento.pdf --notas 1 6 --excel resultado.xlsx --engine tabula
```
**Nota:** El motor por defecto es pdfplumber (no requiere especificar --engine)
#### Con información detallada
```bash
tableta documento.pdf --notas 1 6 --excel resultado.xlsx --verbose
```
#### Guardar metadatos
```bash
tableta documento.pdf --notas 1 6 --excel resultado.xlsx --metadata meta.json
```
### API Programática
```python
from pathlib import Path
from pdf_notes_extractor import extract_tables_from_notes
from pdf_notes_extractor.output import OutputManager
# Extraer tablas de las notas 1, 6 y 12
pdf_path = Path("estados_financieros.pdf")
note_numbers = {1, 6, 12}
results = extract_tables_from_notes(
pdf_path=pdf_path,
note_numbers=note_numbers,
engine='pdfplumber', # Por defecto, puede omitirse
verbose=True
)
# Procesar resultados
for note_num, result in results.items():
print(f"Nota {note_num}:")
print(f" - Tablas encontradas: {len(result.tables)}")
print(f" - Páginas: {result.pages_processed}")
print(f" - Tiempo: {result.extraction_time:.2f}s")
# Acceder a las tablas (pandas DataFrames)
for i, df in enumerate(result.tables, 1):
print(f" - Tabla {i}: {df.shape[0]} filas x {df.shape[1]} columnas")
# Guardar a Excel
output_manager = OutputManager()
output_manager.save_to_excel(results, Path("resultado.xlsx"))
```
### Uso avanzado
```python
from pdf_notes_extractor import extract_tables_from_notes
from pdf_notes_extractor.analyzer import find_note_locations, analyze_pdf_structure
from pdf_notes_extractor.extractors import CamelotExtractor
from pathlib import Path
pdf_path = Path("documento.pdf")
# Analizar estructura del PDF
pdf_info = analyze_pdf_structure(pdf_path)
print(f"Total páginas: {pdf_info['total_pages']}")
print(f"Tiene tablas: {pdf_info['has_tables']}")
# Encontrar todas las notas disponibles
locations = find_note_locations(pdf_path)
print(f"Notas encontradas: {sorted(locations.keys())}")
for note_num, location in locations.items():
print(f"Nota {note_num}: páginas {location.pages_range()}")
# Usar extractor específico
extractor = CamelotExtractor()
tables = extractor.extract(pdf_path, pages="1-5")
```
## 📖 Estructura del Proyecto
```
tableta/
├── pdf_notes_extractor/
│ ├── __init__.py # API pública
│ ├── cli.py # Interfaz de línea de comandos
│ ├── core.py # Función principal de extracción
│ ├── models.py # Modelos de datos
│ ├── patterns.py # Patrones regex para detectar notas
│ ├── analyzer.py # Análisis de PDFs
│ ├── extractors.py # Extractores (Camelot, Tabula)
│ └── output.py # Exportación de resultados
├── tests/ # Tests unitarios
├── examples/ # Ejemplos de uso
├── pyproject.toml # Configuración del proyecto
├── setup.py # Setup alternativo
├── README.md # Este archivo
├── LICENSE # Licencia MIT
└── .gitignore # Archivos a ignorar
```
## 🔧 Requisitos
- Python >= 3.8
- pandas >= 1.3.0
- pdfplumber >= 0.7.0
- openpyxl >= 3.0.0
### Opcionales
- camelot-py[cv] >= 0.11.0 (para mejor extracción de tablas)
- tabula-py >= 2.5.0 (motor alternativo)
## 📝 Formato de Salida
### Excel
El archivo Excel generado contiene:
- **Hoja "Resumen"**: Información general de todas las notas procesadas
- **Hojas individuales**: Una hoja por cada tabla encontrada (formato: `Nota_X_Tabla_Y`)
### CSV
Genera archivos individuales:
- `_resumen.csv`: Resumen de la extracción
- `Nota_X_tabla_Y.csv`: Cada tabla en su propio archivo
- `Nota_X_sin_tablas.txt`: Marcador para notas sin tablas
### JSON (Metadatos)
```json
{
"extraction_date": "2025-10-10T01:43:11",
"notes_processed": [1, 6, 12],
"total_tables_found": 5,
"details": {
"1": {
"pages": "10-12",
"tables_count": 2,
"extraction_time": 1.23,
"warnings": [],
"table_shapes": [[10, 5], [15, 4]]
}
}
}
```
## 🤝 Contribuir
Las contribuciones son bienvenidas. Por favor:
1. Fork el proyecto
2. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
3. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
4. Push a la rama (`git push origin feature/AmazingFeature`)
5. Abre un Pull Request
## 📄 Licencia
Este proyecto está bajo la Licencia MIT. Ver el archivo `LICENSE` para más detalles.
## 🐛 Reportar Problemas
Si encuentras algún problema, por favor abre un issue en GitHub incluyendo:
- Descripción del problema
- Pasos para reproducirlo
- Versión de Python y librerías
- Ejemplo de PDF (si es posible)
## 🙏 Agradecimientos
Esta librería utiliza las siguientes herramientas:
- [pdfplumber](https://github.com/jsvine/pdfplumber) - Extracción de texto y tablas
- [Camelot](https://github.com/camelot-dev/camelot) - Extracción avanzada de tablas
- [Tabula](https://github.com/tabulapdf/tabula-py) - Motor alternativo de extracción
- [pandas](https://pandas.pydata.org/) - Manipulación de datos
## 📊 Estado del Proyecto
- ✅ Versión Beta (0.1.0)
- 🚧 En desarrollo activo
- 📝 Documentación en progreso
## 🗺️ Roadmap
- [ ] Soporte para más idiomas en detección de notas
- [ ] Interfaz gráfica (GUI)
- [ ] Exportación a más formatos (JSON, SQLite)
- [ ] Mejor detección de tablas complejas
- [ ] Caché de resultados
- [ ] Procesamiento en paralelo de múltiples notas
Raw data
{
"_id": null,
"home_page": null,
"name": "tableta",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "pdf, table-extraction, financial, notes, estados-financieros",
"author": null,
"author_email": "Diego Jim\u00e9nez <diego.jimenez.g@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/73/72/d2c3ee83a3426307cb284669b8c3deac917c19185e12a8a6299e93d3e0ff/tableta-0.2.1.tar.gz",
"platform": null,
"description": "# PDF Notes Extractor (Tableta)\n\nLibrer\u00eda Python para extraer tablas desde notas en PDFs de estados financieros.\n\n## \ud83c\udfaf Versi\u00f3n 0.2.0 - Mejorada con l\u00f3gica del Playground\n\nEsta versi\u00f3n integra la l\u00f3gica mejorada y probada del playground, proporcionando:\n- **Detecci\u00f3n m\u00e1s precisa de notas** mediante an\u00e1lisis de contexto\n- **Extracci\u00f3n de tablas m\u00e1s confiable** usando pdfplumber como motor por defecto\n- **Validaci\u00f3n robusta** que elimina falsos positivos (reduce ~73% de errores)\n- **Mejor identificaci\u00f3n de subt\u00edtulos** vs tabla de contenidos\n\n## \ud83d\udccb Caracter\u00edsticas\n\n- \u2705 Extrae tablas de notas espec\u00edficas en PDFs\n- \u2705 Soporta m\u00faltiples motores de extracci\u00f3n (PDFPlumber, Camelot, Tabula)\n- \u2705 **PDFPlumber como motor por defecto** (m\u00e1s preciso y confiable)\n- \u2705 Exporta a Excel con m\u00faltiples hojas\n- \u2705 Exporta a CSV individuales\n- \u2705 Interfaz de l\u00ednea de comandos (CLI)\n- \u2705 API program\u00e1tica para usar en scripts\n- \u2705 Detecci\u00f3n autom\u00e1tica de rangos de p\u00e1ginas por nota\n- \u2705 Limpieza y normalizaci\u00f3n de datos\n- \u2705 Validaci\u00f3n estricta para evitar falsos positivos\n\n## \ud83d\ude80 Instalaci\u00f3n\n\n### Instalaci\u00f3n b\u00e1sica (solo pdfplumber)\n\n```bash\npip install tableta\n```\n\n### Con soporte para Camelot (opcional)\n\n```bash\npip install tableta[camelot]\n```\n\n### Con soporte para Tabula (opcional)\n\n```bash\npip install tableta[tabula]\n```\n\n### Con todos los extractores (opcional)\n\n```bash\npip install tableta[all]\n```\n\n**Nota:** La instalaci\u00f3n b\u00e1sica incluye pdfplumber, que es el motor recomendado y por defecto.\n\n### Para desarrollo\n\n```bash\ngit clone https://github.com/diegonov1/tableta.git\ncd tableta\npip install -e \".[dev]\"\n```\n\n## \ud83d\udcbb Uso\n\n### L\u00ednea de comandos (CLI)\n\n#### Extraer notas espec\u00edficas a Excel\n\n```bash\ntableta documento.pdf --notas 1 6 12 --excel resultado.xlsx\n```\n\n#### Extraer todas las notas\n\n```bash\ntableta documento.pdf --notas all --excel resultado.xlsx\n```\n\n#### Extraer rango de notas\n\n```bash\ntableta documento.pdf --notas 1-5 --excel resultado.xlsx\n```\n\n#### Exportar a CSV\n\n```bash\ntableta documento.pdf --notas 1 6 --csv-dir ./tablas\n```\n\n#### Usar motor alternativo (Camelot o Tabula)\n\n```bash\n# Usar Camelot\ntableta documento.pdf --notas 1 6 --excel resultado.xlsx --engine camelot\n\n# Usar Tabula\ntableta documento.pdf --notas 1 6 --excel resultado.xlsx --engine tabula\n```\n\n**Nota:** El motor por defecto es pdfplumber (no requiere especificar --engine)\n\n#### Con informaci\u00f3n detallada\n\n```bash\ntableta documento.pdf --notas 1 6 --excel resultado.xlsx --verbose\n```\n\n#### Guardar metadatos\n\n```bash\ntableta documento.pdf --notas 1 6 --excel resultado.xlsx --metadata meta.json\n```\n\n### API Program\u00e1tica\n\n```python\nfrom pathlib import Path\nfrom pdf_notes_extractor import extract_tables_from_notes\nfrom pdf_notes_extractor.output import OutputManager\n\n# Extraer tablas de las notas 1, 6 y 12\npdf_path = Path(\"estados_financieros.pdf\")\nnote_numbers = {1, 6, 12}\n\nresults = extract_tables_from_notes(\n pdf_path=pdf_path,\n note_numbers=note_numbers,\n engine='pdfplumber', # Por defecto, puede omitirse\n verbose=True\n)\n\n# Procesar resultados\nfor note_num, result in results.items():\n print(f\"Nota {note_num}:\")\n print(f\" - Tablas encontradas: {len(result.tables)}\")\n print(f\" - P\u00e1ginas: {result.pages_processed}\")\n print(f\" - Tiempo: {result.extraction_time:.2f}s\")\n \n # Acceder a las tablas (pandas DataFrames)\n for i, df in enumerate(result.tables, 1):\n print(f\" - Tabla {i}: {df.shape[0]} filas x {df.shape[1]} columnas\")\n\n# Guardar a Excel\noutput_manager = OutputManager()\noutput_manager.save_to_excel(results, Path(\"resultado.xlsx\"))\n```\n\n### Uso avanzado\n\n```python\nfrom pdf_notes_extractor import extract_tables_from_notes\nfrom pdf_notes_extractor.analyzer import find_note_locations, analyze_pdf_structure\nfrom pdf_notes_extractor.extractors import CamelotExtractor\nfrom pathlib import Path\n\npdf_path = Path(\"documento.pdf\")\n\n# Analizar estructura del PDF\npdf_info = analyze_pdf_structure(pdf_path)\nprint(f\"Total p\u00e1ginas: {pdf_info['total_pages']}\")\nprint(f\"Tiene tablas: {pdf_info['has_tables']}\")\n\n# Encontrar todas las notas disponibles\nlocations = find_note_locations(pdf_path)\nprint(f\"Notas encontradas: {sorted(locations.keys())}\")\n\nfor note_num, location in locations.items():\n print(f\"Nota {note_num}: p\u00e1ginas {location.pages_range()}\")\n\n# Usar extractor espec\u00edfico\nextractor = CamelotExtractor()\ntables = extractor.extract(pdf_path, pages=\"1-5\")\n```\n\n## \ud83d\udcd6 Estructura del Proyecto\n\n```\ntableta/\n\u251c\u2500\u2500 pdf_notes_extractor/\n\u2502 \u251c\u2500\u2500 __init__.py # API p\u00fablica\n\u2502 \u251c\u2500\u2500 cli.py # Interfaz de l\u00ednea de comandos\n\u2502 \u251c\u2500\u2500 core.py # Funci\u00f3n principal de extracci\u00f3n\n\u2502 \u251c\u2500\u2500 models.py # Modelos de datos\n\u2502 \u251c\u2500\u2500 patterns.py # Patrones regex para detectar notas\n\u2502 \u251c\u2500\u2500 analyzer.py # An\u00e1lisis de PDFs\n\u2502 \u251c\u2500\u2500 extractors.py # Extractores (Camelot, Tabula)\n\u2502 \u2514\u2500\u2500 output.py # Exportaci\u00f3n de resultados\n\u251c\u2500\u2500 tests/ # Tests unitarios\n\u251c\u2500\u2500 examples/ # Ejemplos de uso\n\u251c\u2500\u2500 pyproject.toml # Configuraci\u00f3n del proyecto\n\u251c\u2500\u2500 setup.py # Setup alternativo\n\u251c\u2500\u2500 README.md # Este archivo\n\u251c\u2500\u2500 LICENSE # Licencia MIT\n\u2514\u2500\u2500 .gitignore # Archivos a ignorar\n```\n\n## \ud83d\udd27 Requisitos\n\n- Python >= 3.8\n- pandas >= 1.3.0\n- pdfplumber >= 0.7.0\n- openpyxl >= 3.0.0\n\n### Opcionales\n\n- camelot-py[cv] >= 0.11.0 (para mejor extracci\u00f3n de tablas)\n- tabula-py >= 2.5.0 (motor alternativo)\n\n## \ud83d\udcdd Formato de Salida\n\n### Excel\n\nEl archivo Excel generado contiene:\n- **Hoja \"Resumen\"**: Informaci\u00f3n general de todas las notas procesadas\n- **Hojas individuales**: Una hoja por cada tabla encontrada (formato: `Nota_X_Tabla_Y`)\n\n### CSV\n\nGenera archivos individuales:\n- `_resumen.csv`: Resumen de la extracci\u00f3n\n- `Nota_X_tabla_Y.csv`: Cada tabla en su propio archivo\n- `Nota_X_sin_tablas.txt`: Marcador para notas sin tablas\n\n### JSON (Metadatos)\n\n```json\n{\n \"extraction_date\": \"2025-10-10T01:43:11\",\n \"notes_processed\": [1, 6, 12],\n \"total_tables_found\": 5,\n \"details\": {\n \"1\": {\n \"pages\": \"10-12\",\n \"tables_count\": 2,\n \"extraction_time\": 1.23,\n \"warnings\": [],\n \"table_shapes\": [[10, 5], [15, 4]]\n }\n }\n}\n```\n\n## \ud83e\udd1d Contribuir\n\nLas contribuciones son bienvenidas. Por favor:\n\n1. Fork el proyecto\n2. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)\n3. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)\n4. Push a la rama (`git push origin feature/AmazingFeature`)\n5. Abre un Pull Request\n\n## \ud83d\udcc4 Licencia\n\nEste proyecto est\u00e1 bajo la Licencia MIT. Ver el archivo `LICENSE` para m\u00e1s detalles.\n\n## \ud83d\udc1b Reportar Problemas\n\nSi encuentras alg\u00fan problema, por favor abre un issue en GitHub incluyendo:\n- Descripci\u00f3n del problema\n- Pasos para reproducirlo\n- Versi\u00f3n de Python y librer\u00edas\n- Ejemplo de PDF (si es posible)\n\n## \ud83d\ude4f Agradecimientos\n\nEsta librer\u00eda utiliza las siguientes herramientas:\n- [pdfplumber](https://github.com/jsvine/pdfplumber) - Extracci\u00f3n de texto y tablas\n- [Camelot](https://github.com/camelot-dev/camelot) - Extracci\u00f3n avanzada de tablas\n- [Tabula](https://github.com/tabulapdf/tabula-py) - Motor alternativo de extracci\u00f3n\n- [pandas](https://pandas.pydata.org/) - Manipulaci\u00f3n de datos\n\n## \ud83d\udcca Estado del Proyecto\n\n- \u2705 Versi\u00f3n Beta (0.1.0)\n- \ud83d\udea7 En desarrollo activo\n- \ud83d\udcdd Documentaci\u00f3n en progreso\n\n## \ud83d\uddfa\ufe0f Roadmap\n\n- [ ] Soporte para m\u00e1s idiomas en detecci\u00f3n de notas\n- [ ] Interfaz gr\u00e1fica (GUI)\n- [ ] Exportaci\u00f3n a m\u00e1s formatos (JSON, SQLite)\n- [ ] Mejor detecci\u00f3n de tablas complejas\n- [ ] Cach\u00e9 de resultados\n- [ ] Procesamiento en paralelo de m\u00faltiples notas\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Extractor de tablas desde notas en PDFs de estados financieros (con detecci\u00f3n mejorada)",
"version": "0.2.1",
"project_urls": {
"Bug Tracker": "https://github.com/diegonov1/tableta/issues",
"Documentation": "https://github.com/diegonov1/tableta#readme",
"Homepage": "https://github.com/diegonov1/tableta",
"Repository": "https://github.com/diegonov1/tableta"
},
"split_keywords": [
"pdf",
" table-extraction",
" financial",
" notes",
" estados-financieros"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "e329b0f9798d4dac3232cec6ad7cbbf5c43fc7ed04177c55978456f5c285b6e0",
"md5": "742850a99f003a67b6c243c842713fec",
"sha256": "f2f031f60ac2185e3864736d195567bbbf3f0fba848fa3ce71c06b52397e2ccf"
},
"downloads": -1,
"filename": "tableta-0.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "742850a99f003a67b6c243c842713fec",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 20542,
"upload_time": "2025-10-11T05:13:11",
"upload_time_iso_8601": "2025-10-11T05:13:11.286349Z",
"url": "https://files.pythonhosted.org/packages/e3/29/b0f9798d4dac3232cec6ad7cbbf5c43fc7ed04177c55978456f5c285b6e0/tableta-0.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7372d2c3ee83a3426307cb284669b8c3deac917c19185e12a8a6299e93d3e0ff",
"md5": "b0419c0ca4ef21acd8b968f7dd2159fa",
"sha256": "addcbf3b7d46a637720c2088fe244a7273589798ef15ab433ab1bf4a1c9bfc25"
},
"downloads": -1,
"filename": "tableta-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "b0419c0ca4ef21acd8b968f7dd2159fa",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 26084,
"upload_time": "2025-10-11T05:13:12",
"upload_time_iso_8601": "2025-10-11T05:13:12.683975Z",
"url": "https://files.pythonhosted.org/packages/73/72/d2c3ee83a3426307cb284669b8c3deac917c19185e12a8a6299e93d3e0ff/tableta-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-11 05:13:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "diegonov1",
"github_project": "tableta",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pandas",
"specs": [
[
">=",
"1.3.0"
]
]
},
{
"name": "pdfplumber",
"specs": [
[
">=",
"0.7.0"
]
]
},
{
"name": "openpyxl",
"specs": [
[
">=",
"3.0.0"
]
]
}
],
"lcname": "tableta"
}