Add excel-to-markdown skill and converter script

- Add excel_to_markdown.py script for converting Excel files to Markdown tables
- Create excel-to-markdown skill with SKILL.md documentation
- Support automatic data range detection and flexible output options
- Include features for row/column numbering and partial conversions
- Add skill-creator reference documentation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Misaka Company
2026-01-27 12:54:34 +08:00
commit b017e36753
4 changed files with 604 additions and 0 deletions

View File

@@ -0,0 +1,220 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Excel to Markdown Converter
将Excel文档转换为Markdown表格格式
"""
import openpyxl
from openpyxl.utils import get_column_letter
from typing import Optional, Tuple
import argparse
class ExcelToMarkdown:
"""Excel转Markdown转换器"""
def __init__(self, excel_file: str):
"""
初始化转换器
Args:
excel_file: Excel文件路径
"""
self.workbook = openpyxl.load_workbook(excel_file, data_only=True)
self.sheet = self.workbook.active
def detect_data_range(self, max_scan_rows: int = 100, max_scan_cols: int = 100) -> Tuple[int, int]:
"""
自动检测数据范围
Args:
max_scan_rows: 最大扫描行数
max_scan_cols: 最大扫描列数
Returns:
(最大行号, 最大列号)
"""
max_row = 0
max_col = 0
# 扫描前100行和前100列
scan_rows = min(max_scan_rows, self.sheet.max_row)
scan_cols = min(max_scan_cols, self.sheet.max_column)
for row in range(1, scan_rows + 1):
for col in range(1, scan_cols + 1):
cell_value = self.sheet.cell(row=row, column=col).value
if cell_value is not None and str(cell_value).strip() != "":
max_row = max(max_row, row)
max_col = max(max_col, col)
return max_row, max_col
def convert(self,
max_rows: Optional[int] = None,
max_cols: Optional[int] = None,
show_row_numbers: bool = False,
show_col_numbers: bool = False,
start_row: int = 1,
start_col: int = 1) -> str:
"""
转换Excel为Markdown格式
Args:
max_rows: 最大行数None表示自动检测
max_cols: 最大列数None表示自动检测
show_row_numbers: 是否显示行号
show_col_numbers: 是否显示列号(字母形式)
start_row: 起始行号默认1
start_col: 起始列号默认1
Returns:
Markdown格式的表格字符串
"""
# 自动检测数据范围
if max_rows is None or max_cols is None:
detected_rows, detected_cols = self.detect_data_range()
if max_rows is None:
max_rows = detected_rows
if max_cols is None:
max_cols = detected_cols
# 确保至少有1行1列
if max_rows < 1 or max_cols < 1:
return "| 无数据 |\n|--------|\n"
# 计算实际的结束位置
end_row = min(start_row + max_rows - 1, self.sheet.max_row)
end_col = min(start_col + max_cols - 1, self.sheet.max_column)
markdown_lines = []
# 构建列号行(如果需要)
if show_col_numbers:
header_parts = []
if show_row_numbers:
header_parts.append("") # 行号列的占位
for col in range(start_col, end_col + 1):
col_letter = get_column_letter(col)
header_parts.append(col_letter)
markdown_lines.append("| " + " | ".join(header_parts) + " |")
# 分隔线
separator_parts = ["---"] * len(header_parts)
markdown_lines.append("| " + " | ".join(separator_parts) + " |")
# 构建数据行
for row in range(start_row, end_row + 1):
row_parts = []
# 添加行号(如果需要)
if show_row_numbers:
row_parts.append(str(row))
# 添加单元格数据
for col in range(start_col, end_col + 1):
cell_value = self.sheet.cell(row=row, column=col).value
# 处理空值
if cell_value is None:
cell_str = ""
else:
cell_str = str(cell_value).strip()
# 转义Markdown特殊字符
cell_str = cell_str.replace("|", "\\|")
cell_str = cell_str.replace("\n", "<br>")
row_parts.append(cell_str)
markdown_lines.append("| " + " | ".join(row_parts) + " |")
# 如果是第一行且没有显示列号,添加分隔线
if row == start_row and not show_col_numbers:
separator_parts = ["---"] * len(row_parts)
markdown_lines.append("| " + " | ".join(separator_parts) + " |")
return "\n".join(markdown_lines)
def save_to_file(self, markdown_text: str, output_file: str):
"""
保存Markdown到文件
Args:
markdown_text: Markdown文本
output_file: 输出文件路径
"""
with open(output_file, 'w', encoding='utf-8') as f:
f.write(markdown_text)
def close(self):
"""关闭工作簿"""
self.workbook.close()
def main():
"""命令行入口"""
parser = argparse.ArgumentParser(
description='将Excel文档转换为Markdown表格格式',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
# 自动检测范围并转换
python excel_to_markdown.py input.xlsx -o output.md
# 指定转换前10行、前5列
python excel_to_markdown.py input.xlsx -o output.md -r 10 -c 5
# 显示行号和列号
python excel_to_markdown.py input.xlsx -o output.md --show-rows --show-cols
# 从第2行第2列开始转换5行3列
python excel_to_markdown.py input.xlsx -o output.md -r 5 -c 3 --start-row 2 --start-col 2
"""
)
parser.add_argument('input_file', help='输入的Excel文件路径')
parser.add_argument('-o', '--output', help='输出的Markdown文件路径不指定则输出到控制台')
parser.add_argument('-r', '--max-rows', type=int, help='最大转换行数(不指定则自动检测)')
parser.add_argument('-c', '--max-cols', type=int, help='最大转换列数(不指定则自动检测)')
parser.add_argument('--show-rows', action='store_true', help='显示行号')
parser.add_argument('--show-cols', action='store_true', help='显示列号(字母形式)')
parser.add_argument('--start-row', type=int, default=1, help='起始行号默认1')
parser.add_argument('--start-col', type=int, default=1, help='起始列号默认1')
args = parser.parse_args()
try:
# 创建转换器
converter = ExcelToMarkdown(args.input_file)
# 执行转换
markdown_text = converter.convert(
max_rows=args.max_rows,
max_cols=args.max_cols,
show_row_numbers=args.show_rows,
show_col_numbers=args.show_cols,
start_row=args.start_row,
start_col=args.start_col
)
# 输出结果
if args.output:
converter.save_to_file(markdown_text, args.output)
print(f"✓ 转换完成!已保存到: {args.output}")
else:
print(markdown_text)
# 关闭工作簿
converter.close()
except FileNotFoundError:
print(f"✗ 错误: 找不到文件 '{args.input_file}'")
except Exception as e:
print(f"✗ 错误: {str(e)}")
if __name__ == "__main__":
main()