Files
claudeskill/demo_scripts/excel_to_markdown.py
Misaka Company 06c4f8eafa Reorganize project structure: move scripts to demo_scripts
- Rename scripts/ directory to demo_scripts/ for clarity
- Move excel_to_markdown.py to demo_scripts/ directory
- This better reflects the purpose of these scripts as demonstration examples

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 15:06:01 +08:00

220 lines
7.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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()