Skill: xiaoheizp/ke-office-automation (version 1.1.0)

--- name: ke-office-automation description: 科特船长 - 办公自动化脚本，Excel/Word/文件批量处理 version: 1.0.0 metadata: {"openclaw": {"emoji": "🤖", "requires": {"bins": ["python3"]}}} --- # 办公自动化脚本 - 科特船长版 ## 功能说明 提供常用办公自动化脚本，包括： - Excel 自动汇总 - Word 批量处理 - 文件批量重命名 - PDF 合并/拆分 - 邮件自动发送 ## 使用场景 ### 财务/会计 - 多表格自动汇总 - 发票数据提取 - 银行流水整理 ### HR/行政 - 员工信息整理 - 考勤数据汇总 - 合同批量处理 ### 销售/运营 - 客户信息整理 - 订单数据汇总 - 报表自动生成 ### 通用场景 - 文件批量重命名 - 文件夹整理 - 数据格式转换 ## 使用方法 ```bash # Excel 汇总 clawhub run ke-office-automation --action excel-merge --input ./data/ --output ./merged.xlsx # Word 批量处理 clawhub run ke-office-automation --action word-batch --input ./docs/ --action-type replace --old "旧文本" --new "新文本" # 文件批量重命名 clawhub run ke-office-automation --action rename --input ./files/ --pattern "{date}_{original}" # PDF 合并 clawhub run ke-office-automation --action pdf-merge --input ./pdfs/ --output ./merged.pdf # 邮件自动发送 clawhub run ke-office-automation --action email-send --config ./email-config.json --data ./recipients.xlsx ``` ## 参数说明 | 参数 | 说明 | 必填 | |------|------|------| | `--action` | 操作类型 | 是 | | `--input` | 输入文件/文件夹路径 | 是 | | `--output` | 输出文件路径 | 条件必填 | | `--pattern` | 重命名模式 | 条件必填 | | `--config` | 配置文件路径 | 条件必填 | ## 可用操作 | 操作 | 说明 | 适用场景 | |------|------|----------| | excel-merge | 合并多个 Excel 文件 | 多表格汇总 | | excel-split | 拆分 Excel 文件 | 数据分发 | | word-batch | Word 批量处理 | 合同/通知批量修改 | | rename | 文件批量重命名 | 文件整理 | | pdf-merge | PDF 合并 | 报告合并 | | pdf-split | PDF 拆分 | 报告拆分 | | email-send | 邮件批量发送 | 通知/营销 | ## 定制服务 需要定制自动化脚本？ ### 服务类型 - **简单脚本**: ¥500-1000（单一功能） - **中等复杂**: ¥1000-3000（多步骤） - **系统级**: ¥3000+（完整流程） ### 典型案例 - 财务日报自动生成：¥1500 - 客户信息自动整理：¥1200 - 合同批量处理：¥2000 - 邮件营销自动化：¥1800 ### 服务流程 1. 需求沟通（免费） 2. 方案确认 3. 开发测试（1-3 天） 4. 交付培训 5. 售后支持（30 天免费） 联系：私信获取报价 ## 免费资源 提供以下免费脚本模板： - Excel 汇总脚本 - 文件重命名脚本 - PDF 合并脚本 GitHub: 待开源 ## 常见问题 **Q: 需要编程基础吗？** A: 不需要，按说明使用即可。 **Q: 支持 Mac/Windows 吗？** A: 都支持，需要安装 Python 3.8+ **Q: 数据安全吗？** A: 所有处理在本地完成，数据不会上传。 --- **作者**: 科特船长 **更多技能**: https://clawhub.ai/@xiaoheizp **定制咨询**: 私信获取报价

path: office_automation.py
content: #!/usr/bin/env python3
"""
办公自动化脚本 - 科特船长版
功能：Excel 合并/文件重命名/PDF 处理/Word 批量处理
"""

import os
import sys
import json
import shutil
from pathlib import Path
from datetime import datetime

