mirror of
https://github.com/haris-musa/excel-mcp-server.git
synced 2025-12-08 17:12:41 +08:00
feat: Add functions to insert and delete rows and columns in Excel sheets. (#73)
This commit is contained in:
@ -33,6 +33,10 @@ from excel_mcp.sheet import (
|
|||||||
merge_range,
|
merge_range,
|
||||||
unmerge_range,
|
unmerge_range,
|
||||||
get_merged_ranges,
|
get_merged_ranges,
|
||||||
|
insert_row,
|
||||||
|
insert_cols,
|
||||||
|
delete_rows,
|
||||||
|
delete_cols,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get project root directory path for log file path.
|
# 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}")
|
logger.error(f"Error getting validation info: {e}")
|
||||||
raise
|
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():
|
async def run_sse():
|
||||||
"""Run Excel MCP server in SSE mode."""
|
"""Run Excel MCP server in SSE mode."""
|
||||||
# Assign value to EXCEL_FILES_PATH in SSE mode
|
# Assign value to EXCEL_FILES_PATH in SSE mode
|
||||||
|
|||||||
@ -365,3 +365,111 @@ def delete_range_operation(
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to delete range: {e}")
|
logger.error(f"Failed to delete range: {e}")
|
||||||
raise SheetError(str(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))
|
||||||
|
|||||||
Reference in New Issue
Block a user