
Excel Parser
- 80 installs
- Updated March 14, 2026
- yejinlei/excel-parser-skill
Helps with ai & agent building tasks.
About
excel-parser is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- excel-parser
- AI & Agent Building
- AI-coding skill
Excel Parser by the numbers
- 80 all-time installs (skills.sh)
- Ranked #5,257 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yejinlei/excel-parser-skill --skill excel-parserAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 80 |
|---|---|
| Last updated | March 14, 2026 |
| Repository | yejinlei/excel-parser-skill ↗ |
What it does
Helps with ai & agent building tasks.
Files
Excel Parser Skill
Excel Parser技能用于从Excel文件中提取内容和写入内容,支持多种Excel格式。
Compatibility
- Python 3.7+
- 依赖:
python-dotenv,python-calamine - 备选依赖:
xlwings(用于所有Excel格式)
使用方法
基本使用
from excel_parser import ExcelParser, process_excel, write_excel_file, update_excel_file
# 方法1: 使用ExcelParser类
parser = ExcelParser()
# 读取Excel文件
result = parser.parse_excel('path/to/file.xlsx')
# 获取文本格式输出
text = parser.parse_excel_to_text('path/to/file.xlsx')
# 写入Excel文件
write_data = {
"sheets": [
{
"name": "Sheet1",
"rows": [["A1", "B1"], ["A2", "B2"]],
"merged_cells": [
{
"start_row": 0,
"end_row": 0,
"start_col": 0,
"end_col": 1
}
]
}
]
}
parser.write_excel('output.xlsx', write_data)
# 更新Excel文件
parser.update_excel('existing_file.xlsx', write_data)
# 方法2: 使用便捷函数
# 读取Excel文件
result = process_excel('path/to/file.xlsx')
# 写入Excel文件
write_result = write_excel_file('output.xlsx', write_data)
# 更新Excel文件
update_result = update_excel_file('existing_file.xlsx', write_data)返回结果格式
{
"text": "格式化的文本内容",
"sheets": [
{
"name": "Sheet1",
"rows": [["A1", "B1"], ["A2", "B2"]],
"row_count": 2,
"column_count": 2
}
],
"sheet_count": 1,
"total_cells": 4,
"engine": "python-calamine"
}支持的文件格式
- .xls (Excel 97-2003)
- .xlsx, .xlsm (Excel 2007+)
- .xltx, .xltm (Excel模板)
环境变量配置
创建 .env 文件:
# 最大行数限制,默认100行
EXCEL_MAX_ROWS=100
# 是否保留空行,默认false
EXCEL_KEEP_EMPTY_ROWS=false详细文档
更多使用示例和故障排除信息,参见 README.md。
# Excel解析器配置
# 最大行数限制,默认100行
# EXCEL_MAX_ROWS=100
# 是否保留空行,默认false
# EXCEL_KEEP_EMPTY_ROWS=false
name: Upload Python Package
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual Environment
venv/
ENV/
env/
# IDE
.vscode/
.idea/
# Environment variables
.env
# Test files
test/
tests/
*.log
Changelog
所有显著的变更都将记录在此文件中。
格式基于 Keep a Changelog, 并且本项目遵循 语义化版本。
[1.0.0] - 2026-03-02
新增
- 初始版本发布
- 支持 .xls、.xlsx、.xlsm、.xltx、.xltm 格式
- 使用 python-calamine 作为主要解析引擎
- 自动降级到 xlrd/openpyxl 作为备选
- 自动安装依赖功能
- 结构化数据输出
- 文本格式转换
- 命令行支持
特性
- 高性能Excel解析,基于Rust实现
- 多工作表支持
- 跨平台兼容(Windows、Linux、macOS)
- 智能引擎选择
- 完善的错误处理
[Unreleased]
变更
- 将备选引擎从 xlrd 替换为 xlwings,提供更好的兼容性
- 移除 openpyxl 依赖,统一使用 xlwings 作为备选引擎
计划
- [ ] 支持更多Excel格式
- [ ] 添加数据验证功能
- [ ] 支持公式计算
- [ ] 添加单元格格式信息
- [ ] 支持图片提取
MIT License
Copyright (c) 2026 Excel Parser Skill Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
include README.md
include LICENSE.txt
include SKILL.md
include requirements.txt
include .env.example
recursive-include scripts *.py
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
Excel Parser Skill
  