def merge_excel_files(input_dir, output_file):
    """合并 Excel 文件"""
    print(f"📁 扫描目录：{input_dir}")
    
    input_path = Path(input_dir)
    if not input_path.exists():
        print(f"❌ 目录不存在：{input_dir}")
        return
    
    excel_files = list(input_path.glob("*.xlsx")) + list(input_path.glob("*.xls"))
    excel_files = sorted(excel_files)
    
    if not excel_files:
        print("❌ 未找到 Excel 文件")
        print("💡 提示：确保文件在指定目录中")
        return
    
    print(f"✅ 找到 {len(excel_files)} 个 Excel 文件:")
    for i, f in enumerate(excel_files, 1):
        print(f"   {i}. {f.name}")
    
    # 生成合并报告
    report = f"# Excel 合并报告\n\n"
    report += f"**扫描目录**: {input_dir}\n"
    report += f"**文件数量**: {len(excel_files)}\n"
    report += f"**扫描时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
    report += "## 文件列表\n\n"
    for f in excel_files:
        report += f"- {f.name}\n"
    
    # 尝试使用 pandas 合并
    try:
        import pandas as pd
        print("\n📊 使用 pandas 合并 Excel 文件...")
        
        all_data = []
        for f in excel_files:
            try:
                df = pd.read_excel(f)
                df['源文件'] = f.name
                all_data.append(df)
                print(f"   ✅ {f.name}: {len(df)} 行")
            except Exception as e:
                print(f"   ⚠️ {f.name}: 读取失败 - {e}")
        
        if all_data:
            merged_df = pd.concat(all_data, ignore_index=True)
            
            # 输出文件
            if output_file.endswith('.xlsx'):
                merged_df.to_excel(output_file, index=False)
            elif output_file.endswith('.csv'):
                merged_df.to_csv(output_file, index=False, encoding='utf-8-sig')
            else:
                output_file = output_file + '.xlsx'
                merged_df.to_excel(output_file, index=False)
            
            print(f"\n✅ 合并完成！")
            print(f"📄 输出文件：{output_file}")
            print(f"📊 总行数：{len(merged_df)}")
            
            report += f"\n## 合并结果\n\n"
            report += f"- 总行数：{len(merged_df)}\n"
            report += f"- 输出文件：{output_file}\n"
    
    except ImportError:
        print("\n⚠️  pandas 未安装，无法合并数据")
        print("💡 安装命令：pip install pandas openpyxl")
        report += f"\n## 提示\n\n需要安装 pandas 和 openpyxl 才能合并数据\n"
        report += "```\npip install pandas openpyxl\n```\n"
    
    # 保存报告
    report_file = Path(output_file).with_suffix('.md')
    report_file.write_text(report, encoding='utf-8')
    print(f"📄 报告已保存：{report_file}")

def rename_files(input_dir, pattern):
    """批量重命名文件"""
    print(f"📁 扫描目录：{input_dir}")
    
    input_path = Path(input_dir)
    if not input_path.exists():
        print(f"❌ 目录不存在：{input_dir}")
        return
    
    files = [f for f in input_path.iterdir() if f.is_file()]
    files = sorted(files, key=lambda f: f.stat().st_mtime)  # 按修改时间排序
    
    if not files:
        print("❌ 未找到文件")
        return
    
    print(f"✅ 找到 {len(files)} 个文件")
    
    date_str = datetime.now().strftime("%Y%m%d")
    renamed_count = 0
    
    print(f"\n📝 重命名预览:")
    for i, file in enumerate(files, 1):
        if "{original}" in pattern:
            new_name = pattern.replace("{original}", file.stem)
            new_name = new_name.replace("{date}", date_str)
        elif "{date}" in pattern:
            new_name = pattern.replace("{date}", date_str) + f"_{i:03d}"
        else:
            new_name = pattern + f"_{i:03d}"
        
        new_name = new_name + file.suffix
        new_path = file.parent / new_name
        
        if new_path != file:
            print(f"   {file.name} → {new_name}")
            renamed_count += 1
    
    # 确认执行
    print(f"\n✅ 将重命名 {renamed_count} 个文件")
    
    # 执行重命名
    for i, file in enumerate(files, 1):
        if "{original}" in pattern:
            new_name = pattern.replace("{original}", file.stem)
            new_name = new_name.replace("{date}", date_str)
        elif "{date}" in pattern:
            new_name = pattern.replace("{date}", date_str) + f"_{i:03d}"
        else:
            new_name = pattern + f"_{i:03d}"
        
        new_name = new_name + file.suffix
        new_path = file.parent / new_name
        
        if new_path != file:
            try:
                shutil.move(str(file), str(new_path))
            except Exception as e:
                print(f"   ❌ {file.name} 重命名失败：{e}")
    
    print(f"\n✅ 重命名完成！")

