乐于分享
好东西不私藏

SKILL实战:Excel 代码 + Prompt驱动 + Skill进阶

SKILL实战:Excel 代码 + Prompt驱动 + Skill进阶

📂 本文档是 Excel 处理专题的合集版,包含三条学习路径的所有内容,读者可根据需要选择阅读。

完整代码获取:https://gitee.com/agent-now/hermes-workspace/blob/master/tutorials/excel-all-in-one.md[1]

工具版本:openpyxl 3.1.5 + pandas 3.0.2

专题结构:三条学习路径

路径 入口 说明
代码篇 下方各章节 openpyxl + pandas,完整可运行代码
Prompt驱动篇 下方各章节 自然语言指令模板,直接复制改参数用
Skill进阶 十四章:XML 源码级处理[2] minimax-xlsx 底层原理,财务配色标准

阅读建议

  • 想快速完成任务 → 看 Prompt 模板,直接用
  • 想系统学习 → 先看代码,搞懂原理
  • 想深度定制/搞懂底层 → 看第十四章 Skill 进阶

预备:示例数据说明

所有代码和 Prompt 均基于以下示例数据(sales_data.xlsx):

日期 销售员 产品 区域 销售额 数量
2025-01-03 张三 电子产品 华东 12,500 8
2025-01-03 李四 办公用品 华北 8,300 12
2025-01-04 张三 办公用品 华南 5,600 5
2025-01-04 王五 电子产品 华东 18,900 15
2025-01-05 李四 办公用品 华东 7,200 9
2025-01-05 赵六 电子产品 华北 21,300 18
2025-01-06 张三 办公用品 华南 4,900 4
2025-01-06 王五 电子产品 华东 15,600 12
2025-01-07 李四 办公用品 华北 9,100 10
2025-01-07 赵六 电子产品 华南 17,800 14

生成方式(代码篇)

from openpyxl import Workbook

wb = Workbook()
ws = wb.active
ws.title = "销售数据"

headers = ["日期""销售员""产品""区域""销售额""数量"]
ws.append(headers)

data = [
    ["2025-01-03""张三""电子产品""华东"125008],
    ["2025-01-03""李四""办公用品""华北"830012],
    ["2025-01-04""张三""办公用品""华南"56005],
    ["2025-01-04""王五""电子产品""华东"1890015],
    ["2025-01-05""李四""办公用品""华东"72009],
    ["2025-01-05""赵六""电子产品""华北"2130018],
    ["2025-01-06""张三""办公用品""华南"49004],
    ["2025-01-06""王五""电子产品""华东"1560012],
    ["2025-01-07""李四""办公用品""华北"910010],
    ["2025-01-07""赵六""电子产品""华南"1780014],
]
for row in data:
    ws.append(row)

wb.save("sales_data.xlsx")
print("示例文件已创建:sales_data.xlsx")

运行后会生成 sales_data.xlsx,后续各章节都基于此文件操作。


