Skip to main content
Glama

copy_range

Transfer a specified cell range within an Excel sheet or between sheets using source and target coordinates. Ideal for reorganizing or duplicating data efficiently.

Instructions

Copy a range of cells to another location.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filepathYes
sheet_nameYes
source_endYes
source_startYes
target_sheetNo
target_startYes

Implementation Reference

  • MCP tool handler for 'copy_range': handles input parameters, resolves file path, imports and calls the core copy_range_operation function from sheet.py, and returns the result message or error.
    @mcp.tool() def copy_range( filepath: str, sheet_name: str, source_start: str, source_end: str, target_start: str, target_sheet: Optional[str] = None ) -> str: """Copy a range of cells to another location.""" try: full_path = get_excel_path(filepath) from excel_mcp.sheet import copy_range_operation result = copy_range_operation( full_path, sheet_name, source_start, source_end, target_start, target_sheet or sheet_name # Use source sheet if target_sheet is None ) return result["message"] except (ValidationError, SheetError) as e: return f"Error: {str(e)}" except Exception as e: logger.error(f"Error copying range: {e}") raise
  • Core helper function implementing the range copy logic: loads workbook, validates sheets and ranges, calculates offsets, copies cell values and styles cell-by-cell, and saves the workbook.
    def copy_range_operation( filepath: str, sheet_name: str, source_start: str, source_end: str, target_start: str, target_sheet: Optional[str] = None ) -> Dict: """Copy a range of cells to another location.""" try: wb = load_workbook(filepath) if sheet_name not in wb.sheetnames: logger.error(f"Sheet '{sheet_name}' not found") raise ValidationError(f"Sheet '{sheet_name}' not found") source_ws = wb[sheet_name] target_ws = wb[target_sheet] if target_sheet else source_ws # Parse source range try: start_row, start_col, end_row, end_col = parse_cell_range(source_start, source_end) except ValueError as e: logger.error(f"Invalid source range: {e}") raise ValidationError(f"Invalid source range: {str(e)}") # Parse target starting point try: target_row = int(''.join(filter(str.isdigit, target_start))) target_col = column_index_from_string(''.join(filter(str.isalpha, target_start))) except ValueError as e: logger.error(f"Invalid target cell: {e}") raise ValidationError(f"Invalid target cell: {str(e)}") # Copy the range row_offset = target_row - start_row col_offset = target_col - start_col for i in range(start_row, end_row + 1): for j in range(start_col, end_col + 1): source_cell = source_ws.cell(row=i, column=j) target_cell = target_ws.cell(row=i + row_offset, column=j + col_offset) target_cell.value = source_cell.value if source_cell.has_style: target_cell._style = copy(source_cell._style) wb.save(filepath) return {"message": f"Range copied successfully"} except (ValidationError, SheetError): raise except Exception as e: logger.error(f"Failed to copy range: {e}") raise SheetError(f"Failed to copy range: {str(e)}")
  • Supporting helper function for copying ranges between worksheets, including detailed style copying (font, border, fill, format, alignment). Not directly called by the tool but provides similar copy logic.
    def copy_range( source_ws: Worksheet, target_ws: Worksheet, source_range: str, target_start: Optional[str] = None, ) -> None: """Copy range from source worksheet to target worksheet.""" # Parse source range if ':' in source_range: source_start, source_end = source_range.split(':') else: source_start = source_range source_end = None src_start_row, src_start_col, src_end_row, src_end_col = parse_cell_range( source_start, source_end ) if src_end_row is None: src_end_row = src_start_row src_end_col = src_start_col if target_start is None: target_start = source_start tgt_start_row, tgt_start_col, _, _ = parse_cell_range(target_start) for i, row in enumerate(range(src_start_row, src_end_row + 1)): for j, col in enumerate(range(src_start_col, src_end_col + 1)): source_cell = source_ws.cell(row=row, column=col) target_cell = target_ws.cell(row=tgt_start_row + i, column=tgt_start_col + j) target_cell.value = source_cell.value try: # Copy font font_kwargs = {} if hasattr(source_cell.font, 'name'): font_kwargs['name'] = source_cell.font.name if hasattr(source_cell.font, 'size'): font_kwargs['size'] = source_cell.font.size if hasattr(source_cell.font, 'bold'): font_kwargs['bold'] = source_cell.font.bold if hasattr(source_cell.font, 'italic'): font_kwargs['italic'] = source_cell.font.italic if hasattr(source_cell.font, 'color'): font_color = None if source_cell.font.color: font_color = source_cell.font.color.rgb font_kwargs['color'] = font_color target_cell.font = Font(**font_kwargs) # Copy border new_border = Border() for side in ['left', 'right', 'top', 'bottom']: source_side = getattr(source_cell.border, side) if source_side and source_side.style: side_color = source_side.color.rgb if source_side.color else None setattr(new_border, side, Side( style=source_side.style, color=side_color )) target_cell.border = new_border # Copy fill if hasattr(source_cell, 'fill'): fill_kwargs = {'patternType': source_cell.fill.patternType} if hasattr(source_cell.fill, 'fgColor') and source_cell.fill.fgColor: fg_color = None if hasattr(source_cell.fill.fgColor, 'rgb'): fg_color = source_cell.fill.fgColor.rgb fill_kwargs['fgColor'] = fg_color if hasattr(source_cell.fill, 'bgColor') and source_cell.fill.bgColor: bg_color = None if hasattr(source_cell.fill.bgColor, 'rgb'): bg_color = source_cell.fill.bgColor.rgb fill_kwargs['bgColor'] = bg_color target_cell.fill = PatternFill(**fill_kwargs) # Copy number format and alignment if source_cell.number_format: target_cell.number_format = source_cell.number_format if source_cell.alignment: target_cell.alignment = source_cell.alignment except Exception: continue def delete_range(worksheet: Worksheet, start_cell: str, end_cell: Optional[str] = None) -> None:

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/haris-musa/excel-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server