feat: Add functions to insert and delete rows and columns in Excel sheets. (#73)

This commit is contained in:
John Fisher
2025-07-29 13:20:49 -04:00
committed by GitHub
parent e4b8033dad
commit 429a1e2a13
2 changed files with 184 additions and 0 deletions

View File

@ -33,6 +33,10 @@ from excel_mcp.sheet import (
merge_range,
unmerge_range,
get_merged_ranges,
insert_row,
insert_cols,
delete_rows,
delete_cols,
)
# Get project root directory path for log file path.
@ -599,6 +603,78 @@ def get_data_validation_info(
logger.error(f"Error getting validation info: {e}")
raise
@mcp.tool()
def insert_rows(
filepath: str,
sheet_name: str,
start_row: int,
count: int = 1
) -> str:
"""Insert one or more rows starting at the specified row."""
try:
full_path = get_excel_path(filepath)
result = insert_row(full_path, sheet_name, start_row, count)
return result["message"]
except (ValidationError, SheetError) as e:
return f"Error: {str(e)}"
except Exception as e:
logger.error(f"Error inserting rows: {e}")
raise
@mcp.tool()
def insert_columns(
filepath: str,
sheet_name: str,
start_col: int,
count: int = 1
) -> str:
"""Insert one or more columns starting at the specified column."""
try:
full_path = get_excel_path(filepath)
result = insert_cols(full_path, sheet_name, start_col, count)
return result["message"]
except (ValidationError, SheetError) as e:
return f"Error: {str(e)}"
except Exception as e:
logger.error(f"Error inserting columns: {e}")
raise
@mcp.tool()
def delete_sheet_rows(
filepath: str,
sheet_name: str,
start_row: int,
count: int = 1
) -> str:
"""Delete one or more rows starting at the specified row."""
try:
full_path = get_excel_path(filepath)
result = delete_rows(full_path, sheet_name, start_row, count)
return result["message"]
except (ValidationError, SheetError) as e:
return f"Error: {str(e)}"
except Exception as e:
logger.error(f"Error deleting rows: {e}")
raise
@mcp.tool()
def delete_sheet_columns(
filepath: str,
sheet_name: str,
start_col: int,
count: int = 1
) -> str:
"""Delete one or more columns starting at the specified column."""
try:
full_path = get_excel_path(filepath)
result = delete_cols(full_path, sheet_name, start_col, count)
return result["message"]
except (ValidationError, SheetError) as e:
return f"Error: {str(e)}"
except Exception as e:
logger.error(f"Error deleting columns: {e}")
raise
async def run_sse():
"""Run Excel MCP server in SSE mode."""
# Assign value to EXCEL_FILES_PATH in SSE mode

View File

@ -365,3 +365,111 @@ def delete_range_operation(
except Exception as e:
logger.error(f"Failed to delete range: {e}")
raise SheetError(str(e))
def insert_row(filepath: str, sheet_name: str, start_row: int, count: int = 1) -> Dict[str, Any]:
"""Insert one or more rows starting at the specified row."""
try:
wb = load_workbook(filepath)
if sheet_name not in wb.sheetnames:
raise SheetError(f"Sheet '{sheet_name}' not found")
worksheet = wb[sheet_name]
# Validate parameters
if start_row < 1:
raise ValidationError("Start row must be 1 or greater")
if count < 1:
raise ValidationError("Count must be 1 or greater")
worksheet.insert_rows(start_row, count)
wb.save(filepath)
return {"message": f"Inserted {count} row(s) starting at row {start_row} in sheet '{sheet_name}'"}
except (ValidationError, SheetError) as e:
logger.error(str(e))
raise
except Exception as e:
logger.error(f"Failed to insert rows: {e}")
raise SheetError(str(e))
def insert_cols(filepath: str, sheet_name: str, start_col: int, count: int = 1) -> Dict[str, Any]:
"""Insert one or more columns starting at the specified column."""
try:
wb = load_workbook(filepath)
if sheet_name not in wb.sheetnames:
raise SheetError(f"Sheet '{sheet_name}' not found")
worksheet = wb[sheet_name]
# Validate parameters
if start_col < 1:
raise ValidationError("Start column must be 1 or greater")
if count < 1:
raise ValidationError("Count must be 1 or greater")
worksheet.insert_cols(start_col, count)
wb.save(filepath)
return {"message": f"Inserted {count} column(s) starting at column {start_col} in sheet '{sheet_name}'"}
except (ValidationError, SheetError) as e:
logger.error(str(e))
raise
except Exception as e:
logger.error(f"Failed to insert columns: {e}")
raise SheetError(str(e))
def delete_rows(filepath: str, sheet_name: str, start_row: int, count: int = 1) -> Dict[str, Any]:
"""Delete one or more rows starting at the specified row."""
try:
wb = load_workbook(filepath)
if sheet_name not in wb.sheetnames:
raise SheetError(f"Sheet '{sheet_name}' not found")
worksheet = wb[sheet_name]
# Validate parameters
if start_row < 1:
raise ValidationError("Start row must be 1 or greater")
if count < 1:
raise ValidationError("Count must be 1 or greater")
if start_row > worksheet.max_row:
raise ValidationError(f"Start row {start_row} exceeds worksheet bounds (max row: {worksheet.max_row})")
worksheet.delete_rows(start_row, count)
wb.save(filepath)
return {"message": f"Deleted {count} row(s) starting at row {start_row} in sheet '{sheet_name}'"}
except (ValidationError, SheetError) as e:
logger.error(str(e))
raise
except Exception as e:
logger.error(f"Failed to delete rows: {e}")
raise SheetError(str(e))
def delete_cols(filepath: str, sheet_name: str, start_col: int, count: int = 1) -> Dict[str, Any]:
"""Delete one or more columns starting at the specified column."""
try:
wb = load_workbook(filepath)
if sheet_name not in wb.sheetnames:
raise SheetError(f"Sheet '{sheet_name}' not found")
worksheet = wb[sheet_name]
# Validate parameters
if start_col < 1:
raise ValidationError("Start column must be 1 or greater")
if count < 1:
raise ValidationError("Count must be 1 or greater")
if start_col > worksheet.max_column:
raise ValidationError(f"Start column {start_col} exceeds worksheet bounds (max column: {worksheet.max_column})")
worksheet.delete_cols(start_col, count)
wb.save(filepath)
return {"message": f"Deleted {count} column(s) starting at column {start_col} in sheet '{sheet_name}'"}
except (ValidationError, SheetError) as e:
logger.error(str(e))
raise
except Exception as e:
logger.error(f"Failed to delete columns: {e}")
raise SheetError(str(e))