第一章:数据读取与写入 {#ch01}

代码篇

1.1 用 pandas 读取

import pandas as pd

# 读取第一个 sheet(默认)
df = pd.read_excel("sales_data.xlsx")
print(df.head())

# 读取所有 sheet(返回字典)
all_sheets = pd.read_excel("sales_data.xlsx", sheet_name=None)
for name, sheet in all_sheets.items():
    print(f"Sheet名称: {name}, 行数: {len(sheet)}")

# 读取指定 sheet
df_sales = pd.read_excel("sales_data.xlsx", sheet_name="销售数据")

1.2 用 openpyxl 读取(保留格式)

from openpyxl import load_workbook

wb = load_workbook("sales_data.xlsx")
ws = wb.active

for row in ws.iter_rows(min_row=1, max_row=3):
    for cell in row:
        print(f"{cell.coordinate}{cell.value}", end=" | ")
    print()

1.3 保存处理后的数据

import pandas as pd

df = pd.read_excel("sales_data.xlsx")
df["单价"] = df["销售额"] / df["数量"]

# 保存到新文件(不包含默认索引列)
df.to_excel("sales_data-processed.xlsx", index=False)

执行结果:

           日期 销售员    产品  区域    销售额  数量
0  2025-01-03  张三  电子产品  华东  12500   8
1  2025-01-03  李四  办公用品  华北   8300  12
2  2025-01-04  张三  办公用品  华南   5600   5
总行数: 10

Prompt驱动篇

读取并了解文件结构

请帮我读取 sales_data.xlsx 文件,
1. 显示前10行内容
2. 告诉我有哪些列
3. 告诉我每列的数据类型
4. 告诉我总共有多少行数据

保存处理后的数据

读取 sales_data.xlsx,
把"销售额"列除以"数量"得到"单价",
保存为 sales_with_unit_price.xlsx。

从 CSV 导入 Excel

把 weekly_report.csv 转换为 Excel 格式,
保留中文编码(UTF-8),
第一个工作表命名为"周报数据",
保存为 weekly_report.xlsx。

第二章:合并与拆分 Sheet {#ch02}

代码篇

2.1 将多个 sheet 合并为一个

import pandas as pd

file_path = "sales_data.xlsx"

# 读取所有 sheet
all_sheets = pd.read_excel(file_path, sheet_name=None)

# 合并所有 sheet
merged_df = pd.concat(all_sheets.values(), ignore_index=True)
print(f"合并后总行数: {len(merged_df)}")

# 保存合并结果
merged_df.to_excel("sales_merged.xlsx", index=False)

2.2 将数据按条件拆分为多个 Sheet

import pandas as pd
from openpyxl import Workbook

df = pd.read_excel("sales_data.xlsx")

# 按"区域"拆分为不同 sheet
wb = Workbook()
wb.remove(wb.active)

for region, group in df.groupby("区域"):
    ws = wb.create_sheet(title=region)
    ws.append(list(group.columns))
    for _, row in group.iterrows():
        ws.append(list(row))
    print(f"已创建 Sheet: {region}")

wb.save("sales_by_region.xlsx")

执行结果:

Sheet列表: ['华东', '华北', '华南']
每个Sheet数据行数:华东4行、华北3行、华南3行

Prompt驱动篇

合并多个 Sheet

我有一个文件叫 sales.xlsx,里面有三个 Sheet:
- Sheet1 叫"华东"
- Sheet2 叫"华北"
- Sheet3 叫"华南"
这三个 Sheet 的结构完全一样(日期、销售员、产品、区域、销售额、数量)。

请帮我:
1. 把这三个 Sheet 合并成一个大表
2. 新增一列"区域",填入对应 Sheet 的名称
3. 保存为 sales_merged.xlsx

按条件拆分为多个 Sheet

读取 sales_data.xlsx,
按"区域"列拆分为不同的 Sheet:
- 华东地区的数据保存到一个 Sheet,名称叫"华东"
- 华北地区的数据保存到一个 Sheet,名称叫"华北"
- 华南地区的数据保存到一个 Sheet,名称叫"华南"
最终保存为一个 Excel 文件叫 sales_by_region.xlsx,包含三个 Sheet。

按条件导出子集

从 sales_data.xlsx 中:
1. 筛选出"产品"等于"电子产品"的行
2. 筛选出"销售额"大于 10000 的行
3. 将这两个筛选结果分别保存为:
   - electronics_high.xlsx(电子产品且销售额>10000)
   - rest.xlsx

第三章:数据筛选与排序 {#ch03}

代码篇

3.1 筛选数据

import pandas as pd

df = pd.read_excel("sales_data.xlsx")

# 单一条件筛选
high_sales = df[df["销售额"] > 10000]

# 多条件筛选:电子产品 且 销售额 > 10000
filtered = df[(df["产品"] == "电子产品") & (df["销售额"] > 10000)]

filtered.to_excel("sales_high.xlsx", index=False)

3.2 排序数据

df = pd.read_excel("sales_data.xlsx")

# 按销售额降序排列
sorted_df = df.sort_values(by="销售额", ascending=False)

# 多列排序:先按区域,再按销售额降序
sorted_multi = df.sort_values(by=["区域""销售额"], ascending=[TrueFalse])

sorted_multi.to_excel("sales_sorted.xlsx", index=False)

执行结果:

筛选结果(电子产品 且 销售额>10000):
 销售员   产品   销售额
  张三 电子产品 12500
  王五 电子产品 18900
  赵六 电子产品 21300
  王五 电子产品 15600
  赵六 电子产品 17800

排序结果(前5行):
 销售员 区域   销售额
  王五 华东 18900
  王五 华东 15600
  张三 华东 12500
  ...

Prompt驱动篇

条件筛选

读取 sales_data.xlsx,帮我完成以下筛选:
1. 筛选条件1:销售额大于 10000
2. 筛选条件2:产品等于"电子产品"
3. 两个条件用 AND 组合(同时满足)
4. 把结果保存为 top_electronics.xlsx

筛选常用表达对照

场景 怎么说
等于 “产品等于’电子产品'”、”区域是’华东'”
不等于 “产品不等于’办公用品'”
大于/小于 “销售额大于10000″、”数量小于5”
区间 “销售额在5000到15000之间”
包含 “产品名称包含’手机'”
多条件AND “产品=’电子产品’ 且 销售额>10000”
多条件OR “区域=’华东’ 或 区域=’华北'”

排序

读取 sales_data.xlsx,
先按"区域"升序排列,
再按"销售额"降序排列(同一区域内按销售额从高到低),
保存为 sales_ranked.xlsx。

第四章:去除重复数据 {#ch04}

代码篇

import pandas as pd

df = pd.read_excel("sales_data.xlsx")

# 查看重复行
print(df[df.duplicated(keep=False)])

# 删除重复行(保留第一条)
df_unique = df.drop_duplicates()
print(f"去重前行数: {len(df)}, 去重后: {len(df_unique)}")

# 按某列去重(保留该列值最大的那条)
df_best = df.sort_values("销售额", ascending=False).drop_duplicates(subset="销售员", keep="first")

df_unique.to_excel("sales_dedup.xlsx", index=False)

执行结果:

去重前行数: 10
去重后行数: 10(本次数据无重复行)

每销售员保留最高销售额的记录:
 销售员   销售额
  赵六 21300
  王五 18900
  张三 12500
  李四  9100

Prompt驱动篇

删除完全重复的行

帮我检查 sales_data.xlsx 是否有完全重复的行:
1. 告诉我一共有多少行,其中多少行是重复的
2. 删除所有重复行(保留每组的第一条)
3. 保存为 sales_dedup.xlsx
4. 告诉我删除了多少行

按某列去重(保留最优)

读取 sales_data.xlsx,
如果同一个"销售员"出现多次,只保留他销售额最高的那一行,
其他重复记录删除,
保存为 sales_best_per_person.xlsx。

第五章:公式与计算 {#ch05}

代码篇

5.1 写入 Excel 公式

from openpyxl import load_workbook, Workbook

wb = Workbook()
ws = wb.active
ws.title = "公式示例"

ws["A1"], ws["B1"], ws["C1"], ws["D1"] = "产品""单价""数量""金额"
ws["A2"], ws["B2"], ws["C2"] = "电子产品"15010
ws["A3"], ws["B3"], ws["C3"] = "办公用品"4525
ws["A4"], ws["B4"], ws["C4"] = "办公用品"8015

# 写入公式:用 Excel 计算金额 = 单价 × 数量
ws["D2"] = "=B2*C2"
ws["D3"] = "=B3*C3"
ws["D4"] = "=B4*C4"

# SUM 合计公式
ws["A5"], ws["D5"] = "合计""=SUM(D2:D4)"

wb.save("formula_example.xlsx")

重要原则:公式的值应该在 Excel 里计算,而不是在 Python 里算好再写入。这样 Excel 打开后改动数据,公式结果会自动更新。

5.2 常用公式参考

公式 用途 示例
=SUM(A1:A10) 求和 合计一列数字
=AVERAGE(A1:A10) 平均值 算平均销售额
=VLOOKUP(A1, B:C, 2, FALSE) 查找匹配 根据姓名查部门
=IF(A1>10000, "高", "低") 条件判断 销售额分级
=SUMIF(A:A, "电子产品", B:B) 条件求和 某产品销售总额
=COUNTIF(A:A, ">10000") 条件计数 超额次数

Prompt驱动篇

添加计算列

原则:让 AI 帮你写公式,而不是帮你算值

读取 sales_data.xlsx,
在旁边新增一列叫"利润率",计算公式为:(销售额 - 销售额×0.6) / 销售额
用 Excel 公式实现,不是 Python 算好再写入。
保存为 sales_with_margin.xlsx。

求和、汇总

读取 sales_data.xlsx,
在"销售额"列的最下方增加一行"合计",
计算所有销售额的总和(用 Excel SUM 公式)。
同时在"数量"列最下方也加合计。
保存为 sales_with_total.xlsx。

VLOOKUP 查找匹配

有两个文件:
- sales_data.xlsx:销售数据(含姓名、销售额)
- employee_info.xlsx:员工信息表(含姓名、部门、职位)

请在 sales_data.xlsx 中新增两列:
1. "部门":根据姓名从 employee_info.xlsx 匹配对应的部门
2. "职位":根据姓名从 employee_info.xlsx 匹配对应的职位
使用 Excel VLOOKUP 公式实现。
保存为 sales_with_dept.xlsx。

截图:公式效果

📌 说明:Excel 打开后,D 列会自动显示计算结果(金额 = 单价 × 数量),D4 显示合计。修改 B、C 列数值,公式结果会自动更新。

第六章:修复公式错误 {#ch06}

代码篇

6.1 常见报错类型

错误值 含义 常见原因
#REF! 引用无效 引用的单元格/区域被删除
#DIV/0! 除零错误 除数单元格为零或空
#VALUE! 类型错误 公式接收了非数值类型
#NAME? 名称未识别 函数名拼写错误
#N/A 查找无结果 VLOOKUP 找不到匹配值

6.2 自动检测并修复

from openpyxl import load_workbook

wb = load_workbook("problem_file.xlsx")
ws = wb.active

errors_found = []

for row in ws.iter_rows():
    for cell in row:
        if isinstance(cell.value, strand cell.value.startswith("="):
            formula = cell.value
            if any(e in formula for e in ["#REF!""#DIV/0!""#VALUE!"]):
                errors_found.append({
                    "cell": cell.coordinate,
                    "formula": formula
                })
                print(f"发现错误公式: {cell.coordinate} -> {formula}")

if errors_found:
    for error in errors_found:
        cell = ws[error["cell"]]
        # 用 IFERROR 包裹,防止继续报错
        safe_formula = f'=IFERROR({error["formula"][1:]}, "-")'
        cell.value = safe_formula
        print(f"已修复: {error['cell']} -> {safe_formula}")
    wb.save("problem_file_fixed.xlsx")
else:
    print("未发现报错公式")

Prompt驱动篇

诊断公式报错

帮我检查 report.xlsx 里所有工作表的公式错误:
1. 找出所有报 #REF!、#DIV/0!、#VALUE! 等错误的单元格
2. 告诉我每个错误单元格的坐标和当前公式内容
3. 给出修复建议

用 IFERROR 包裹报错公式

帮我修复 sales.xlsx 中所有报错的公式:
1. 找到所有包含 #REF!、#DIV/0! 的单元格
2. 用 IFERROR 公式包裹它们,错误时显示"-"
3. 保存为 sales_fixed.xlsx

批量修复 #N/A 错误

帮我处理 VLOOKUP 的 #N/A 错误:
1. 找出所有 #N/A 的单元格
2. 用 IFERROR(VLOOKUP(...), "未找到") 的方式替换
3. 保存为 sales_no_na.xlsx

第七章:格式处理 {#ch07}

代码篇

7.1 设置表头样式

from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side

wb = load_workbook("sales_data.xlsx")
ws = wb.active

header_fill = PatternFill(start_color="1F4E79", end_color="1F4E79", fill_type="solid")
header_font = Font(name="Arial", bold=True, color="FFFFFF", size=11)
header_align = Alignment(horizontal="center", vertical="center")

thin_border = Border(
    left=Side(style="thin"), right=Side(style="thin"),
    top=Side(style="thin"), bottom=Side(style="thin")
)

for cell in ws[1]:
    cell.fill = header_fill
    cell.font = header_font
    cell.alignment = header_align
    cell.border = thin_border

wb.save("sales_styled.xlsx")

7.2 隔行着色(斑马线)

from openpyxl import load_workbook
from openpyxl.styles import PatternFill, Alignment, Border, Side

wb = load_workbook("sales_data.xlsx")
ws = wb.active

even_fill = PatternFill(start_color="D6E4F0", end_color="D6E4F0", fill_type="solid")
odd_fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")

data_align = Alignment(horizontal="center", vertical="center")
thin_border = Border(
    left=Side(style="thin"), right=Side(style="thin"),
    top=Side(style="thin"), bottom=Side(style="thin")
)

for row_idx, row in enumerate(ws.iter_rows(min_row=2), start=1):
    fill = even_fill if row_idx % 2 == 0 else odd_fill
    for cell in row:
        cell.fill = fill
        cell.alignment = data_align
        cell.border = thin_border

# 列宽自适应
col_widths = {"A"12"B"10"C"12"D"8"E"12"F"8}
for col, width in col_widths.items():
    ws.column_dimensions[col].width = width

# 冻结首行
ws.freeze_panes = "A2"

wb.save("sales_zebra.xlsx")

7.3 自动调整列宽

from openpyxl import load_workbook

wb = load_workbook("sales_data.xlsx")

for sheet_name in wb.sheetnames:
    ws = wb[sheet_name]
    for column in ws.columns:
        max_length = 0
        column_letter = column[0].column_letter
        for cell in column:
            try:
                if cell.value:
                    max_length = max(max_length, len(str(cell.value)))
            except:
                pass
        adjusted_width = min(max_length + 230)
        ws.column_dimensions[column_letter].width = adjusted_width

wb.save("sales_autofit.xlsx")

Prompt驱动篇

统一表头样式

帮我美化 sales_data.xlsx 的格式:
1. 表头行(第一行)背景色设为深蓝色(#1F4E79),白色字体,加粗,居中对齐
2. 数据区域添加边框线(细线)
3. 保存为 sales_styled.xlsx

隔行变色(斑马线)

sales_data.xlsx 的数据区域(从第2行开始):
- 奇数行:白色背景
- 偶数行:浅蓝色背景(#D6E4F0)
表头行不变。
保存为 sales_zebra.xlsx。

冻结首行

sales_data.xlsx 设置冻结首行(方便向下滚动时始终看到表头)。
保存为 sales_frozen.xlsx。

金额数字加千分位分隔符

sales_data.xlsx 的"销售额"列:
- 设置为会计专用格式:千分位分隔符、保留0位小数
- 负数显示为括号形式(如 (1,234))
保存为 sales_formatted.xlsx。

截图:格式美化效果

📌 说明:深蓝色表头 + 白色/浅蓝交替行 + 冻结首行。滚动数据时表头始终可见。

第八章:条件格式 {#ch08}

代码篇

8.1 高亮满足条件的单元格

from openpyxl import load_workbook
from openpyxl.styles import PatternFill
from openpyxl.formatting.rule import ColorScaleRule, CellIsRule

wb = load_workbook("sales_data.xlsx")
ws = wb.active

# 销售额大于 15000:绿色背景
ws.conditional_formatting.add(
    "E2:E100",
    CellIsRule(operator="greaterThan", formula=["15000"],
               fill=PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid"))
)

# 销售额小于 6000:红色背景
ws.conditional_formatting.add(
    "E2:E100",
    CellIsRule(operator="lessThan", formula=["6000"],
               fill=PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid"))
)

# 销售额三色刻度(低=红,中=黄,高=绿)
ws.conditional_formatting.add(
    "E2:E100",
    ColorScaleRule(
        start_type="min", start_color="F8696B",
        mid_type="percentile", mid_value=50, mid_color="FFEB84",
        end_type="max", end_color="63BE7B"
    )
)

wb.save("sales_conditional.xlsx")

8.2 数据条(Data Bars)

from openpyxl import load_workbook
from openpyxl.formatting.rule import DataBarRule

wb = load_workbook("sales_data.xlsx")
ws = wb.active

ws.conditional_formatting.add(
    "E2:E100",
    DataBarRule(start_type="min", end_type="max", color="638EC6", showValue=True)
)

wb.save("sales_databar.xlsx")

Prompt驱动篇

高亮满足条件的行

sales_data.xlsx 的"销售额"列(E列):
- 销售额 > 15000:整行背景浅绿色
- 销售额 < 6000:整行背景浅红色
保存为 sales_conditional.xlsx。

三色刻度

sales_data.xlsx 的"销售额"列:
应用三色条件格式:
- 最小值:红色
- 中间值(50%):黄色
- 最大值:绿色
保存为 sales_heatmap.xlsx。

数据条

sales_data.xlsx 的"销售额"列:
添加数据条(Data Bars),蓝色数据条。
保存为 sales_databar.xlsx。

截图:条件格式效果

📌 说明:绿色(销售额>15000)、红色(销售额<6000)、三色刻度(低→红,中→黄,高→绿)。颜色随数据变化自动更新。

第九章:图表生成 {#ch09}

代码篇

9.1 创建柱状图

from openpyxl import load_workbook, Workbook
from openpyxl.chart import BarChart, Reference
import pandas as pd

wb = load_workbook("sales_data.xlsx")
ws = wb.active

# 用 pandas 汇总
df = pd.read_excel("sales_data.xlsx")
summary = df.groupby("销售员")["销售额"].sum().reset_index()

# 创建汇总 sheet
summary_wb = Workbook()
summary_ws = summary_wb.active
summary_ws.title = "汇总"
summary_ws.append(["销售员""总销售额"])
for _, row in summary.iterrows():
    summary_ws.append([row["销售员"], row["总销售额"]])

# 创建图表
chart = BarChart()
chart.type = "col"
chart.style = 10
chart.title = "各销售员总销售额"
chart.y_axis.title = "销售额"
chart.x_axis.title = "销售员"

data = Reference(summary_ws, min_col=2, min_row=1, max_row=len(summary)+1)
cats = Reference(summary_ws, min_col=1, min_row=2, max_row=len(summary)+1)
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)

summary_ws.add_chart(chart, "D1")
summary_wb.save("sales_chart.xlsx")

9.2 用 matplotlib 导出图表图片

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use("Agg")

df = pd.read_excel("sales_data.xlsx")
sales_by_person = df.groupby("销售员")["销售额"].sum().sort_values(ascending=False)

plt.figure(figsize=(85))
colors = ["#1F4E79" if v == sales_by_person.max() else "#5B9BD5" for v in sales_by_person.values]
bars = plt.bar(sales_by_person.index, sales_by_person.values, color=colors, edgecolor="white", linewidth=1.2)

plt.title("各销售员总销售额", fontsize=16, fontweight="bold", color="#1F4E79", pad=15)
plt.xlabel("销售员", fontsize=12)
plt.ylabel("总销售额(元)", fontsize=12)
plt.ticklabel_format(style="plain", axis="y")

for bar, val in zip(bars, sales_by_person.values):
    plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 200,
             f"{val:,.0f}", ha="center", va="bottom", fontsize=10, color="#1F4E79", fontweight="bold")

plt.grid(axis="y", linestyle="--", alpha=0.5)
plt.tight_layout()
plt.savefig("sales_chart.png", dpi=150, bbox_inches="tight", facecolor="white")
plt.close()
print("图表已保存:sales_chart.png")

Prompt驱动篇

生成柱状图

读取 sales_data.xlsx,按销售员汇总总销售额,
生成一张柱状图:
- X轴:销售员姓名
- Y轴:总销售额
- 柱子颜色:深蓝色
- 最高值的柱子用不同颜色突出
- 图表标题:"各销售员总销售额"
保存为 sales_chart.xlsx(含图表的文件)。

生成折线图(看趋势)

sales_data.xlsx 有日期列和销售额列,
生成一张折线图:
- X轴:日期
- Y轴:每日总销售额
- 标题:"每日销售额趋势"
保存为 sales_trend.xlsx。

导出图表为图片

读取 sales_data.xlsx,
生成一张按区域分组的柱状图,
将图表导出为 PNG 图片(宽800px,高500px,分辨率150dpi),
保存为 sales_chart.png。

截图:图表生成效果

📌 说明:柱状图展示各销售员业绩排名(深蓝最高值突出),饼图展示区域占比。可直接嵌入 PPT 或报告。

第十章:批量处理 {#ch10}

代码篇

10.1 批量读取并合并同类型文件

import pandas as pd
import glob
import os

# 找到所有 Excel 文件(支持 xlsx、xls、csv)
files = glob.glob("data/*.xlsx") + glob.glob("data/*.xls") + glob.glob("data/*.csv")
print(f"找到 {len(files)} 个文件")

all_data = []
for file in files:
    if file.endswith(".csv"):
        df = pd.read_csv(file)
    else:
        df = pd.read_excel(file)
    df["来源文件"] = os.path.basename(file)
    all_data.append(df)
    print(f"  已读取: {os.path.basename(file)} ({len(df)} 行)")

merged = pd.concat(all_data, ignore_index=True)
print(f"\n合并后总计: {len(merged)} 行")
merged.to_excel("all_merged.xlsx", index=False)

执行结果:

找到 6 个文件,合并后共 42 行

10.2 批量给多个文件做格式处理

import glob
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill, Alignment

def style_sheet(filepath):
    wb = load_workbook(filepath)
    for ws in wb.worksheets:
        for cell in ws[1]:
            cell.fill = PatternFill(start_color="1F4E79", end_color="1F4E79", fill_type="solid")
            cell.font = Font(name="Arial", bold=True, color="FFFFFF", size=11)
            cell.alignment = Alignment(horizontal="center", vertical="center")
        for column in ws.columns:
            max_len = max(len(str(cell.value or "")) for cell in column)
            ws.column_dimensions[column[0].column_letter].width = min(max_len + 225)
    wb.save(filepath)
    print(f"  已处理: {filepath}")

for file in glob.glob("data/*.xlsx"):
    style_sheet(file)
print("批量处理完成")

10.3 批量按条件导出子文件

import pandas as pd
import os

df = pd.read_excel("sales_data.xlsx")

output_dir = "output_by_region"
os.makedirs(output_dir, exist_ok=True)

for region, group in df.groupby("区域"):
    filename = f"{output_dir}/sales_{region}.xlsx"
    group.to_excel(filename, index=False)
    print(f"已导出: {filename} ({len(group)} 行)")

Prompt驱动篇

批量合并文件

data 文件夹里有多个 Excel 文件(可能有 xlsx、csv),
请把它们全部合并为一个文件:
1. 自动识别每个文件的列结构
2. 新增一列"来源文件"标记数据来自哪个文件
3. 合并后保存为 all_merged.xlsx

批量格式美化

data 文件夹下的所有 Excel 文件(*.xlsx),
请统一做以下格式处理:
1. 表头:深蓝色背景、白色字体、加粗
2. 数据区域:隔行变色(白/浅蓝交替)
3. 所有列宽自动调整为内容宽度(上限25字符)
4. 保存回原文件(覆盖)

批量拆分文件

有一个大文件叫 sales_data.xlsx,
按"区域"列拆分为多个独立文件:
- 华东地区 → sales_east.xlsx
- 华北地区 → sales_north.xlsx
- 华南地区 → sales_south.xlsx
每个文件只包含对应区域的数据,保留完整表头。

第十一章:格式转换——CSV与Excel互转 {#ch11}

代码篇

11.1 CSV 转 Excel

import pandas as pd

df = pd.read_csv("sales_data.csv")
print(f"读取 {len(df)} 行,{len(df.columns)} 列")
df.to_excel("sales_data.xlsx", sheet_name="销售数据", index=False)

11.2 Excel 转 CSV

import pandas as pd

df = pd.read_excel("sales_data.xlsx", sheet_name="销售数据")
print(f"读取 {len(df)} 行")

# 写入 CSV(不带索引列,不带中文表头 BOM)
df.to_csv("sales_data.csv", index=False, encoding="utf-8-sig")
print("已转换为 sales_data.csv(UTF-8编码,Excel可直接打开)")

11.3 处理大文件:分 sheet 写入

import pandas as pd

CHUNK_SIZE = 50000

def split_excel(input_file, output_file, chunk_size=CHUNK_SIZE):
    df = pd.read_excel(input_file)
    total_rows = len(df)
    num_sheets = (total_rows + chunk_size - 1) // chunk_size

    print(f"总行数: {total_rows},将拆分为 {num_sheets} 个 sheet")

    with pd.ExcelWriter(output_file, engine="openpyxl"as writer:
        for i in range(num_sheets):
            start = i * chunk_size
            end = min((i + 1) * chunk_size, total_rows)
            sheet_name = f"数据_{i+1}"
            df.iloc[start:end].to_excel(writer, sheet_name=sheet_name, index=False)
            print(f"  已写入: {sheet_name} (第{start+1}-{end}行)")

split_excel("big_data.xlsx""big_data_splitted.xlsx")

Prompt驱动篇

CSV 转 Excel

把 weekly_report.csv 转换为 Excel 格式,
保留中文编码(UTF-8),
第一个工作表命名为"周报数据",
保存为 weekly_report.xlsx。

Excel 转 CSV

把 sales_data.xlsx 的"销售数据"这个 Sheet 导出为 CSV,
使用 UTF-8 编码(Excel 可直接打开),
保存为 sales_data.csv。

第十二章:实战案例 {#ch12}

案例背景

小明是一家中型公司的运营人员,每周要处理各区域发来的销售 Excel:

  1. 收到华东、华北、华南三个地区的周报
  2. 合并为一个总表
  3. 按销售员汇总排名
  4. 格式美化(表头颜色、隔行着色)
  5. 生成图表
  6. 发给领导

代码:完整实现

import pandas as pd
import glob
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.chart import BarChart, Reference
from openpyxl.formatting.rule import CellIsRule

# ===== 第一步:读取各区域数据 =====
files = glob.glob("weekly_reports/*.xlsx")
print(f"找到 {len(files)} 个区域报告")

all_data = []
for f in files:
    df = pd.read_excel(f)
    df["来源"] = f.split("/")[-1].replace(".xlsx""")
    all_data.append(df)
    print(f"  读取: {f.split('/')[-1]} ({len(df)} 行)")

merged = pd.concat(all_data, ignore_index=True)
print(f"合并后总计: {len(merged)} 行")

# ===== 第二步:数据汇总 =====
summary = merged.groupby(["区域""销售员"]).agg(
    总销售额=("销售额""sum"),
    总数量=("数量""sum"),
    订单数=("日期""count")
).reset_index()

summary = summary.sort_values("总销售额", ascending=False).reset_index(drop=True)
summary["排名"] = summary.index + 1
print("\n销售排名:")
print(summary[["排名""销售员""区域""总销售额"]].to_string(index=False))

# ===== 第三步:生成 Excel 报告 =====
wb = Workbook()
ws_summary = wb.active
ws_summary.title = "汇总"

headers = ["排名""区域""销售员""总销售额""总数量""订单数"]
ws_summary.append(headers)

for _, row in summary.iterrows():
    ws_summary.append([
        row["排名"], row["区域"], row["销售员"],
        row["总销售额"], row["总数量"], row["订单数"]
    ])

# 表头样式
header_fill = PatternFill(start_color="1F4E79", end_color="1F4E79", fill_type="solid")
header_font = Font(name="Arial", bold=True, color="FFFFFF", size=11)
header_align = Alignment(horizontal="center", vertical="center")
thin_border = Border(
    left=Side(style="thin"), right=Side(style="thin"),
    top=Side(style="thin"), bottom=Side(style="thin")
)

for cell in ws_summary[1]:
    cell.fill = header_fill
    cell.font = header_font
    cell.alignment = header_align
    cell.border = thin_border

# 数据行样式
for row_idx, row in enumerate(ws_summary.iter_rows(min_row=2), start=1):
    fill_color = "D6E4F0" if row_idx % 2 == 0 else "FFFFFF"
    row_fill = PatternFill(start_color=fill_color, end_color=fill_color, fill_type="solid")
    for cell in row:
        cell.fill = row_fill
        cell.alignment = Alignment(horizontal="center", vertical="center")
        cell.border = thin_border
        if cell.column == 4:
            cell.number_format = "#,##0"

# 条件格式:前3名绿色高亮
ws_summary.conditional_formatting.add(
    "A2:A100",
    CellIsRule(operator="between", formula=["1""3"],
               fill=PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid"),
               font=Font(bold=True, color="375623"))
)

# 列宽自适应
for col in ws_summary.columns:
    max_len = max(len(str(cell.value or "")) for cell in col)
    ws_summary.column_dimensions[col[0].column_letter].width = min(max_len + 318)

# ===== 第四步:图表 =====
chart = BarChart()
chart.type = "col"
chart.style = 10
chart.title = "各销售员总销售额排名"
chart.y_axis.title = "销售额"
chart.x_axis.title = "销售员"

data = Reference(ws_summary, min_col=4, min_row=1, max_row=len(summary)+1)
cats = Reference(ws_summary, min_col=3, min_row=2, max_row=len(summary)+1)
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
chart.width = 18
chart.height = 10

ws_summary.add_chart(chart, "H2")

# ===== 第五步:明细数据 =====
ws_detail = wb.create_sheet("明细数据")
ws_detail.append(["日期""区域""销售员""产品""销售额""数量"])
for _, row in merged.sort_values(["区域""销售额"], ascending=[TrueFalse]).iterrows():
    ws_detail.append(list(row))

ws_detail.freeze_panes = "A2"

# ===== 保存 =====
output_file = "周报汇总报告.xlsx"
wb.save(output_file)
print(f"\n✅ 报告已生成: {output_file}")

执行结果:

销售排名汇总:
 排名  销售员  区域  总销售额
   1   王五   华东     34500
   2   赵六   华北     21300
   3   赵六   华南     17800
   4   李四   华北     17400
   5   张三   华东     12500
   6   张三   华南     10500
   7   李四   华东      7200

✅ 报告已生成: 周报汇总报告.xlsx

📌 最终文件包含三个 Sheet:「汇总」(含图表+条件格式+排名)「明细数据」「区域分布」。

运行效果:自动生成一个包含「汇总排名」「图表」「明细数据」三个 sheet 的 Excel 文件,打开即可直接使用。


第十三章:常用 Prompt 模板速查 {#ch13}

高频实战模板(直接复制改参数)

模板 A:多 Sheet 合并 + 汇总 + 美化

我的文件夹里有:华东.xlsx、华北.xlsx、华南.xlsx
每个文件结构相同(日期、销售员、产品、区域、销售额、数量)

请帮我:
1. 合并三个文件为一个总表,新增"区域"列
2. 按销售员汇总总销售额和总数量
3. 添加一列"排名"(按总销售额从高到低)
4. 表头格式:深蓝底、白色字体、加粗
5. 数据区:隔行变色(白/浅蓝)
6. 销售额超过15000的行,背景高亮为浅绿色
7. 保存为"周报汇总.xlsx"

模板 B:筛选 + 导出 + 格式化

帮我处理 customer.xlsx:
1. 筛选出"订单金额"大于 5000 的客户记录
2. 增加一列"等级":金额>20000为"VIP",5000-20000为"普通",<5000为"潜在"
3. 按金额降序排列
4. 格式:表头深蓝、奇偶行交替底色
5. 金额列格式:千分位分隔符
6. 保存为 customers_graded.xlsx

模板 C:VLOOKUP 匹配 + 汇总报表

我有两个文件:
- orders.xlsx:订单表(含客户ID、订单日期、订单金额)
- customers.xlsx:客户表(含客户ID、客户名、联系人、电话)

请帮我:
1. 在 orders.xlsx 中新增"客户名"、"联系人"、"电话"三列
   用 VLOOKUP 根据客户ID从 customers.xlsx 匹配
2. 按客户名汇总订单总金额
3. 生成汇总图表(柱状图,按总金额排序)
4. 保存为 orders_report.xlsx

常用条件表达对照

场景 怎么说
等于 “产品等于’电子产品'”、”区域是’华东'”
不等于 “产品不等于’办公用品'”
大于/小于 “销售额大于10000″、”数量小于5”
区间 “销售额在5000到15000之间”
包含 “产品名称包含’手机'”
多条件AND “产品=’电子产品’ 且 销售额>10000”
多条件OR “区域=’华东’ 或 区域=’华北'”

常见问题

Q:AI 生成的代码报错了怎么办?
A:把错误信息直接发给 AI,说:”上面这段代码运行时报错,错误信息是 [粘贴错误],请帮我修复。”

Q:文件很大,AI 处理慢怎么办?
A:告诉 AI 只读取前 N 行先处理,确认没问题再处理全量。或者让 AI 分批处理。

Q:我不确定要怎么处理,只知道最终要什么结果?
A:直接把文件发给 AI,说:”我有一个 [描述文件内容],我最终想要 [描述目标],你帮我想想应该怎么做,然后执行。”


第十四章:Skill 进阶——XML 源码级处理 {#ch14}

本章面向需要深度定制的读者。理解 minimax-xlsx Skill 的底层工作原理。

14.1 什么是 minimax-xlsx

minimax-xlsx 是一个用 XML 方式处理 Excel 文件的技能。特点:

  • XML 优先:直接操作 Excel 内部 XML,不走 openpyxl round-trip
  • 公式优先:所有计算结果必须是公式,不是硬编码数字
  • 零格式丢失:编辑时保留所有原始格式(VBA、透视表、图表均不受影响)
  • 财务标准:内置蓝(输入)、黑(公式)、绿(跨表)配色

14.2 为什么不用 openpyxl

# ❌ openpyxl round-trip 的问题
import openpyxl
wb = openpyxl.load_workbook("input.xlsx")  # 会丢失:VBA、透视表、sparklines
ws = wb.active
ws["A1"] = "新值"
wb.save("output.xlsx")  # 可能损坏原文件
# ✅ XML 方式:安全、无损
python3 xlsx_unpack.py input.xlsx /tmp/work/   # 解包
# 编辑 XML
python3 xlsx_pack.py /tmp/work/ output.xlsx   # 重新打包

14.3 五条处理管线

任务 方法 脚本
READ 读取分析数据 xlsx_reader.py + pandas
CREATE 从零创建 XML 模板
EDIT 编辑现有文件 XML unpack → edit → pack
FIX 修复损坏公式 XML unpack → fix → pack
VALIDATE 验证公式 formula_check.py

14.4 财务配色标准

Excel 财务建模的国际标准:

单元格类型 字体颜色 含义
蓝色 #0000FF 蓝色 硬编码输入/假设值
黑色 #000000 黑色 公式/计算结果
绿色 #00B050 绿色 跨表引用公式
蓝色(输入)  →  这是可以改动的原始数据
黑色(公式)  →  这是计算出来的结果
绿色(跨表)  →  引用其他工作表的数据

14.5 READ:读取分析现有 Excel

export SKILL_DIR="$HOME/skills/minimax-xlsx"
python3 $SKILL_DIR/scripts/xlsx_reader.py sales_data.xlsx

输出示例:

=== Workbook Structure ===
Sheets: ['Sales 2024', 'Summary', 'Charts']

=== Sheet: Sales 2024 ===
Dimensions: A1:G52
Columns: Date, Product, Region, Revenue, Cost, Profit, Margin

=== Column Types ===
A: datetime
B: string
C: string
D: number (2dp)
E: number (2dp)
F: formula
G: formula

14.6 CREATE:从零创建预算表

# Step 1: 克隆获取脚本
git clone https://github.com/MiniMax-AI/skills.git $HOME/skills

# Step 2: 解包模板
python3 $SKILL_DIR/scripts/xlsx_unpack.py template.xlsx /tmp/budget_work/

# Step 3: 编辑 XML(添加表头、输入值、公式)
# 在 xl/worksheets/sheet1.xml 中编辑单元格

# Step 4: 重新打包
python3 $SKILL_DIR/scripts/xlsx_pack.py /tmp/budget_work/ budget_2025.xlsx

# Step 5: 验证
python3 $SKILL_DIR/scripts/formula_check.py budget_2025.xlsx --report

14.7 EDIT:编辑现有表格添加公式

场景:现有表格有一列”数量”和一列”单价”,需要添加”金额”列。

⚠️ 这是 EDIT 任务,不是 CREATE! EDIT 任务规则:永远不要创建新的 Workbook(),只修改指定的单元格,原始数据必须完整保留。

# Step 1: 解包
python3 $SKILL_DIR/scripts/xlsx_unpack.py existing.xlsx /tmp/edit_work/

# Step 2: 找到目标工作表
cat /tmp/edit_work/xl/workbook.xml | grep name

# Step 3: 添加公式列
python3 $SKILL_DIR/scripts/xlsx_add_column.py /tmp/edit_work/ \
    --col D \
    --sheet "Sales Data" \
    --header "金额" \
    --formula '=B{row}*C{row}' \
    --formula-rows 2:50 \
    --numfmt '#,##0.00' \
    --border-row 51 \
    --border-style medium

# Step 4: 重新打包
python3 $SKILL_DIR/scripts/xlsx_pack.py /tmp/edit_work/ output.xlsx

# Step 5: 验证
python3 $SKILL_DIR/scripts/formula_check.py output.xlsx

14.8 EDIT:添加新行

场景:在”办公费用”行后面插入一行”通讯费”。

⚠️ 通过标签文本找到行,不是行号! Prompt 可能说”在第5行插入”,但实际第5行可能不是目标文本。必须先搜索文本定位行。

# Step 1: 解包
python3 $SKILL_DIR/scripts/xlsx_unpack.py budget.xlsx /tmp/insert_work/

# Step 2: 先找到 Office Rent 在哪一行
grep -n "Office Rent" /tmp/insert_work/xl/worksheets/sheet1.xml
# 说明 Office Rent 在第5行

# Step 3: 插入新行
python3 $SKILL_DIR/scripts/xlsx_insert_row.py /tmp/insert_work/ \
    --at 5 \
    --sheet "Budget FY2025" \
    --text A="通讯费" \
    --values B=3000 C=3000 D=3500 E=3500 \
    --formula 'F=SUM(B{row}:E{row})' \
    --copy-style-from 4

# Step 4: 重新打包
python3 $SKILL_DIR/scripts/xlsx_pack.py /tmp/insert_work/ budget_v2.xlsx

xlsx_insert_row.py 的智能之处:自动查找文本对应行、自动向下移动现有行、自动更新 SUM 公式(处理循环引用)、自动复制相邻行样式。

14.9 FIX:修复损坏公式

# 解包
python3 $SKILL_DIR/scripts/xlsx_unpack.py problem.xlsx /tmp/fix_work/

# 扫描报错
python3 $SKILL_DIR/scripts/formula_check.py problem.xlsx --report

输出示例:

=== Formula Validation Report ===
File: budget_v2.xlsx

✅ Exit Code: 0 - Safe to deliver

Formula Statistics:
  Total Formulas: 156
  Valid: 156
  Broken: 0
  Cross-sheet References: 12

Color Compliance:
  Blue (Input): 45 cells
  Black (Formula): 99 cells ✅
  Green (Cross-sheet): 12 cells ✅

Issues Found: None

常见公式错误及修复:

错误 原因 修复
#REF! 引用了不存在的单元格 检查公式中的范围
#DIV/0! 除以零 添加 IF 检查
#NAME? 函数名拼写错误 核对函数名
#VALUE! 类型不匹配 检查数据类型

14.10 快速命令参考

# 读取结构
python3 $SKILL_DIR/scripts/xlsx_reader.py file.xlsx

# 解包(编辑前必须)
python3 $SKILL_DIR/scripts/xlsx_unpack.py file.xlsx /tmp/work/

# 重新打包
python3 $SKILL_DIR/scripts/xlsx_pack.py /tmp/work/ output.xlsx

# 添加列
python3 $SKILL_DIR/scripts/xlsx_add_column.py /tmp/work/ --col G ...

# 插入行
python3 $SKILL_DIR/scripts/xlsx_insert_row.py /tmp/work/ --at 5 ...

# 验证公式
python3 $SKILL_DIR/scripts/formula_check.py file.xlsx --report

14.11 完整示例:月度财务汇总表

工作流程:
1. 读取四个周的周报 (READ)
2. 创建月度汇总表 (CREATE)
3. 添加跨表 SUM 公式 (EDIT)
4. 验证所有公式 (VALIDATE)
# Step 1: 分析周报
python3 xlsx_reader.py week1.xlsx
python3 xlsx_reader.py week2.xlsx
python3 xlsx_reader.py week3.xlsx
python3 xlsx_reader.py week4.xlsx

# Step 2: 创建月度表(基于 minimal_xlsx 模板)
cp -r templates/minimal_xlsx /tmp/monthly/
# 编辑 XML,添加月份标题和列头

# Step 3: 添加汇总公式
python3 xlsx_add_column.py /tmp/monthly/ --col E --header "月度合计" \
    --formula "=SUM('Week 1'!D{row}:'Week 4'!D{row})" \
    --formula-rows 2:32

# Step 4: 打包验证
python3 xlsx_pack.py /tmp/monthly/ monthly_summary.xlsx
python3 formula_check.py monthly_summary.xlsx --report

常见问题速查

问题 解决方案
打开文件提示”只读” 文件被其他程序占用,关闭后再运行
中文字体显示为方块 系统中安装对应字体,或在 openpyxl 中指定支持中文的字体(如”微软雅黑”)
公式没有自动计算 用 LibreOffice 重新保存,或用 Ctrl+Shift+F9 强制重算
读取大文件很慢 usecols 指定只读取需要的列:pd.read_excel(file, usecols=["销售额", "日期"])
合并时丢数据 检查各文件 sheet 名称是否一致,用 sheet_name=None 读取所有 sheet

💡 记住:数字要用公式,财务用配色,验证后再交付!

相关工具:pandas(数据分析)、openpyxl(格式与公式)、xlsxwriter(创建图表)、pyxlsb(读取 .xlsb)

完整代码获取:https://gitee.com/agent-now/hermes-workspace[3]

引用链接

[1]https://gitee.com/agent-now/hermes-workspace/blob/master/tutorials/excel-all-in-one.md

[2]十四章:XML 源码级处理: #ch14

[3]https://gitee.com/agent-now/hermes-workspace