Excel内容解析技能,使用 python-calamine 库提取Excel文件内容。支持多种Excel格式,包括旧版的 .xls 和新版的 .xlsx、.xlsm 等。
✨ 功能特性
- 🚀 高性能: 基于Rust的python-calamine库,解析速度极快
- 📊 多格式支持: 支持 .xls、.xlsx、.xlsm、.xltx、.xltm 格式
- 🔄 自动降级: 当python-calamine失败时,自动使用xlwings
- 📦 自动安装: 缺少依赖时自动尝试安装
- 📝 结构化输出: 提供完整的工作表结构和文本格式结果
- 🌐 跨平台: 支持Windows、Linux、macOS
📦 安装
从 PyPI 安装
pip install excel-parser-skill从源码安装
git clone https://github.com/yourusername/excel-parser-skill.git
cd excel-parser-skill
pip install -e .🚀 快速开始
基本使用
from excel_parser import ExcelParser
# 创建解析器实例
parser = ExcelParser()
# 解析Excel文件
result = parser.parse_excel('path/to/your/file.xlsx')
# 查看结果
print(f"工作表数量: {result['sheet_count']}")
print(f"总单元格数: {result['total_cells']}")
print(f"使用引擎: {result['engine']}")
# 查看工作表数据
for sheet in result['sheets']:
print(f"\n工作表: {sheet['name']}")
print(f"行数: {sheet['row_count']}, 列数: {sheet['column_count']}")转换为文本格式
from excel_parser import ExcelParser
parser = ExcelParser()
text = parser.parse_excel_to_text('path/to/your/file.xls')
print(text)使用主函数
from excel_parser import process_excel
result = process_excel('path/to/your/file.xlsx')
print(result['text'])命令行使用
python -m excel_parser your_file.xlsx📖 详细文档
详细的使用文档请查看 SKILL.md
🛠️ 支持的文件格式
| 格式 | 扩展名 | 支持状态 |
|---|---|---|
| Excel 97-2003 | .xls | ✅ 支持 |
| Excel 2007+ | .xlsx | ✅ 支持 |
| Excel 宏 | .xlsm | ✅ 支持 |
| Excel 模板 | .xltx, .xltm | ✅ 支持 |
📤 输出格式
结构化数据
{
"text": "解析的文本内容",
"sheets": [
{
"name": "Sheet1",
"rows": [["A1", "B1"], ["A2", "B2"]],
"row_count": 2,
"column_count": 2
}
],
"sheet_count": 1,
"total_cells": 4,
"engine": "python-calamine"
}文本格式
=== Excel文件: example.xlsx ===
工作表数量: 1
总单元格数: 4
使用引擎: python-calamine
--- 工作表: Sheet1 ---
行数: 2, 列数: 2
1: A1 B1
2: A2 B2🔧 故障排除
常见问题
Q: 安装失败怎么办?
A: 确保Python版本>=3.7,并尝试:
pip install --upgrade pip
pip install excel-parser-skillQ: 解析失败怎么办?
A: 检查文件是否损坏,或尝试使用备用引擎:
# 会自动降级到xlwings
result = parser.parse_excel('file.xls')Q: 支持哪些Python版本?
A: 支持Python 3.7及以上版本。
🤝 贡献
欢迎提交Issue和Pull Request!
1. Fork 本仓库 2. 创建你的特性分支 (git checkout -b feature/AmazingFeature) 3. 提交你的修改 (git commit -m 'Add some AmazingFeature') 4. 推送到分支 (git push origin feature/AmazingFeature) 5. 打开一个 Pull Request
📄 许可证
本项目采用 MIT 许可证。
🙏 致谢
- python-calamine - 高性能Excel解析库
- xlwings - Excel文件读写支持
📞 联系方式
- GitHub Issues: https://github.com/yourusername/excel-parser-skill/issues
- Email: your.email@example.com
---
如果这个项目对你有帮助,请给个 ⭐️ Star!
python-dotenv
python-calamine
xlwings
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from .excel_parser import ExcelParser, process_excel
__all__ = ['ExcelParser', 'process_excel']
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Excel内容解析脚本
支持多种Excel格式的内容提取,使用python-calamine库
"""
import os
import sys
from typing import Dict, Any, List, Optional
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
def install_dependency(package):
"""自动安装缺失的依赖"""
import subprocess
print(f"正在安装依赖: {package}")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", package])
print(f"依赖 {package} 安装成功")
return True
except subprocess.CalledProcessError as e:
print(f"依赖 {package} 安装失败: {e}")
return False
class ExcelParser:
"""Excel文件解析器"""
def __init__(self):
"""初始化Excel解析器"""
self.calamine = None
self._init_engine()
# 加载环境变量配置
self.max_rows = int(os.getenv('EXCEL_MAX_ROWS', 100))
self.keep_empty_rows = os.getenv('EXCEL_KEEP_EMPTY_ROWS', 'false').lower() == 'true'
def _init_engine(self):
"""初始化解析引擎"""
try:
from python_calamine import CalamineWorkbook
self.calamine = CalamineWorkbook
except ImportError:
print("Calamine依赖未安装,正在尝试自动安装...")
if install_dependency("python-calamine"):
try:
from python_calamine import CalamineWorkbook
self.calamine = CalamineWorkbook
except ImportError:
raise Exception("Calamine依赖安装失败,请手动安装: pip install python-calamine")
else:
raise Exception("Calamine依赖安装失败,请手动安装: pip install python-calamine")
def parse_excel(self, excel_path: str) -> Dict[str, Any]:
"""
解析Excel文件内容
Args:
excel_path: Excel文件路径
Returns:
包含解析结果的字典
"""
result = {
"sheets": [],
"sheet_count": 0,
"total_cells": 0,
"engine": "python-calamine"
}
try:
# 使用python-calamine解析Excel文件
workbook = self.calamine.from_path(excel_path)
# 获取所有工作表名称
sheet_names = workbook.sheet_names
result["sheet_count"] = len(sheet_names)
# 解析每个工作表
for idx, sheet_name in enumerate(sheet_names):
sheet_data = {
"name": sheet_name,
"rows": [],
"row_count": 0,
"column_count": 0,
"merged_cells": []
}
# 获取工作表数据
sheet = workbook.get_sheet_by_index(idx)
if sheet:
# 读取所有行 - 使用to_python()方法获取数据
try:
# 尝试使用to_python()方法
data = sheet.to_python()
rows = []
for row in data:
# 处理行数据
row_data = []
for cell in row:
# 转换单元格值
if cell is None:
row_data.append("")
elif isinstance(cell, str):
row_data.append(cell.strip())
else:
row_data.append(str(cell))
rows.append(row_data)
except AttributeError:
# 如果to_python()不可用,尝试直接访问
rows = []
# 获取工作表的行数和列数
try:
# 尝试遍历所有单元格
row_idx = 0
while True:
try:
row_data = []
col_idx = 0
while True:
try:
cell = sheet.get_cell(row_idx, col_idx)
if cell is None:
row_data.append("")
elif isinstance(cell, str):
row_data.append(cell.strip())
else:
row_data.append(str(cell))
col_idx += 1
except:
break
if row_data:
rows.append(row_data)
row_idx += 1
except:
break
except Exception as e2:
print(f"直接访问单元格失败: {e2}")
raise
# 计算行数和列数
if rows:
sheet_data["rows"] = rows
sheet_data["row_count"] = len(rows)
sheet_data["column_count"] = len(rows[0]) if rows[0] else 0
result["total_cells"] += sheet_data["row_count"] * sheet_data["column_count"]
result["sheets"].append(sheet_data)
except Exception as e:
# 如果python-calamine失败,尝试使用xlwings
print(f"python-calamine解析失败,尝试使用xlwings: {e}")
result = self._parse_with_fallback(excel_path)
return result
def _parse_with_fallback(self, excel_path: str) -> Dict[str, Any]:
"""
使用xlwings作为备选解析方案
"""
result = {
"sheets": [],
"sheet_count": 0,
"total_cells": 0,
"engine": "xlwings"
}
try:
import xlwings as xw
# 使用不可见模式打开Excel
app = xw.App(visible=False)
try:
workbook = app.books.open(excel_path)
# 获取所有工作表
sheet_names = [sheet.name for sheet in workbook.sheets]
result["sheet_count"] = len(sheet_names)
# 解析每个工作表
for sheet in workbook.sheets:
sheet_data = {
"name": sheet.name,
"rows": [],
"row_count": 0,
"column_count": 0
}
# 获取工作表数据
rows = []
# 获取已使用的范围
used_range = sheet.used_range
if used_range:
# 获取行数和列数
row_count = used_range.rows.count
col_count = used_range.columns.count
# 读取所有数据
for row_idx in range(row_count):
row_data = []
for col_idx in range(col_count):
cell = sheet.cells(row_idx + 1, col_idx + 1)
value = cell.value
# 转换单元格值
if value is None:
row_data.append("")
elif isinstance(value, str):
row_data.append(value.strip())
else:
row_data.append(str(value))
rows.append(row_data)
# 计算行数和列数
if rows:
sheet_data["rows"] = rows
sheet_data["row_count"] = len(rows)
sheet_data["column_count"] = len(rows[0]) if rows[0] else 0
result["total_cells"] += sheet_data["row_count"] * sheet_data["column_count"]
result["sheets"].append(sheet_data)
# 关闭工作簿
workbook.close()
finally:
# 退出Excel应用
app.quit()
except ImportError:
print("xlwings依赖未安装,正在尝试自动安装...")
if install_dependency("xlwings"):
# 重新导入并处理
import xlwings as xw
# 使用不可见模式打开Excel
app = xw.App(visible=False)
try:
workbook = app.books.open(excel_path)
# 获取所有工作表
sheet_names = [sheet.name for sheet in workbook.sheets]
result["sheet_count"] = len(sheet_names)
# 解析每个工作表
for sheet in workbook.sheets:
sheet_data = {
"name": sheet.name,
"rows": [],
"row_count": 0,
"column_count": 0
}
# 获取工作表数据
rows = []
# 获取已使用的范围
used_range = sheet.used_range
if used_range:
# 获取行数和列数
row_count = used_range.rows.count
col_count = used_range.columns.count
# 读取所有数据
for row_idx in range(row_count):
row_data = []
for col_idx in range(col_count):
cell = sheet.cells(row_idx + 1, col_idx + 1)
value = cell.value
# 转换单元格值
if value is None:
row_data.append("")
elif isinstance(value, str):
row_data.append(value.strip())
else:
row_data.append(str(value))
rows.append(row_data)
# 计算行数和列数
if rows:
sheet_data["rows"] = rows
sheet_data["row_count"] = len(rows)
sheet_data["column_count"] = len(rows[0]) if rows[0] else 0
result["total_cells"] += sheet_data["row_count"] * sheet_data["column_count"]
result["sheets"].append(sheet_data)
# 关闭工作簿
workbook.close()
finally:
# 退出Excel应用
app.quit()
else:
raise Exception("xlwings依赖安装失败,请手动安装: pip install xlwings")
except Exception as e:
raise Exception(f"Excel解析失败: {str(e)}")
return result
def parse_excel_to_text(self, excel_path: str) -> str:
"""
将Excel文件解析为文本格式
Args:
excel_path: Excel文件路径
Returns:
解析后的文本
"""
try:
result = self.parse_excel(excel_path)
text_parts = []
text_parts.append(f"=== Excel文件: {os.path.basename(excel_path)} ===")
text_parts.append(f"工作表数量: {result['sheet_count']}")
text_parts.append(f"总单元格数: {result['total_cells']}")
text_parts.append(f"使用引擎: {result['engine']}")
text_parts.append("")
# 处理每个工作表
for sheet in result['sheets']:
text_parts.append(f"--- 工作表: {sheet['name']} ---")
text_parts.append(f"行数: {sheet['row_count']}, 列数: {sheet['column_count']}")
if 'merged_cells' in sheet and sheet['merged_cells']:
text_parts.append(f"合并单元格数量: {len(sheet['merged_cells'])}")
text_parts.append("")
# 输出数据,使用配置的最大行数限制
max_rows = min(sheet['row_count'], self.max_rows)
for i, row in enumerate(sheet['rows'][:max_rows]):
# 根据配置决定是否保留空行
if self.keep_empty_rows or any(cell.strip() for cell in row):
row_text = "\t".join(row)
text_parts.append(f"{i+1}: {row_text}")
# 如果有更多行,提示
if sheet['row_count'] > self.max_rows:
text_parts.append(f"... 还有 {sheet['row_count'] - self.max_rows} 行未显示")
text_parts.append("")
return "\n".join(text_parts)
except Exception as e:
return f"【Excel文件处理失败: {str(e)}】"
def write_excel(self, output_path: str, data: Dict[str, Any]) -> bool:
"""
写入Excel文件
Args:
output_path: 输出文件路径
data: 要写入的数据,格式如下:
{
"sheets": [
{
"name": "Sheet1",
"rows": [["A1", "B1"], ["A2", "B2"]],
"merged_cells": [
{
"start_row": 0,
"end_row": 0,
"start_col": 0,
"end_col": 1
}
]
}
]
}
Returns:
是否写入成功
"""
try:
import xlwings as xw
# 使用不可见模式打开Excel
app = xw.App(visible=False)
try:
# 创建新工作簿
workbook = app.books.add()
# 处理数据
sheets_data = data.get('sheets', [])
if not sheets_data:
# 如果没有提供数据,使用默认工作表
workbook.sheets[0].name = "Sheet1"
else:
# 删除默认工作表
if len(workbook.sheets) > 1:
workbook.sheets[0].delete()
# 创建新工作表
for sheet_data in sheets_data:
sheet_name = sheet_data.get('name', 'Sheet')
rows = sheet_data.get('rows', [])
merged_cells = sheet_data.get('merged_cells', [])
# 检查工作表是否存在
sheet = None
for existing_sheet in workbook.sheets:
if existing_sheet.name == sheet_name:
sheet = existing_sheet
break
if not sheet:
# 创建新工作表
sheet = workbook.sheets.add(after=workbook.sheets[-1])
sheet.name = sheet_name
# 写入数据
for row_idx, row in enumerate(rows):
for col_idx, cell_value in enumerate(row):
sheet.range((row_idx + 1, col_idx + 1)).value = cell_value
# 处理合并单元格
for merged_cell in merged_cells:
start_row = merged_cell.get('start_row', 0) + 1
end_row = merged_cell.get('end_row', 0) + 1
start_col = merged_cell.get('start_col', 0) + 1
end_col = merged_cell.get('end_col', 0) + 1
if start_row <= end_row and start_col <= end_col:
start_cell = (start_row, start_col)
end_cell = (end_row, end_col)
sheet.range(start_cell, end_cell).api.merge()
# 保存文件
workbook.save(output_path)
workbook.close()
return True
finally:
# 退出Excel应用
app.quit()
except Exception as e:
print(f"写入Excel文件失败: {e}")
import traceback
traceback.print_exc()
return False
def update_excel(self, excel_path: str, data: Dict[str, Any]) -> bool:
"""
更新现有Excel文件
Args:
excel_path: 现有Excel文件路径
data: 要更新的数据,格式同write_excel
Returns:
是否更新成功
"""
try:
import xlwings as xw
# 使用不可见模式打开Excel
app = xw.App(visible=False)
try:
# 打开现有工作簿
workbook = app.books.open(excel_path)
# 处理数据
sheets_data = data.get('sheets', [])
for sheet_data in sheets_data:
sheet_name = sheet_data.get('name')
rows = sheet_data.get('rows', [])
merged_cells = sheet_data.get('merged_cells', [])
if sheet_name:
# 检查工作表是否存在
sheet = None
for existing_sheet in workbook.sheets:
if existing_sheet.name == sheet_name:
sheet = existing_sheet
break
if not sheet:
# 创建新工作表
sheet = workbook.sheets.add(after=workbook.sheets[-1])
sheet.name = sheet_name
# 清空现有数据(可选)
# sheet.clear()
# 写入数据
for row_idx, row in enumerate(rows):
for col_idx, cell_value in enumerate(row):
sheet.range((row_idx + 1, col_idx + 1)).value = cell_value
# 处理合并单元格
for merged_cell in merged_cells:
start_row = merged_cell.get('start_row', 0) + 1
end_row = merged_cell.get('end_row', 0) + 1
start_col = merged_cell.get('start_col', 0) + 1
end_col = merged_cell.get('end_col', 0) + 1
if start_row <= end_row and start_col <= end_col:
start_cell = (start_row, start_col)
end_cell = (end_row, end_col)
sheet.range(start_cell, end_cell).api.merge()
# 保存文件
workbook.save()
workbook.close()
return True
finally:
# 退出Excel应用
app.quit()
except Exception as e:
print(f"更新Excel文件失败: {e}")
import traceback
traceback.print_exc()
return False
def process_excel(excel_path: str) -> Dict[str, Any]:
"""
处理Excel文件的主函数
Args:
excel_path: Excel文件路径
Returns:
包含text、sheets和sheet_count的字典
"""
parser = ExcelParser()
excel_data = parser.parse_excel(excel_path)
text = parser.parse_excel_to_text(excel_path)
return {
"text": text,
"sheets": excel_data["sheets"],
"sheet_count": excel_data["sheet_count"],
"total_cells": excel_data["total_cells"],
"engine": excel_data["engine"]
}
def write_excel_file(output_path: str, data: Dict[str, Any]) -> Dict[str, Any]:
"""
写入Excel文件的主函数
Args:
output_path: 输出文件路径
data: 要写入的数据
Returns:
包含success和message的字典
"""
parser = ExcelParser()
success = parser.write_excel(output_path, data)
if success:
return {
"success": True,
"message": f"Excel文件已成功写入: {output_path}",
"file_path": output_path
}
else:
return {
"success": False,
"error": f"写入Excel文件失败: {output_path}"
}
def update_excel_file(excel_path: str, data: Dict[str, Any]) -> Dict[str, Any]:
"""
更新Excel文件的主函数
Args:
excel_path: 现有Excel文件路径
data: 要更新的数据
Returns:
包含success和message的字典
"""
parser = ExcelParser()
success = parser.update_excel(excel_path, data)
if success:
return {
"success": True,
"message": f"Excel文件已成功更新: {excel_path}",
"file_path": excel_path
}
else:
return {
"success": False,
"error": f"更新Excel文件失败: {excel_path}"
}
def main(input_data: Dict[str, Any] = None) -> Dict[str, Any]:
"""SKILL 入口点"""
if input_data is None:
input_data = {}
# 确定操作类型
action = input_data.get('action', 'read').lower()
if action == 'read':
# 读取Excel文件
# 支持多种参数名称,提高兼容性
excel_path = input_data.get('file_path', '') or input_data.get('file', '')
if not excel_path:
return {"success": False, "error": "Excel file path is required"}
try:
result = process_excel(excel_path)
return {"success": True, "result": result}
except Exception as e:
return {"success": False, "error": f"Excel processing failed: {str(e)}"}
elif action == 'write':
# 写入Excel文件
output_path = input_data.get('output_path', '') or input_data.get('file_path', '') or input_data.get('file', '')
data = input_data.get('data', {})
if not output_path:
return {"success": False, "error": "Output file path is required"}
if not data.get('sheets'):
return {"success": False, "error": "Excel data is required"}
try:
result = write_excel_file(output_path, data)
if result['success']:
return {"success": True, "result": result}
else:
return {"success": False, "error": result.get('error', 'Write failed')}
except Exception as e:
return {"success": False, "error": f"Excel write failed: {str(e)}"}
elif action == 'update':
# 更新Excel文件
excel_path = input_data.get('file_path', '') or input_data.get('file', '')
data = input_data.get('data', {})
if not excel_path:
return {"success": False, "error": "Excel file path is required"}
if not data.get('sheets'):
return {"success": False, "error": "Excel data is required"}
try:
result = update_excel_file(excel_path, data)
if result['success']:
return {"success": True, "result": result}
else:
return {"success": False, "error": result.get('error', 'Update failed')}
except Exception as e:
return {"success": False, "error": f"Excel update failed: {str(e)}"}
else:
return {"success": False, "error": f"Invalid action: {action}. Supported actions: read, write, update"}
if __name__ == "__main__":
# 测试代码
if len(sys.argv) > 1:
action = sys.argv[1]
if action == 'read':
# 测试读取Excel文件
if len(sys.argv) > 2:
excel_path = sys.argv[2]
else:
print("使用方法: python excel_parser.py read <excel_file_path>")
sys.exit(1)
if not os.path.exists(excel_path):
print(f"文件不存在: {excel_path}")
sys.exit(1)
try:
result = process_excel(excel_path)
print(f"Excel解析完成,共 {result['sheet_count']} 个工作表")
print(f"总单元格数: {result['total_cells']}")
print(f"使用引擎: {result['engine']}")
print("\n解析结果:")
print(result['text'])
except Exception as e:
print(f"处理失败: {e}")
sys.exit(1)
elif action == 'write':
# 测试写入Excel文件
if len(sys.argv) > 2:
output_path = sys.argv[2]
else:
print("使用方法: python excel_parser.py write <output_file_path>")
sys.exit(1)
try:
test_data = {
"sheets": [
{
"name": "测试工作表",
"rows": [
["姓名", "年龄", "城市"],
["张三", 25, "北京"],
["李四", 30, "上海"],
["王五", 35, "广州"]
],
"merged_cells": [
{
"start_row": 0,
"end_row": 0,
"start_col": 0,
"end_col": 2
}
]
}
]
}
result = write_excel_file(output_path, test_data)
if result['success']:
print(f"Excel文件写入成功: {result['file_path']}")
else:
print(f"Excel文件写入失败: {result['error']}")
except Exception as e:
print(f"写入失败: {e}")
sys.exit(1)
elif action == 'update':
# 测试更新Excel文件
if len(sys.argv) > 3:
excel_path = sys.argv[2]
output_path = sys.argv[3]
else:
print("使用方法: python excel_parser.py update <input_file_path> <output_file_path>")
sys.exit(1)
if not os.path.exists(excel_path):
print(f"文件不存在: {excel_path}")
sys.exit(1)
try:
# 先读取文件
parser = ExcelParser()
excel_data = parser.parse_excel(excel_path)
# 修改数据
if excel_data['sheets']:
# 在第一个工作表中添加一行
excel_data['sheets'][0]['rows'].append(["赵六", 40, "深圳"])
# 写入到新文件
result = write_excel_file(output_path, excel_data)
if result['success']:
print(f"Excel文件更新成功: {result['file_path']}")
else:
print(f"Excel文件更新失败: {result['error']}")
except Exception as e:
print(f"更新失败: {e}")
sys.exit(1)
else:
print("支持的操作: read, write, update")
sys.exit(1)
else:
print("使用方法:")
print(" 读取Excel: python excel_parser.py read <excel_file_path>")
print(" 写入Excel: python excel_parser.py write <output_file_path>")
print(" 更新Excel: python excel_parser.py update <input_file_path> <output_file_path>")
sys.exit(1)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试SKILL入口点的写Excel功能
"""
from excel_parser import main
import json
# 测试数据
test_data = {
"action": "write",
"output_path": "test_skill_output.xlsx",
"data": {
"sheets": [
{
"name": "SKILL测试",
"rows": [
["标题"],
["数据1", "数据2"],
["数据3", "数据4"]
]
}
]
}
}
# 调用SKILL入口点
result = main(test_data)
# 打印结果
print(json.dumps(result, ensure_ascii=False, indent=2))
# 验证文件是否生成
import os
if os.path.exists("test_skill_output.xlsx"):
print("\n文件已成功生成!")
else:
print("\n文件生成失败!")
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages
with open('README.md', 'r', encoding='utf-8') as f:
long_description = f.read()
with open('requirements.txt', 'r', encoding='utf-8') as f:
requirements = f.read().splitlines()
setup(
name='excel-parser-skill',
version='1.2.0',
description='Excel content parsing skill using calamine library',
long_description=long_description,
long_description_content_type='text/markdown',
author='Excel Parser Skill Team',
author_email='',
url='',
packages=find_packages(),
package_data={
'': ['*.md', '*.txt', '*.env.example'],
},
include_package_data=True,
install_requires=requirements,
extras_require={
'dev': [
'pytest',
'black',
'flake8',
],
},
classifiers=[
'Programming Language :: Python :: 3',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
],
python_requires='>=3.7',
entry_points={
'console_scripts': [
'excel-parser=scripts.excel_parser:main',
],
},
)
Excel Parser Skill 发布指南
通过npx skills add安装
发布到GitHub后,用户可以通过以下命令安装:
基本安装
# 从GitHub仓库安装
npx skills add yejinlei/excel-parser-skill
# 或者使用完整URL
npx skills add https://github.com/yejinlei/excel-parser-skill指定技能安装
# 只安装excel-parser技能
npx skills add yejinlei/excel-parser-skill --skill excel-parser全局安装
# 安装到全局目录
npx skills add yejinlei/excel-parser-skill --global非交互式安装(CI/CD友好)
# 跳过确认提示
npx skills add yejinlei/excel-parser-skill --yes发布步骤
1. 创建GitHub仓库
1. 在GitHub上创建新仓库:excel-parser-skill 2. 将excel-parser目录内容推送到仓库
2. 推送代码
# 进入项目目录
cd src/public/skills/skills/excel-parser
# 初始化Git仓库(如果还没有)
git init
# 添加所有文件
git add .
# 提交
git commit -m "Initial release: Excel Parser Skill v1.0.0"
# 推送到GitHub
git push -u origin main3. 创建Release
1. 在GitHub仓库页面,点击右侧的 "Releases" 2. 点击 "Create a new release" 3. 填写发布信息:
- Tag version:
v1.0.0 - Release title:
Excel Parser Skill v1.0.0 - 描述:复制CHANGELOG内容
4. 点击 "Publish release"
发布到 PyPI
1. 注册 PyPI 账号
访问 https://pypi.org/ 注册账号
2. 创建 API Token
1. 登录 PyPI 2. 进入 Account Settings 3. 在 API tokens 部分点击 "Add API token" 4. 填写 Token 名称,选择 Scope 为 "Entire account" 5. 复制生成的 Token
3. 配置 GitHub Secrets
1. 在GitHub仓库页面,点击 "Settings" 2. 选择左侧 "Secrets and variables" -> "Actions" 3. 点击 "New repository secret" 4. 添加 Secret:
- Name:
PYPI_API_TOKEN - Value: 刚才复制的 PyPI API Token
4. 自动发布
创建 Release 后,GitHub Actions 会自动: 1. 构建Python包 2. 发布到 PyPI
验证发布
1. 检查 GitHub Release
- 访问 https://github.com/yejinlei/excel-parser-skill/releases
- 确认 Release 信息正确
2. 检查 PyPI
- 访问 https://pypi.org/project/excel-parser-skill/
- 确认包已上传
3. 测试安装
# 通过npx skills add安装
npx skills add yejinlei/excel-parser-skill
# 或通过pip安装
pip install excel-parser-skill后续维护
更新版本
1. 修改代码 2. 更新版本号 3. 更新 CHANGELOG 4. 提交并推送 5. 创建新的 Release
处理问题
- 在 GitHub Issues 中跟踪问题
- 及时回复用户反馈
- 定期更新依赖
联系方式
- GitHub Issues: https://github.com/yejinlei/excel-parser-skill/issues
- Email: your.email@example.com
Excel Parser Skill 发布检查清单
目录结构检查
excel-parser/
├── SKILL.md ✅ 技能说明文档(必需)
├── LICENSE.txt ✅ 许可证文件
├── README.md ✅ 项目说明文档
├── requirements.txt ✅ 依赖文件
├── setup.py ✅ Python包设置文件
├── MANIFEST.in ✅ 包清单文件
├── .gitignore ✅ Git忽略文件
├── CHANGELOG.md ✅ 变更日志
├── .env.example ✅ 环境变量示例
├── .github/ ✅ GitHub配置
│ └── workflows/
│ └── python-publish.yml ✅ 自动发布工作流
└── scripts/ ✅ 脚本目录
├── __init__.py ✅ Python包初始化文件
└── excel_parser.py ✅ Excel解析脚本发布要求检查
必需文件
- ✅ SKILL.md - 技能说明文档
- ✅ LICENSE.txt - 许可证文件
- ✅ README.md - 项目说明文档
- ✅ requirements.txt - 依赖文件
- ✅ scripts/__init__.py - Python包初始化文件
可选但推荐文件
- ✅ setup.py - Python包设置文件
- ✅ MANIFEST.in - 包清单文件
- ✅ .gitignore - Git忽略文件
- ✅ CHANGELOG.md - 变更日志
- ✅ .env.example - 环境变量示例
- ✅ .github/workflows/python-publish.yml - 自动发布工作流
代码质量检查
- ✅ 无内部依赖(不依赖anthropics_skills)
- ✅ 完整的错误处理
- ✅ 清晰的文档说明
- ✅ 支持多种文件格式
- ✅ 环境变量配置说明
- ✅ 自动安装依赖功能
文档质量检查
- ✅ 功能特性描述清晰
- ✅ 使用方法详细完整
- ✅ 输入输出格式说明
- ✅ 依赖要求明确
- ✅ 环境变量配置说明
- ✅ 注意事项和使用场景
- ✅ 故障排除指南
发布步骤
1. 测试
- [ ] 本地测试通过
- [ ] 所有示例代码可运行
- [ ] 错误处理正常工作
2. 文档
- [ ] README.md 完整
- [ ] SKILL.md 完整
- [ ] CHANGELOG.md 更新
- [ ] 版本号一致
3. GitHub
- [ ] 代码推送到GitHub
- [ ] 创建Release
- [ ] 配置GitHub Secrets
4. PyPI
- [ ] 注册PyPI账号
- [ ] 创建API Token
- [ ] 自动发布成功
5. 验证
- [ ] npx skills add 安装成功
- [ ] pip install 安装成功
- [ ] 功能测试通过
安装测试
# 测试npx skills add安装
npx skills add yejinlei/excel-parser-skill --yes
# 测试pip安装
pip install excel-parser-skill
# 测试导入
python -c "from excel_parser import ExcelParser; print('Success!')"