[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FVRXY219272A6FGRHDVFZG":3,"skill-same:01M6FVRXY219272A6FGRHDVFZG":91},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":25,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":64,"commitSha":65,"skillDirectory":66,"forksCount":67,"repositoryHtmlUrl":68,"repositoryHomepageUrl":6,"ownerHtmlUrl":69,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":70,"install":71,"resources":84},"01M6FVRXY219272A6FGRHDVFZG","excel-automation",null,"Advanced Excel automation with Python using xlwings - interact with live Excel instances","kbarbel640-del\u002Fskills","kbarbel640-del","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F255315490?v=4","01M6CJPPQGCCESXMG3K7BBGQ5J","01M6CJPPX2PB2BCZERFVM2C2B3",1,"MIT","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Flijie420461340\u002Fexcel-automation\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000004","电子表格","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"automation","Excel Automation","xlsx","operations","opus","sonnet","advanced","with","live","macros","xlwings","instances","computer","execution","office","file","https","code","github","python","2026-11-10 10:12:30",false,"---\nname: excel-automation\ndescription: Advanced Excel automation with Python using xlwings - interact with live Excel instances\nauthor: claude-office-skills\nversion: \"1.0\"\ntags: [excel, automation, xlwings, macros, python]\nmodels: [claude-sonnet-4, claude-opus-4]\ntools: [computer, code_execution, file_operations]\nlibrary:\n  name: xlwings\n  url: https:\u002F\u002Fgithub.com\u002Fxlwings\u002Fxlwings\n  stars: 3.3k\n---\n\n# Excel Automation Skill\n\n## Overview\n\nThis skill enables advanced Excel automation using **xlwings** - a library that can interact with live Excel instances. Unlike openpyxl (file-only), xlwings can control Excel in real-time, execute VBA, update dashboards, and automate complex workflows.\n\n## How to Use\n\n1. Describe the Excel automation task you need\n2. Specify if you need live Excel interaction or file processing\n3. I'll generate xlwings code and execute it\n\n**Example prompts:**\n- \"Update this live Excel dashboard with new data\"\n- \"Run this VBA macro and get the results\"\n- \"Create an Excel add-in for data validation\"\n- \"Automate monthly report generation with live charts\"\n\n## Domain Knowledge\n\n### xlwings vs openpyxl\n\n| Feature | xlwings | openpyxl |\n|---------|---------|----------|\n| Requires Excel | Yes | No |\n| Live interaction | Yes | No |\n| VBA execution | Yes | No |\n| Speed (large files) | Fast | Slow |\n| Server deployment | Limited | Easy |\n\n### xlwings Fundamentals\n\n```python\nimport xlwings as xw\n\n# Connect to active Excel workbook\nwb = xw.Book.caller()  # From Excel add-in\nwb = xw.books.active   # Active workbook\n\n# Open specific file\nwb = xw.Book('path\u002Fto\u002Ffile.xlsx')\n\n# Create new workbook\nwb = xw.Book()\n\n# Get sheet\nsheet = wb.sheets['Sheet1']\nsheet = wb.sheets[0]\n```\n\n### Working with Ranges\n\n#### Reading and Writing\n```python\n# Single cell\nsheet['A1'].value = 'Hello'\nvalue = sheet['A1'].value\n\n# Range\nsheet['A1:C3'].value = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\ndata = sheet['A1:C3'].value  # Returns list of lists\n\n# Named range\nsheet['MyRange'].value = 'Named data'\n\n# Expand range (detect data boundaries)\nsheet['A1'].expand().value  # All connected data\nsheet['A1'].expand('table').value  # Table format\n```\n\n#### Dynamic Ranges\n```python\n# Current region (like Ctrl+Shift+End)\ndata = sheet['A1'].current_region.value\n\n# Used range\nused = sheet.used_range.value\n\n# Last row with data\nlast_row = sheet['A1'].end('down').row\n\n# Resize range\nrng = sheet['A1'].resize(10, 5)  # 10 rows, 5 columns\n```\n\n### Formatting\n```python\n# Font\nsheet['A1'].font.bold = True\nsheet['A1'].font.size = 14\nsheet['A1'].font.color = (255, 0, 0)  # RGB red\n\n# Fill\nsheet['A1'].color = (255, 255, 0)  # Yellow background\n\n# Number format\nsheet['B1'].number_format = '$#,##0.00'\n\n# Column width\nsheet['A:A'].column_width = 20\n\n# Row height\nsheet['1:1'].row_height = 30\n\n# Autofit\nsheet['A:D'].autofit()\n```\n\n### Excel Features\n\n#### Charts\n```python\n# Add chart\nchart = sheet.charts.add(left=100, top=100, width=400, height=250)\nchart.set_source_data(sheet['A1:B10'])\nchart.chart_type = 'column_clustered'\nchart.name = 'Sales Chart'\n\n# Modify existing chart\nchart = sheet.charts['Sales Chart']\nchart.chart_type = 'line'\n```\n\n#### Tables\n```python\n# Create Excel Table\nrng = sheet['A1'].expand()\ntable = sheet.tables.add(source=rng, name='SalesTable')\n\n# Refresh table\ntable.refresh()\n\n# Access table data\ntable_data = table.data_body_range.value\n```\n\n#### Pictures\n```python\n# Add picture\nsheet.pictures.add('logo.png', left=10, top=10, width=100, height=50)\n\n# Update picture from matplotlib\nimport matplotlib.pyplot as plt\nfig, ax = plt.subplots()\nax.plot([1, 2, 3], [1, 4, 9])\nsheet.pictures.add(fig, name='MyPlot', update=True)\n```\n\n### VBA Integration\n```python\n# Run VBA macro\nwb.macro('MacroName')()\n\n# With arguments\nwb.macro('MyMacro')('arg1', 'arg2')\n\n# Get return value\nresult = wb.macro('CalculateTotal')(100, 200)\n\n# Access VBA module\nvb_code = wb.api.VBProject.VBComponents('Module1').CodeModule.Lines(1, 10)\n```\n\n### User Defined Functions (UDFs)\n```python\n# Define a UDF (in Python file)\nimport xlwings as xw\n\n@xw.func\ndef my_sum(x, y):\n    \"\"\"Add two numbers\"\"\"\n    return x + y\n\n@xw.func\n@xw.arg('data', ndim=2)\ndef my_array_func(data):\n    \"\"\"Process array data\"\"\"\n    import numpy as np\n    return np.sum(data)\n\n# These become Excel functions: =my_sum(A1, B1)\n```\n\n### Application Control\n```python\n# Excel application settings\napp = xw.apps.active\napp.screen_updating = False  # Speed up\napp.calculation = 'manual'   # Manual calc\napp.display_alerts = False   # Suppress dialogs\n\n# Perform operations...\n\n# Restore\napp.screen_updating = True\napp.calculation = 'automatic'\napp.display_alerts = True\n```\n\n## Best Practices\n\n1. **Disable Screen Updating**: For batch operations\n2. **Use Arrays**: Read\u002Fwrite entire ranges, not cell-by-cell\n3. **Manual Calculation**: Turn off auto-calc during data loading\n4. **Close Connections**: Properly close workbooks when done\n5. **Error Handling**: Handle Excel not being installed\n\n## Common Patterns\n\n### Performance Optimization\n```python\nimport xlwings as xw\n\ndef batch_update(data, workbook_path):\n    app = xw.App(visible=False)\n    try:\n        app.screen_updating = False\n        app.calculation = 'manual'\n        \n        wb = app.books.open(workbook_path)\n        sheet = wb.sheets['Data']\n        \n        # Write all data at once\n        sheet['A1'].value = data\n        \n        app.calculation = 'automatic'\n        wb.save()\n    finally:\n        wb.close()\n        app.quit()\n```\n\n### Dashboard Update\n```python\ndef update_dashboard(data_dict):\n    wb = xw.books.active\n    \n    # Update data sheet\n    data_sheet = wb.sheets['Data']\n    for name, values in data_dict.items():\n        data_sheet[name].value = values\n    \n    # Refresh all charts\n    dashboard = wb.sheets['Dashboard']\n    for chart in dashboard.charts:\n        chart.refresh()\n    \n    # Update timestamp\n    from datetime import datetime\n    dashboard['A1'].value = f'Last Updated: {datetime.now()}'\n```\n\n### Report Generator\n```python\ndef generate_monthly_report(month, data):\n    template = xw.Book('template.xlsx')\n    \n    # Fill data\n    sheet = template.sheets['Report']\n    sheet['B2'].value = month\n    sheet['A5'].value = data\n    \n    # Run calculations\n    template.app.calculate()\n    \n    # Export to PDF\n    sheet.api.ExportAsFixedFormat(0, f'report_{month}.pdf')\n    \n    template.save(f'report_{month}.xlsx')\n```\n\n## Examples\n\n### Example 1: Live Dashboard Update\n```python\nimport xlwings as xw\nimport pandas as pd\nfrom datetime import datetime\n\n# Connect to running Excel\nwb = xw.books.active\ndashboard = wb.sheets['Dashboard']\ndata_sheet = wb.sheets['Data']\n\n# Fetch new data (simulated)\nnew_data = pd.DataFrame({\n    'Date': pd.date_range('2024-01-01', periods=30),\n    'Sales': [1000 + i*50 for i in range(30)],\n    'Costs': [600 + i*30 for i in range(30)]\n})\n\n# Update data sheet\ndata_sheet['A1'].value = new_data\n\n# Calculate profit\ndata_sheet['D1'].value = 'Profit'\ndata_sheet['D2'].value = '=B2-C2'\ndata_sheet['D2'].expand('down').value = data_sheet['D2'].formula\n\n# Update KPIs on dashboard\ndashboard['B2'].value = new_data['Sales'].sum()\ndashboard['B3'].value = new_data['Costs'].sum()\ndashboard['B4'].value = new_data['Sales'].sum() - new_data['Costs'].sum()\ndashboard['A1'].value = f'Updated: {datetime.now().strftime(\"%Y-%m-%d %H:%M\")}'\n\n# Refresh charts\nfor chart in dashboard.charts:\n    chart.api.Refresh()\n\nprint(\"Dashboard updated!\")\n```\n\n### Example 2: Batch Processing Multiple Files\n```python\nimport xlwings as xw\nfrom pathlib import Path\n\ndef process_sales_files(folder_path, output_path):\n    \"\"\"Consolidate multiple Excel files into one summary.\"\"\"\n    \n    app = xw.App(visible=False)\n    app.screen_updating = False\n    \n    try:\n        # Create summary workbook\n        summary_wb = xw.Book()\n        summary_sheet = summary_wb.sheets[0]\n        summary_sheet.name = 'Consolidated'\n        \n        headers = ['File', 'Total Sales', 'Total Units', 'Avg Price']\n        summary_sheet['A1'].value = headers\n        \n        row = 2\n        for file in Path(folder_path).glob('*.xlsx'):\n            wb = app.books.open(str(file))\n            data_sheet = wb.sheets['Sales']\n            \n            # Extract summary\n            total_sales = data_sheet['B:B'].api.SpecialCells(11).Value  # xlCellTypeConstants\n            total_units = data_sheet['C:C'].api.SpecialCells(11).Value\n            \n            # Calculate and write\n            summary_sheet[f'A{row}'].value = file.name\n            summary_sheet[f'B{row}'].value = sum(total_sales) if isinstance(total_sales, (list, tuple)) else total_sales\n            summary_sheet[f'C{row}'].value = sum(total_units) if isinstance(total_units, (list, tuple)) else total_units\n            summary_sheet[f'D{row}'].value = f'=B{row}\u002FC{row}'\n            \n            wb.close()\n            row += 1\n        \n        # Format summary\n        summary_sheet['A1:D1'].font.bold = True\n        summary_sheet['B:D'].number_format = '$#,##0.00'\n        summary_sheet['A:D'].autofit()\n        \n        summary_wb.save(output_path)\n        \n    finally:\n        app.quit()\n    \n    print(f\"Consolidated {row-2} files to {output_path}\")\n\n# Usage\nprocess_sales_files('\u002Fpath\u002Fto\u002Fsales\u002F', 'consolidated_sales.xlsx')\n```\n\n### Example 3: Excel Add-in with UDFs\n```python\n# myudfs.py - Place in xlwings project\n\nimport xlwings as xw\nimport numpy as np\n\n@xw.func\n@xw.arg('data', pd.DataFrame, index=False, header=False)\n@xw.ret(expand='table')\ndef GROWTH_RATE(data):\n    \"\"\"Calculate period-over-period growth rate\"\"\"\n    values = data.iloc[:, 0].values\n    growth = np.diff(values) \u002F values[:-1] * 100\n    return [['Growth %']] + [[g] for g in growth]\n\n@xw.func\n@xw.arg('range1', np.array, ndim=2)\n@xw.arg('range2', np.array, ndim=2)\ndef CORRELATION(range1, range2):\n    \"\"\"Calculate correlation between two ranges\"\"\"\n    return np.corrcoef(range1.flatten(), range2.flatten())[0, 1]\n\n@xw.func\ndef SENTIMENT(text):\n    \"\"\"Basic sentiment analysis (placeholder)\"\"\"\n    positive = ['good', 'great', 'excellent', 'amazing']\n    negative = ['bad', 'poor', 'terrible', 'awful']\n    \n    text_lower = text.lower()\n    pos_count = sum(word in text_lower for word in positive)\n    neg_count = sum(word in text_lower for word in negative)\n    \n    if pos_count > neg_count:\n        return 'Positive'\n    elif neg_count > pos_count:\n        return 'Negative'\n    return 'Neutral'\n```\n\n## Limitations\n\n- Requires Excel to be installed\n- Limited support on macOS for some features\n- Not suitable for server-side processing\n- VBA features require trust settings\n- Performance varies with Excel version\n\n## Installation\n\n```bash\npip install xlwings\n\n# For add-in functionality\nxlwings addin install\n```\n\n## Resources\n\n- [xlwings Documentation](https:\u002F\u002Fdocs.xlwings.org\u002F)\n- [GitHub Repository](https:\u002F\u002Fgithub.com\u002Fxlwings\u002Fxlwings)\n- [UDF Tutorial](https:\u002F\u002Fdocs.xlwings.org\u002Fen\u002Fstable\u002Fudfs.html)\n- [Excel VBA Reference](https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Foffice\u002Fvba\u002Fapi\u002Foverview\u002Fexcel)\n","# Excel Automation Skill\n\n## Overview\n\nThis skill enables advanced Excel automation using **xlwings** - a library that can interact with live Excel instances. Unlike openpyxl (file-only), xlwings can control Excel in real-time, execute VBA, update dashboards, and automate complex workflows.\n\n## How to Use\n\n1. Describe the Excel automation task you need\n2. Specify if you need live Excel interaction or file processing\n3. I'll generate xlwings code and execute it\n\n**Example prompts:**\n- \"Update this live Excel dashboard with new data\"\n- \"Run this VBA macro and get the results\"\n- \"Create an Excel add-in for data validation\"\n- \"Automate monthly report generation with live charts\"\n\n## Domain Knowledge\n\n### xlwings vs openpyxl\n\n| Feature | xlwings | openpyxl |\n|---------|---------|----------|\n| Requires Excel | Yes | No |\n| Live interaction | Yes | No |\n| VBA execution | Yes | No |\n| Speed (large files) | Fast | Slow |\n| Server deployment | Limited | Easy |\n\n### xlwings Fundamentals\n\n```python\nimport xlwings as xw\n\n# Connect to active Excel workbook\nwb = xw.Book.caller()  # From Excel add-in\nwb = xw.books.active   # Active workbook\n\n# Open specific file\nwb = xw.Book('path\u002Fto\u002Ffile.xlsx')\n\n# Create new workbook\nwb = xw.Book()\n\n# Get sheet\nsheet = wb.sheets['Sheet1']\nsheet = wb.sheets[0]\n```\n\n### Working with Ranges\n\n#### Reading and Writing\n```python\n# Single cell\nsheet['A1'].value = 'Hello'\nvalue = sheet['A1'].value\n\n# Range\nsheet['A1:C3'].value = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]\ndata = sheet['A1:C3'].value  # Returns list of lists\n\n# Named range\nsheet['MyRange'].value = 'Named data'\n\n# Expand range (detect data boundaries)\nsheet['A1'].expand().value  # All connected data\nsheet['A1'].expand('table').value  # Table format\n```\n\n#### Dynamic Ranges\n```python\n# Current region (like Ctrl+Shift+End)\ndata = sheet['A1'].current_region.value\n\n# Used range\nused = sheet.used_range.value\n\n# Last row with data\nlast_row = sheet['A1'].end('down').row\n\n# Resize range\nrng = sheet['A1'].resize(10, 5)  # 10 rows, 5 columns\n```\n\n### Formatting\n```python\n# Font\nsheet['A1'].font.bold = True\nsheet['A1'].font.size = 14\nsheet['A1'].font.color = (255, 0, 0)  # RGB red\n\n# Fill\nsheet['A1'].color = (255, 255, 0)  # Yellow background\n\n# Number format\nsheet['B1'].number_format = '$#,##0.00'\n\n# Column width\nsheet['A:A'].column_width = 20\n\n# Row height\nsheet['1:1'].row_height = 30\n\n# Autofit\nsheet['A:D'].autofit()\n```\n\n### Excel Features\n\n#### Charts\n```python\n# Add chart\nchart = sheet.charts.add(left=100, top=100, width=400, height=250)\nchart.set_source_data(sheet['A1:B10'])\nchart.chart_type = 'column_clustered'\nchart.name = 'Sales Chart'\n\n# Modify existing chart\nchart = sheet.charts['Sales Chart']\nchart.chart_type = 'line'\n```\n\n#### Tables\n```python\n# Create Excel Table\nrng = sheet['A1'].expand()\ntable = sheet.tables.add(source=rng, name='SalesTable')\n\n# Refresh table\ntable.refresh()\n\n# Access table data\ntable_data = table.data_body_range.value\n```\n\n#### Pictures\n```python\n# Add picture\nsheet.pictures.add('logo.png', left=10, top=10, width=100, height=50)\n\n# Update picture from matplotlib\nimport matplotlib.pyplot as plt\nfig, ax = plt.subplots()\nax.plot([1, 2, 3], [1, 4, 9])\nsheet.pictures.add(fig, name='MyPlot', update=True)\n```\n\n### VBA Integration\n```python\n# Run VBA macro\nwb.macro('MacroName')()\n\n# With arguments\nwb.macro('MyMacro')('arg1', 'arg2')\n\n# Get return value\nresult = wb.macro('CalculateTotal')(100, 200)\n\n# Access VBA module\nvb_code = wb.api.VBProject.VBComponents('Module1').CodeModule.Lines(1, 10)\n```\n\n### User Defined Functions (UDFs)\n```python\n# Define a UDF (in Python file)\nimport xlwings as xw\n\n@xw.func\ndef my_sum(x, y):\n    \"\"\"Add two numbers\"\"\"\n    return x + y\n\n@xw.func\n@xw.arg('data', ndim=2)\ndef my_array_func(data):\n    \"\"\"Process array data\"\"\"\n    import numpy as np\n    return np.sum(data)\n\n# These become Excel functions: =my_sum(A1, B1)\n```\n\n### Application Control\n```python\n# Excel application settings\napp = xw.apps.active\napp.screen_updating = False  # Speed up\napp.calculation = 'manual'   # Manual calc\napp.display_alerts = False   # Suppress dialogs\n\n# Perform operations...\n\n# Restore\napp.screen_updating = True\napp.calculation = 'automatic'\napp.display_alerts = True\n```\n\n## Best Practices\n\n1. **Disable Screen Updating**: For batch operations\n2. **Use Arrays**: Read\u002Fwrite entire ranges, not cell-by-cell\n3. **Manual Calculation**: Turn off auto-calc during data loading\n4. **Close Connections**: Properly close workbooks when done\n5. **Error Handling**: Handle Excel not being installed\n\n## Common Patterns\n\n### Performance Optimization\n```python\nimport xlwings as xw\n\ndef batch_update(data, workbook_path):\n    app = xw.App(visible=False)\n    try:\n        app.screen_updating = False\n        app.calculation = 'manual'\n        \n        wb = app.books.open(workbook_path)\n        sheet = wb.sheets['Data']\n        \n        # Write all data at once\n        sheet['A1'].value = data\n        \n        app.calculation = 'automatic'\n        wb.save()\n    finally:\n        wb.close()\n        app.quit()\n```\n\n### Dashboard Update\n```python\ndef update_dashboard(data_dict):\n    wb = xw.books.active\n    \n    # Update data sheet\n    data_sheet = wb.sheets['Data']\n    for name, values in data_dict.items():\n        data_sheet[name].value = values\n    \n    # Refresh all charts\n    dashboard = wb.sheets['Dashboard']\n    for chart in dashboard.charts:\n        chart.refresh()\n    \n    # Update timestamp\n    from datetime import datetime\n    dashboard['A1'].value = f'Last Updated: {datetime.now()}'\n```\n\n### Report Generator\n```python\ndef generate_monthly_report(month, data):\n    template = xw.Book('template.xlsx')\n    \n    # Fill data\n    sheet = template.sheets['Report']\n    sheet['B2'].value = month\n    sheet['A5'].value = data\n    \n    # Run calculations\n    template.app.calculate()\n    \n    # Export to PDF\n    sheet.api.ExportAsFixedFormat(0, f'report_{month}.pdf')\n    \n    template.save(f'report_{month}.xlsx')\n```\n\n## Examples\n\n### Example 1: Live Dashboard Update\n```python\nimport xlwings as xw\nimport pandas as pd\nfrom datetime import datetime\n\n# Connect to running Excel\nwb = xw.books.active\ndashboard = wb.sheets['Dashboard']\ndata_sheet = wb.sheets['Data']\n\n# Fetch new data (simulated)\nnew_data = pd.DataFrame({\n    'Date': pd.date_range('2024-01-01', periods=30),\n    'Sales': [1000 + i*50 for i in range(30)],\n    'Costs': [600 + i*30 for i in range(30)]\n})\n\n# Update data sheet\ndata_sheet['A1'].value = new_data\n\n# Calculate profit\ndata_sheet['D1'].value = 'Profit'\ndata_sheet['D2'].value = '=B2-C2'\ndata_sheet['D2'].expand('down').value = data_sheet['D2'].formula\n\n# Update KPIs on dashboard\ndashboard['B2'].value = new_data['Sales'].sum()\ndashboard['B3'].value = new_data['Costs'].sum()\ndashboard['B4'].value = new_data['Sales'].sum() - new_data['Costs'].sum()\ndashboard['A1'].value = f'Updated: {datetime.now().strftime(\"%Y-%m-%d %H:%M\")}'\n\n# Refresh charts\nfor chart in dashboard.charts:\n    chart.api.Refresh()\n\nprint(\"Dashboard updated!\")\n```\n\n### Example 2: Batch Processing Multiple Files\n```python\nimport xlwings as xw\nfrom pathlib import Path\n\ndef process_sales_files(folder_path, output_path):\n    \"\"\"Consolidate multiple Excel files into one summary.\"\"\"\n    \n    app = xw.App(visible=False)\n    app.screen_updating = False\n    \n    try:\n        # Create summary workbook\n        summary_wb = xw.Book()\n        summary_sheet = summary_wb.sheets[0]\n        summary_sheet.name = 'Consolidated'\n        \n        headers = ['File', 'Total Sales', 'Total Units', 'Avg Price']\n        summary_sheet['A1'].value = headers\n        \n        row = 2\n        for file in Path(folder_path).glob('*.xlsx'):\n            wb = app.books.open(str(file))\n            data_sheet = wb.sheets['Sales']\n            \n            # Extract summary\n            total_sales = data_sheet['B:B'].api.SpecialCells(11).Value  # xlCellTypeConstants\n            total_units = data_sheet['C:C'].api.SpecialCells(11).Value\n            \n            # Calculate and write\n            summary_sheet[f'A{row}'].value = file.name\n            summary_sheet[f'B{row}'].value = sum(total_sales) if isinstance(total_sales, (list, tuple)) else total_sales\n            summary_sheet[f'C{row}'].value = sum(total_units) if isinstance(total_units, (list, tuple)) else total_units\n            summary_sheet[f'D{row}'].value = f'=B{row}\u002FC{row}'\n            \n            wb.close()\n            row += 1\n        \n        # Format summary\n        summary_sheet['A1:D1'].font.bold = True\n        summary_sheet['B:D'].number_format = '$#,##0.00'\n        summary_sheet['A:D'].autofit()\n        \n        summary_wb.save(output_path)\n        \n    finally:\n        app.quit()\n    \n    print(f\"Consolidated {row-2} files to {output_path}\")\n\n# Usage\nprocess_sales_files('\u002Fpath\u002Fto\u002Fsales\u002F', 'consolidated_sales.xlsx')\n```\n\n### Example 3: Excel Add-in with UDFs\n```python\n# myudfs.py - Place in xlwings project\n\nimport xlwings as xw\nimport numpy as np\n\n@xw.func\n@xw.arg('data', pd.DataFrame, index=False, header=False)\n@xw.ret(expand='table')\ndef GROWTH_RATE(data):\n    \"\"\"Calculate period-over-period growth rate\"\"\"\n    values = data.iloc[:, 0].values\n    growth = np.diff(values) \u002F values[:-1] * 100\n    return [['Growth %']] + [[g] for g in growth]\n\n@xw.func\n@xw.arg('range1', np.array, ndim=2)\n@xw.arg('range2', np.array, ndim=2)\ndef CORRELATION(range1, range2):\n    \"\"\"Calculate correlation between two ranges\"\"\"\n    return np.corrcoef(range1.flatten(), range2.flatten())[0, 1]\n\n@xw.func\ndef SENTIMENT(text):\n    \"\"\"Basic sentiment analysis (placeholder)\"\"\"\n    positive = ['good', 'great', 'excellent', 'amazing']\n    negative = ['bad', 'poor', 'terrible', 'awful']\n    \n    text_lower = text.lower()\n    pos_count = sum(word in text_lower for word in positive)\n    neg_count = sum(word in text_lower for word in negative)\n    \n    if pos_count > neg_count:\n        return 'Positive'\n    elif neg_count > pos_count:\n        return 'Negative'\n    return 'Neutral'\n```\n\n## Limitations\n\n- Requires Excel to be installed\n- Limited support on macOS for some features\n- Not suitable for server-side processing\n- VBA features require trust settings\n- Performance varies with Excel version\n\n## Installation\n\n```bash\npip install xlwings\n\n# For add-in functionality\nxlwings addin install\n```\n\n## Resources\n\n- [xlwings Documentation](https:\u002F\u002Fdocs.xlwings.org\u002F)\n- [GitHub Repository](https:\u002F\u002Fgithub.com\u002Fxlwings\u002Fxlwings)\n- [UDF Tutorial](https:\u002F\u002Fdocs.xlwings.org\u002Fen\u002Fstable\u002Fudfs.html)\n- [Excel VBA Reference](https:\u002F\u002Fdocs.microsoft.com\u002Fen-us\u002Foffice\u002Fvba\u002Fapi\u002Foverview\u002Fexcel)\n",{"name":5,"tags":51,"tools":53,"author":56,"models":57,"library":60,"version":63,"description":7},[52,26,36,35,45],"excel",[38,54,55],"code_execution","file_operations","claude-office-skills",[58,59],"claude-sonnet-4","claude-opus-4",{"url":61,"name":36,"stars":62},"https:\u002F\u002Fgithub.com\u002Fxlwings\u002Fxlwings","3.3k","1.0","main","e7e336ac628c3e3bd771aff1aaa469c93778f94a","skills\u002Flijie420461340\u002Fexcel-automation",0,"https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del","2026-08-23 22:39:37",{"source":8,"skillName":5,"commands":72,"prompt":82,"zipAvailable":83},[73,76,79],{"tool":74,"command":75},"npx","npx skills add kbarbel640-del\u002Fskills --skill excel-automation",{"tool":77,"command":78},"bunx","bunx skills add kbarbel640-del\u002Fskills --skill excel-automation",{"tool":80,"command":81},"pnpm","pnpm dlx skills add kbarbel640-del\u002Fskills --skill excel-automation","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Flijie420461340\u002Fexcel-automation\u002FSKILL.md",true,[85],{"path":86,"resourceType":87,"resourceTypeDesc":88,"sizeBytes":89,"sourceHtmlUrl":90},"_meta.json","REFERENCE","参考文档",292,"https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Flijie420461340\u002Fexcel-automation\u002F_meta.json",[92,120,144,165,171,191],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":103,"publishedAt":46},"01M6G8J55967D6281ACMKAKTEQ","crowd-prompting","A marketplace where AI agents improve prompts, system instructions, tool descriptions, and other text-based content with domain expertise from real-world operations — and earn tokens for valuable contributions.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzzadrian\u002Fcrowd-prompting\u002FSKILL.md",[98],{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[104,105,106,33,107,108,109,110,29,111,112,113,114,115,116,117,42,118,119],"crowd prompting","prompting","api","tokens","domain","world","prompts","instructions","text","tool","system","improve","productivity","marketplace","content","ai agents",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":127,"publishedAt":46},"01M6G8J0PKPAYVET6BWE8W4C26","dilemm-ai","Compete in DilemmAI, the prisoner's dilemma AI arena at dilemm.ai. Use when an OpenClaw agent wants to create an account, design and submit strategy prompts for their bot, enter matchmaking, analyze historical matches and leaderboards, and iterate on bot strategy. Requires headless browser automation (no API available yet).","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzyori\u002Fdilemm-ai\u002FSKILL.md",[126],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},[128,106,129,130,131,132,133,26,134,135,136,137,138,139,140,141,142,110,143],"dilemm ai","arena","analyze","browser","openclaw agent","create","browser automation","bot","openclaw","design","strategy","headless","compete","submit","matchmaking","use",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":153,"publishedAt":46},"01M6G8HWAF3K9SW7NP3Z83CPJ6","arxiv-paper-reviews","Interact with arXiv Crawler API to fetch papers, read reviews, and submit comments. Use when working with arXiv papers, fetching paper lists by date\u002Fcategory\u002Finterest, viewing paper details with comments, or submitting paper reviews via API at http:\u002F\u002F150.158.152.82:8000.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzxrys\u002Fweak-accept\u002FSKILL.md",[150],{"categoryNo":151,"categoryName":152,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000021","资料检索与研究",[154,155,156,157,158,159,160,33,161,141,143,162,106,163,164],"arxiv paper reviews","reviews","arxiv","paper","crawler","papers","comments","fetch","read","http","via",{"skillNo":166,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":167,"categories":168,"keywords":170,"publishedAt":46},"01M6G8HQJ7N7WMY6YV7D7SSJ16","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzxrys\u002Farxiv-paper-reviews\u002FSKILL.md",[169],{"categoryNo":151,"categoryName":152,"taxonomyType":20,"taxonomyTypeDesc":21},[157,156,155,154,164,159,160,33,158,141,143,161,162,106,163],{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":177,"publishedAt":46},"01M6G8HM95Y64JNVFC2HN4E2BG","git-summary","Get a quick summary of the current Git repository including status, recent commits, branches, and contributors.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzweack\u002Fgit-summary\u002FSKILL.md",[],[178,179,180,181,182,183,184,185,186,187,188,189,190],"git","summary","git summary","commits","repository","win32","status","linux","contributors","true","quick","get","branches",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":201,"publishedAt":46},"01M6G8HGEGF05CNEJCGVYFSC4R","agent-constitution","Interact with AgentConstitution governance contracts on Base Sepolia. Check compliance, read rules, log actions, query governance state.","https:\u002F\u002Fgithub.com\u002Fkbarbel640-del\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fztsalexey\u002Fagent-constitution\u002FSKILL.md",[197,198],{"categoryNo":23,"categoryName":24,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":199,"categoryName":200,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000037","律师与法务",[202,203,204,205,33,206,207,64,208,162,209,210,211,212,213,42,214,215,44],"agent constitution","constitution","contracts","tree","query","base","log","check","Rules","projects","compliance","actions","state","governance"]