def merge_pdf_files(input_dir, output_file):
    """合并 PDF 文件"""
    print(f"📁 扫描目录：{input_dir}")
    
    input_path = Path(input_dir)
    if not input_path.exists():
        print(f"❌ 目录不存在：{input_dir}")
        return
    
    pdf_files = list(input_path.glob("*.pdf"))
    pdf_files = sorted(pdf_files)
    
    if not pdf_files:
        print("❌ 未找到 PDF 文件")
        return
    
    print(f"✅ 找到 {len(pdf_files)} 个 PDF 文件:")
    for i, f in enumerate(pdf_files, 1):
        print(f"   {i}. {f.name}")
    
    # 尝试使用 pypdf 合并
    try:
        from pypdf import PdfWriter, PdfReader
        print("\n📊 合并 PDF 文件...")
        
        merger = PdfWriter()
        
        for f in pdf_files:
            try:
                reader = PdfReader(f)
                merger.append(reader)
                print(f"   ✅ {f.name}: {len(reader.pages)} 页")
            except Exception as e:
                print(f"   ⚠️ {f.name}: 添加失败 - {e}")
        
        # 输出文件
        if not output_file.endswith('.pdf'):
            output_file = output_file + '.pdf'
        
        merger.write(output_file)
        merger.close()
        
        print(f"\n✅ 合并完成！")
        print(f"📄 输出文件：{output_file}")
    
    except ImportError:
        print("\n⚠️  pypdf 未安装，无法合并 PDF")
        print("💡 安装命令：pip install pypdf")
    
    # 生成报告
    report = f"# PDF 合并报告\n\n"
    report += f"**扫描目录**: {input_dir}\n"
    report += f"**文件数量**: {len(pdf_files)}\n\n"
    report += "## 文件列表\n\n"
    for f in pdf_files:
        report += f"- {f.name}\n"
    
    report_file = Path(output_file).with_suffix('.md')
    report_file.write_text(report, encoding='utf-8')
    print(f"📄 报告已保存：{report_file}")

def word_batch_replace(input_dir, old_text, new_text):
    """Word 批量替换文本"""
    print(f"📁 扫描目录：{input_dir}")
    
    input_path = Path(input_dir)
    if not input_path.exists():
        print(f"❌ 目录不存在：{input_dir}")
        return
    
    docx_files = list(input_path.glob("*.docx"))
    
    if not docx_files:
        print("❌ 未找到 Word 文件")
        return
    
    print(f"✅ 找到 {len(docx_files)} 个 Word 文件")
    print(f"📝 替换内容：'{old_text}' → '{new_text}'")
    
    # 尝试使用 python-docx
    try:
        from docx import Document
        print("\n📊 开始批量替换...")
        
        for f in docx_files:
            try:
                doc = Document(f)
                
                # 替换段落中的文本
                replaced = False
                for paragraph in doc.paragraphs:
                    if old_text in paragraph.text:
                        paragraph.text = paragraph.text.replace(old_text, new_text)
                        replaced = True
                
                # 替换表格中的文本
                for table in doc.tables:
                    for row in table.rows:
                        for cell in row.cells:
                            if old_text in cell.text:
                                cell.text = cell.text.replace(old_text, new_text)
                                replaced = True
                
                if replaced:
                    doc.save(f)
                    print(f"   ✅ {f.name}: 已替换")
                else:
                    print(f"   ⚠️ {f.name}: 未找到匹配文本")
                
            except Exception as e:
                print(f"   ❌ {f.name}: 处理失败 - {e}")
        
        print(f"\n✅ 批量替换完成！")
    
    except ImportError:
        print("\n⚠️  python-docx 未安装，无法处理 Word")
        print("💡 安装命令：pip install python-docx")

def main():
    """主函数"""
    if len(sys.argv) < 2:
        print("=" * 60)
        print("办公自动化脚本 - 科特船长版")
        print("=" * 60)
        print()
        print("用法：python office_automation.py <action> [options]")
        print()
        print("可用操作:")
        print("  excel-merge   合并 Excel 文件")
        print("  rename        批量重命名文件")
        print("  pdf-merge     合并 PDF 文件")
        print("  word-replace  Word 批量替换")
        print()
        print("示例:")
        print("  python office_automation.py excel-merge --input ./data --output ./merged.xlsx")
        print("  python office_automation.py rename --input ./files --pattern '{date}_{original}'")
        print("  python office_automation.py pdf-merge --input ./pdfs --output ./merged.pdf")
        print("  python office_automation.py word-replace --input ./docs --old '旧文本' --new '新文本'")
        print()
        return
    
    action = sys.argv[1]
    
    # 解析参数
    def get_arg(name, default=None):
        try:
            idx = sys.argv.index(f"--{name}")
            if idx + 1 < len(sys.argv):
                return sys.argv[idx + 1]
        except ValueError:
            pass
        return default
    
    if action == "excel-merge":
        input_dir = get_arg("input", "./data")
        output = get_arg("output", "./merged.xlsx")
        merge_excel_files(input_dir, output)
    
    elif action == "rename":
        input_dir = get_arg("input", "./files")
        pattern = get_arg("pattern", "{date}_{original}")
        rename_files(input_dir, pattern)
    
    elif action == "pdf-merge":
        input_dir = get_arg("input", "./pdfs")
        output = get_arg("output", "./merged.pdf")
        merge_pdf_files(input_dir, output)
    
    elif action == "word-replace":
        input_dir = get_arg("input", "./docs")
        old_text = get_arg("old", "")
        new_text = get_arg("new", "")
        if not old_text:
            print("❌ 错误：--old 参数必填")
            return
        word_batch_replace(input_dir, old_text, new_text)
    
    else:
        print(f"❌ 未知操作：{action}")
        print("运行脚本 without 参数查看帮助")

if __name__ == '__main__':
    main()


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)