Skip to main content
Glama
hyunjae-labs

xlwings Excel MCP Server

by hyunjae-labs

copy_worksheet

Copy a worksheet within an Excel workbook to create duplicates for data analysis, reporting, or template reuse.

Instructions

Copy worksheet within workbook. Args: session_id: Session ID from open_workbook (required) source_sheet: Name of the source worksheet target_sheet: Name of the target worksheet

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
session_idYes
source_sheetYes
target_sheetYes

Implementation Reference

  • Registration and handler function for the 'copy_worksheet' tool. Validates session, locks it, calls the implementation, and returns result or error.
    def copy_worksheet( session_id: str, source_sheet: str, target_sheet: str ) -> str: """ Copy worksheet within workbook. Args: session_id: Session ID from open_workbook (required) source_sheet: Name of the source worksheet target_sheet: Name of the target worksheet """ try: # Validate session using centralized helper session = get_validated_session(session_id) if isinstance(session, str): # Error message returned return session with session.lock: from xlwings_mcp.xlwings_impl.sheet_xlw import copy_worksheet_xlw_with_wb result = copy_worksheet_xlw_with_wb(session.workbook, source_sheet, target_sheet) return result.get("message", "Worksheet copied successfully") if "error" not in result else f"Error: {result['error']}" except (ValidationError, SheetError) as e: return f"Error: {str(e)}" except Exception as e: logger.error(f"Error copying worksheet: {e}") raise
  • Core implementation of worksheet copying using xlwings. Handles both COM API copy and fallback data copy, checks for sheet existence and duplicates, saves the workbook.
    def copy_worksheet_xlw_with_wb(wb, source_sheet: str, target_sheet: str) -> Dict[str, Any]: """Session-based version using existing workbook object. Args: wb: Workbook object from session source_sheet: 원본 시트명 target_sheet: 대상 시트명 Returns: 복사 결과 딕셔너리 """ try: # 원본 시트 확인 existing_sheets = [sheet.name for sheet in wb.sheets] if source_sheet not in existing_sheets: return {"error": f"Source sheet '{source_sheet}' not found"} # 대상 이름 중복 확인 if target_sheet in existing_sheets: return {"error": f"Target sheet '{target_sheet}' already exists"} # 시트 복사 source = wb.sheets[source_sheet] # xlwings에서 시트 복사하기 - COM API 사용 try: # COM API를 통한 시트 복사 source.api.Copy(After=source.api) # 복사된 시트는 보통 마지막에 추가됨 # 복사된 시트 찾기 new_sheets = [sheet.name for sheet in wb.sheets] copied_sheet_name = None for sheet_name in new_sheets: if sheet_name not in existing_sheets: copied_sheet_name = sheet_name break if copied_sheet_name: # 복사된 시트 이름 변경 wb.sheets[copied_sheet_name].name = target_sheet else: # 대안 방법: 수동으로 시트 생성 후 데이터 복사 new_sheet = wb.sheets.add(name=target_sheet) source_range = source.used_range if source_range: new_sheet.range("A1").value = source_range.value except Exception as copy_error: logger.warning(f"COM API 복사 실패, 대안 방법 사용: {copy_error}") # 대안 방법: 새 시트를 만들고 데이터를 복사 new_sheet = wb.sheets.add(name=target_sheet) source_range = source.used_range if source_range: new_sheet.range("A1").value = source_range.value # 파일 저장 wb.save() return {"message": f"Sheet '{source_sheet}' copied to '{target_sheet}'"} except Exception as e: logger.error(f"xlwings 워크시트 복사 실패: {e}") return {"error": f"Failed to copy worksheet: {str(e)}"}
  • Legacy/filepath-based implementation of worksheet copying (not used by the main tool handler). Opens workbook, performs copy, cleans up resources.
    def copy_worksheet_xlw(filepath: str, source_sheet: str, target_sheet: str) -> Dict[str, Any]: """xlwings를 사용한 워크시트 복사 Args: filepath: Excel 파일 경로 source_sheet: 원본 시트명 target_sheet: 대상 시트명 Returns: 복사 결과 딕셔너리 """ app = None wb = None # Initialize COM for thread safety (Windows) _com_initialize() try: # 파일 경로 검증 file_path = Path(filepath) if not file_path.exists(): return {"error": f"File not found: {filepath}"} # Excel 앱 시작 app = xw.App(visible=False, add_book=False) # 워크북 열기 wb = app.books.open(filepath) # 원본 시트 확인 existing_sheets = [sheet.name for sheet in wb.sheets] if source_sheet not in existing_sheets: return {"error": f"Source sheet '{source_sheet}' not found"} # 대상 이름 중복 확인 if target_sheet in existing_sheets: return {"error": f"Target sheet '{target_sheet}' already exists"} # 시트 복사 source = wb.sheets[source_sheet] # xlwings에서 시트 복사하기 - COM API 사용 try: # COM API를 통한 시트 복사 source.api.Copy(After=source.api) # 복사된 시트는 보통 마지막에 추가됨 # 복사된 시트 찾기 new_sheets = [sheet.name for sheet in wb.sheets] copied_sheet_name = None for sheet_name in new_sheets: if sheet_name not in existing_sheets: copied_sheet_name = sheet_name break if copied_sheet_name: # 복사된 시트 이름 변경 wb.sheets[copied_sheet_name].name = target_sheet else: # 대안 방법: 수동으로 시트 생성 후 데이터 복사 new_sheet = wb.sheets.add(name=target_sheet) source_range = source.used_range if source_range: new_sheet.range("A1").value = source_range.value except Exception as copy_error: logger.warning(f"COM API 복사 실패, 대안 방법 사용: {copy_error}") # 대안 방법: 새 시트를 만들고 데이터를 복사 new_sheet = wb.sheets.add(name=target_sheet) source_range = source.used_range if source_range: new_sheet.range("A1").value = source_range.value # 파일 저장 wb.save() return {"message": f"Sheet '{source_sheet}' copied to '{target_sheet}'"} except Exception as e: logger.error(f"xlwings 워크시트 복사 실패: {e}") return {"error": f"Failed to copy worksheet: {str(e)}"} finally: # 리소스 정리 if wb: try: wb.close() except Exception as e: logger.warning(f"워크북 닫기 실패: {e}") if app: try: app.quit() except Exception as e:
  • Legacy wrapper in sheet.py that calls the filepath-based impl and raises exceptions on error (not directly used by the tool).
    def copy_sheet(filepath: str, source_sheet: str, target_sheet: str) -> Dict[str, Any]: """Copy a worksheet within the same workbook.""" result = copy_worksheet_xlw(filepath, source_sheet, target_sheet) if "error" in result: raise SheetError(result["error"]) return result

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/hyunjae-labs/xlwings-mcp-server'

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