task-parser / src /excel_exporter.py
Artem Nikolaev
PDF Task Parser with FastAPI and Google integration
ca8ebf7
import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from datetime import datetime
import os
from io import BytesIO
class ExcelExporter:
def __init__(self, filename=None):
self.filename = filename
self.base_filename = "output/tasks.xlsx"
if filename and os.path.exists(filename):
from openpyxl import load_workbook
self.wb = load_workbook(filename)
else:
self.wb = Workbook()
if "Sheet" in self.wb.sheetnames:
self.wb.remove(self.wb["Sheet"])
def add_sheet(self, df, sheet_name: str):
if sheet_name in self.wb.sheetnames:
self.wb.remove(self.wb[sheet_name])
ws = self.wb.create_sheet(title=sheet_name)
headers = list(df.columns)
for col_idx, header in enumerate(headers, 1):
ws.cell(row=1, column=col_idx, value=header)
for row_idx, row in df.iterrows():
for col_idx, value in enumerate(row, 1):
cell = ws.cell(row=row_idx + 2, column=col_idx, value=value)
if isinstance(value, (datetime, pd.Timestamp)):
cell.number_format = 'DD.MM.YYYY'
self._apply_formatting(ws, len(df.columns), len(df))
def _apply_formatting(self, ws, num_columns, num_rows):
header_font = Font(name='Arial', size=12, bold=True, color='FFFFFF')
header_fill = PatternFill(start_color='366092', end_color='366092', fill_type='solid')
header_alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
cell_alignment = Alignment(horizontal='left', vertical='center', wrap_text=True)
date_alignment = Alignment(horizontal='center', vertical='center')
border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)
for col in range(1, num_columns + 1):
cell = ws.cell(row=1, column=col)
cell.font = header_font
cell.fill = header_fill
cell.alignment = header_alignment
cell.border = border
for row in range(2, num_rows + 2):
for col in range(1, num_columns + 1):
cell = ws.cell(row=row, column=col)
cell.border = border
col_letter = ws.cell(row=1, column=col).value
if col_letter in ['Срок', 'Дата']:
cell.alignment = date_alignment
else:
cell.alignment = cell_alignment
for col in ws.columns:
max_length = 0
col_letter = col[0].column_letter
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = min(max_length + 2, 80)
ws.column_dimensions[col_letter].width = adjusted_width
ws.freeze_panes = 'A2'
def save(self, filename=None):
if filename is None:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"output/tasks_{timestamp}.xlsx"
os.makedirs(os.path.dirname(filename), exist_ok=True)
for sheet in self.wb.worksheets:
for row in sheet.iter_rows():
for cell in row:
if cell.value is not None:
_ = cell.value
self.wb.save(filename)
print(f"✅ Excel файл сохранен: {filename}")
return filename
def save_to_buffer(self, buffer):
self.wb.save(buffer)
return buffer