Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
323 lines
8.6 KiB
Python
323 lines
8.6 KiB
Python
"""
|
|
Excel operation tools based on AWorld excel server.
|
|
Provides comprehensive Excel file manipulation capabilities.
|
|
"""
|
|
import json
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Dict, Any, List
|
|
|
|
import pandas as pd
|
|
from openpyxl import load_workbook, Workbook
|
|
from openpyxl.utils import get_column_letter
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
# Export for other modules
|
|
__all__ = [
|
|
'read_excel_data',
|
|
'write_excel_data',
|
|
'create_excel_workbook',
|
|
'create_excel_worksheet',
|
|
'apply_excel_formula',
|
|
'get_excel_metadata',
|
|
'create_excel_screenshot'
|
|
]
|
|
|
|
|
|
async def read_excel_data(
|
|
file_path: str,
|
|
sheet_name: str | None = None,
|
|
max_rows: int = 1000
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Read data from Excel file.
|
|
|
|
Args:
|
|
file_path: Path to Excel file
|
|
sheet_name: Specific sheet name (None for all sheets)
|
|
max_rows: Maximum rows to read
|
|
|
|
Returns:
|
|
Dictionary with Excel data
|
|
"""
|
|
try:
|
|
path = Path(file_path).resolve()
|
|
|
|
if not path.exists():
|
|
return {"success": False, "error": f"File not found: {file_path}"}
|
|
|
|
# Read Excel
|
|
if sheet_name:
|
|
df = pd.read_excel(path, sheet_name=sheet_name, nrows=max_rows)
|
|
data = {sheet_name: df.to_dict(orient="records")}
|
|
sheets = [sheet_name]
|
|
else:
|
|
excel_file = pd.ExcelFile(path)
|
|
data = {}
|
|
sheets = excel_file.sheet_names
|
|
for sheet in sheets:
|
|
df = pd.read_excel(path, sheet_name=sheet, nrows=max_rows)
|
|
data[sheet] = df.to_dict(orient="records")
|
|
|
|
return {
|
|
"success": True,
|
|
"file_path": str(path),
|
|
"sheets": sheets,
|
|
"data": data,
|
|
"sheet_count": len(sheets)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Failed to read Excel: {str(e)}"}
|
|
|
|
|
|
async def write_excel_data(
|
|
file_path: str,
|
|
data: Dict[str, List[Dict]],
|
|
overwrite: bool = False
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Write data to Excel file.
|
|
|
|
Args:
|
|
file_path: Path to Excel file
|
|
data: Dictionary of {sheet_name: [rows]}
|
|
overwrite: Whether to overwrite existing file
|
|
|
|
Returns:
|
|
Dictionary with operation result
|
|
"""
|
|
try:
|
|
path = Path(file_path).resolve()
|
|
|
|
if not data:
|
|
return {"success": False, "error": "Cannot write Excel file: data dictionary is empty"}
|
|
|
|
if path.exists() and not overwrite:
|
|
return {"success": False, "error": "File exists, use overwrite=True"}
|
|
# Create Excel writer
|
|
with pd.ExcelWriter(path, engine='openpyxl') as writer:
|
|
for sheet_name, rows in data.items():
|
|
df = pd.DataFrame(rows)
|
|
df.to_excel(writer, sheet_name=sheet_name, index=False)
|
|
|
|
return {
|
|
"success": True,
|
|
"file_path": str(path),
|
|
"sheets_written": len(data),
|
|
"message": f"Wrote {len(data)} sheets to Excel"
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Failed to write Excel: {str(e)}"}
|
|
|
|
|
|
async def create_excel_workbook(
|
|
file_path: str
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Create a new Excel workbook.
|
|
|
|
Args:
|
|
file_path: Path for new workbook
|
|
|
|
Returns:
|
|
Dictionary with result
|
|
"""
|
|
try:
|
|
path = Path(file_path).resolve()
|
|
|
|
if path.exists():
|
|
return {"success": False, "error": "File already exists"}
|
|
|
|
wb = Workbook()
|
|
wb.save(path)
|
|
|
|
return {
|
|
"success": True,
|
|
"file_path": str(path),
|
|
"message": "Created new workbook"
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Failed to create workbook: {str(e)}"}
|
|
|
|
|
|
async def create_excel_worksheet(
|
|
file_path: str,
|
|
sheet_name: str
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Create a new worksheet in Excel file.
|
|
|
|
Args:
|
|
file_path: Path to Excel file
|
|
sheet_name: Name for new worksheet
|
|
|
|
Returns:
|
|
Dictionary with result
|
|
"""
|
|
try:
|
|
path = Path(file_path).resolve()
|
|
|
|
if not path.exists():
|
|
return {"success": False, "error": "File not found"}
|
|
|
|
wb = load_workbook(path)
|
|
|
|
if sheet_name in wb.sheetnames:
|
|
return {"success": False, "error": f"Sheet '{sheet_name}' already exists"}
|
|
|
|
wb.create_sheet(sheet_name)
|
|
wb.save(path)
|
|
|
|
return {
|
|
"success": True,
|
|
"file_path": str(path),
|
|
"sheet_name": sheet_name,
|
|
"message": f"Created worksheet '{sheet_name}'"
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Failed to create worksheet: {str(e)}"}
|
|
|
|
|
|
async def apply_excel_formula(
|
|
file_path: str,
|
|
sheet_name: str,
|
|
cell: str,
|
|
formula: str
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Apply formula to Excel cell.
|
|
|
|
Args:
|
|
file_path: Path to Excel file
|
|
sheet_name: Worksheet name
|
|
cell: Cell reference (e.g., 'A1')
|
|
formula: Excel formula (e.g., '=SUM(A1:A10)')
|
|
|
|
Returns:
|
|
Dictionary with result
|
|
"""
|
|
try:
|
|
path = Path(file_path).resolve()
|
|
|
|
if not path.exists():
|
|
return {"success": False, "error": "File not found"}
|
|
|
|
wb = load_workbook(path)
|
|
|
|
if sheet_name not in wb.sheetnames:
|
|
return {"success": False, "error": f"Sheet '{sheet_name}' not found"}
|
|
|
|
ws = wb[sheet_name]
|
|
ws[cell] = formula
|
|
wb.save(path)
|
|
|
|
return {
|
|
"success": True,
|
|
"file_path": str(path),
|
|
"sheet": sheet_name,
|
|
"cell": cell,
|
|
"formula": formula
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Failed to apply formula: {str(e)}"}
|
|
|
|
|
|
async def get_excel_metadata(
|
|
file_path: str
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Get Excel file metadata.
|
|
|
|
Args:
|
|
file_path: Path to Excel file
|
|
|
|
Returns:
|
|
Dictionary with metadata
|
|
"""
|
|
try:
|
|
path = Path(file_path).resolve()
|
|
|
|
if not path.exists():
|
|
return {"success": False, "error": "File not found"}
|
|
|
|
wb = load_workbook(path, data_only=True)
|
|
|
|
sheets_info = []
|
|
for sheet_name in wb.sheetnames:
|
|
ws = wb[sheet_name]
|
|
sheets_info.append({
|
|
"name": sheet_name,
|
|
"max_row": ws.max_row,
|
|
"max_column": ws.max_column
|
|
})
|
|
|
|
return {
|
|
"success": True,
|
|
"file_path": str(path),
|
|
"file_size": path.stat().st_size,
|
|
"sheets": sheets_info,
|
|
"sheet_count": len(wb.sheetnames)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Failed to get metadata: {str(e)}"}
|
|
|
|
|
|
async def create_excel_screenshot(
|
|
file_path: str,
|
|
sheet_name: str | None = None,
|
|
output_dir: str = "."
|
|
) -> Dict[str, Any]:
|
|
"""
|
|
Create a screenshot of Excel file (requires GUI environment).
|
|
Note: This is a simplified implementation that exports to image.
|
|
|
|
Args:
|
|
file_path: Path to Excel file
|
|
sheet_name: Sheet to screenshot (None for first sheet)
|
|
output_dir: Output directory for screenshot
|
|
|
|
Returns:
|
|
Dictionary with screenshot result
|
|
"""
|
|
try:
|
|
import time
|
|
import sys
|
|
import subprocess
|
|
|
|
path = Path(file_path).resolve()
|
|
|
|
if not path.exists():
|
|
return {"success": False, "error": "File not found"}
|
|
|
|
output_path = Path(output_dir)
|
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
|
|
timestamp = int(time.time())
|
|
screenshot_file = output_path / f"{path.stem}_{sheet_name or 'sheet'}_{timestamp}.png"
|
|
|
|
# This is a placeholder - actual implementation would require:
|
|
# - pyautogui for screenshots
|
|
# - or Excel API automation
|
|
# - or conversion tools
|
|
|
|
logger.info(f"📸 Excel screenshot would be saved to: {screenshot_file}")
|
|
|
|
return {
|
|
"success": False,
|
|
"error": "Screenshot requires GUI environment and pyautogui",
|
|
"note": "Install with: pip install pyautogui",
|
|
"intended_output": str(screenshot_file)
|
|
}
|
|
|
|
except Exception as e:
|
|
return {"success": False, "error": f"Screenshot failed: {str(e)}"}
|