第 16 章

Python + Excel——AI 驱动的数据分析升级

第16章:Python + Excel 自动化

Python 是世界上最流行的编程语言之一,也是处理 Excel 文件最强大的工具之一。当 VBA 遇到跨工作簿批量处理、大量文件自动化、与数据库或 API 集成等场景时,Python 才是真正的主角。本章核心思路依然是:不需要深入学 Python,AI 帮你写所有代码。 你只需要理解代码在做什么,会改几个参数,就能完成 90% 的 Excel 自动化需求。

为什么要用 Python 处理 Excel

VBA vs Python vs Power Query 的选择

场景 推荐工具 原因
在 Excel 内部做重复操作 VBA 无需安装额外软件,与 Excel 紧密集成
数据清洗和转换 Power Query 图形化操作,无需代码,适合 Excel 用户
处理数百个文件 Python 批量处理能力远超 VBA,速度快,不容易崩溃
复杂数据分析/统计 Python (pandas) pandas 的数据处理能力远超 Excel 函数
需要调用 API/数据库 Python VBA 做不到,Python 有丰富的库
与 AI 模型集成 Python 所有主流 AI API 都有 Python SDK
定时自动运行(无人值守) Python + 任务计划 可在服务器或后台运行,不需要打开 Excel

适合 Python 的典型场景

无需深入学 Python:AI 帮你写所有代码

本章的学习方式和第15章 VBA 一样:描述需求 → AI 写代码 → 复制运行 → 有问题告诉 AI 修复。 你需要了解的只是:代码大概在做什么,怎么改路径和参数。这章会把每个关键概念都用大白话解释清楚。

环境准备:5 分钟搞定

第一步:安装 Python(推荐 Anaconda)

Anaconda 是一个 Python 发行版,预装了数据科学常用的包(包括 pandas、numpy),对新手友好。安装步骤:

  1. 访问 anaconda.com,下载适合你操作系统的个人版(Individual Edition)
  2. 安装时勾选"Add Anaconda to PATH"选项(方便在命令行使用)
  3. 安装完成后,打开"Anaconda Prompt"(Windows)或"终端"(Mac),输入 python --version,看到版本号说明安装成功

如果不想安装 Anaconda,也可以从 python.org 下载标准 Python,安装后用 pip 管理包。

第二步:安装必要的库

在命令行/终端中运行(一行一行复制执行)

pip install openpyxl # 读写 Excel .xlsx 文件 pip install pandas # 数据处理神器 pip install xlrd # 读取旧版 .xls 文件(可选) pip install xlwings # 与正在打开的 Excel 交互(可选) pip install openpyxl pandas # 同时安装两个

如果使用 Anaconda,很多包已预装,只需:

pip install openpyxl

第三步:选择代码编辑器

用 AI 解决安装错误

我在 Windows 11 上用 pip install pandas 安装时报错:
[把完整错误信息粘贴在这里]

我用的是 Python 3.11,Anaconda 环境。请告诉我:
1. 这个错误是什么原因
2. 如何修复
3. 给我具体的命令行命令

openpyxl——操作 Excel 文件

openpyxl 是一个专门用于读写 Excel .xlsx 文件的 Python 库。它能让你像操作 Excel 一样用代码读取、写入、修改单元格,还能设置格式、插入图片、处理多个工作表。

核心概念(3 分钟理解)

openpyxl 的三层结构:

Workbook(工作簿)→ Worksheet(工作表)→ Cell(单元格)

wb = openpyxl.load_workbook("data.xlsx")   # 打开工作簿
ws = wb.active                              # 获取活动工作表
ws = wb["Sheet1"]                           # 按名称获取工作表

# 读取单元格
value = ws["A1"].value                      # 按地址读取
value = ws.cell(row=1, column=1).value      # 按行列号读取

# 写入单元格
ws["B2"].value = "Hello"
ws.cell(row=2, column=2).value = "Hello"

wb.save("output.xlsx")                      # 保存

案例1:批量读取100个 Excel 文件汇总到一张表

import openpyxl import os from pathlib import Path

def merge_excel_files(folder_path, output_path): """批量合并文件夹中所有 xlsx 文件""" folder = Path(folder_path) xlsx_files = list(folder.glob("*.xlsx"))

if not xlsx_files:
    print("没有找到 xlsx 文件!")
    return

output_wb = openpyxl.Workbook()
output_ws = output_wb.active
output_ws.title = "合并数据"

header_written = False
total_rows = 0

for file_path in xlsx_files:
    if file_path.name == Path(output_path).name:
        continue  # 跳过输出文件本身

    wb = openpyxl.load_workbook(file_path, data_only=True)
    ws = wb.active

    file_rows = list(ws.iter_rows(values_only=True))
    if not file_rows:
        continue

    if not header_written:
        # 写入表头(加上"来源文件"列)
        header = list(file_rows[0]) + ["来源文件"]
        output_ws.append(header)
        header_written = True

    # 写入数据行(跳过表头)
    for row in file_rows[1:]:
        output_ws.append(list(row) + [file_path.name])
        total_rows += 1

    print(f"已处理:{file_path.name}({len(file_rows) - 1} 行)")
    wb.close()

output_wb.save(output_path)
print(f"\n合并完成!共 {len(xlsx_files)} 个文件,{total_rows} 行数据。")
print(f"输出文件:{output_path}")

运行

merge_excel_files("C:/Reports/", "C:/Reports/merged_output.xlsx")

案例2:自动生成格式化报表

import openpyxl from openpyxl.styles import Font, PatternFill, Alignment, Border, Side from openpyxl.utils import get_column_letter

def create_formatted_report(data, output_path): """ data: 二维列表,第一行是表头,其余是数据 output_path: 输出文件路径 """ wb = openpyxl.Workbook() ws = wb.active ws.title = "报表"

# 写入数据
for row in data:
    ws.append(row)

# 定义样式
header_fill = PatternFill(start_color="1F4E79", end_color="1F4E79", fill_type="solid")
header_font = Font(bold=True, color="FFFFFF", size=11)
even_fill = PatternFill(start_color="D9E6F5", end_color="D9E6F5", fill_type="solid")
center_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 = center_align
    cell.border = thin_border

ws.row_dimensions[1].height = 28

# 应用数据行格式(交替底色)
for row_idx in range(2, ws.max_row + 1):
    for cell in ws[row_idx]:
        cell.border = thin_border
        if row_idx % 2 == 0:
            cell.fill = even_fill

# 自动调整列宽
for col_idx in range(1, ws.max_column + 1):
    col_letter = get_column_letter(col_idx)
    max_len = 0
    for cell in ws[col_letter]:
        if cell.value:
            max_len = max(max_len, len(str(cell.value)))
    ws.column_dimensions[col_letter].width = min(max_len + 4, 40)

wb.save(output_path)
print(f"报表已保存:{output_path}")

示例用法

sample_data = [ ["姓名", "部门", "薪资", "绩效"], ["张三", "销售部", 12000, "A"], ["李四", "市场部", 11000, "B"], ["王五", "技术部", 18000, "A"], ] create_formatted_report(sample_data, "formatted_report.xlsx")

案例3:批量插入图片到指定单元格

import openpyxl from openpyxl.drawing.image import Image import os

def insert_images_to_excel(excel_path, image_folder, output_path): """ 假设 Excel A列是产品ID,B列要放对应的产品图片 图片文件名格式:{产品ID}.png """ wb = openpyxl.load_workbook(excel_path) ws = wb.active

ws.column_dimensions["B"].width = 20  # 图片列宽

for row_idx in range(2, ws.max_row + 1):
    product_id = ws.cell(row=row_idx, column=1).value
    if not product_id:
        continue

    img_path = os.path.join(image_folder, f"{product_id}.png")
    if not os.path.exists(img_path):
        ws.cell(row=row_idx, column=2).value = "图片未找到"
        continue

    img = Image(img_path)
    img.width = 120   # 像素宽度
    img.height = 80   # 像素高度

    # 把图片锚定到 B 列对应行
    cell_addr = f"B{row_idx}"
    ws.add_image(img, cell_addr)
    ws.row_dimensions[row_idx].height = 65  # 行高适配图片

    print(f"已插入图片:产品 {product_id}")

wb.save(output_path)
print(f"完成!保存至:{output_path}")

案例4:批量生成工资条并拆分保存

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

def generate_individual_payslips(source_path, output_folder): """ 读取工资表,为每个员工生成独立的工资条文件 假设 A列=姓名,B列=部门,C列=薪资,D列=奖金,E列=实发 """ wb = openpyxl.load_workbook(source_path, data_only=True) ws = wb.active os.makedirs(output_folder, exist_ok=True)

header = [cell.value for cell in ws[1]]
thin = Border(
    left=Side(style="thin"), right=Side(style="thin"),
    top=Side(style="thin"), bottom=Side(style="thin")
)
header_fill = PatternFill(start_color="1F4E79", end_color="1F4E79", fill_type="solid")

count = 0
for row in ws.iter_rows(min_row=2, values_only=True):
    if not row[0]:  # 跳过空行
        continue

    emp_name = row[0]
    out_wb = openpyxl.Workbook()
    out_ws = out_wb.active
    out_ws.title = "工资条"

    # 标题
    out_ws.append(["工资条", "", "", "", ""])
    out_ws.merge_cells("A1:E1")
    title_cell = out_ws["A1"]
    title_cell.font = Font(bold=True, size=14)
    title_cell.alignment = Alignment(horizontal="center")

    # 表头行
    out_ws.append(header)
    for cell in out_ws[2]:
        cell.fill = header_fill
        cell.font = Font(bold=True, color="FFFFFF")
        cell.border = thin
        cell.alignment = Alignment(horizontal="center")

    # 数据行
    out_ws.append(list(row))
    for cell in out_ws[3]:
        cell.border = thin

    # 自动列宽
    for col_idx in range(1, len(header) + 1):
        from openpyxl.utils import get_column_letter
        col_letter = get_column_letter(col_idx)
        out_ws.column_dimensions[col_letter].width = 14

    # 保存为 "姓名_工资条.xlsx"
    safe_name = str(emp_name).replace("/", "_").replace("\\", "_")
    out_path = os.path.join(output_folder, f"{safe_name}_工资条.xlsx")
    out_wb.save(out_path)
    count += 1

print(f"工资条生成完成!共 {count} 份,保存在:{output_folder}")

案例5:AI 帮你写 openpyxl 代码

pandas——数据处理神器

pandas 是 Python 最重要的数据处理库,没有之一。它的核心数据结构 DataFrame 就是一张二维表——把 Excel 表格读进来就变成 DataFrame,然后可以用代码对它做任何操作:筛选、排序、去重、分组统计、合并……完成后再导出成 Excel。

DataFrame 概念:把 Excel 表当数据库用

import pandas as pd

读取 Excel 文件(返回 DataFrame,就像一张内存中的 Excel 表)

df = pd.read_excel("sales.xlsx", sheet_name="Sheet1")

查看基本信息

print(df.shape) # (行数, 列数) print(df.columns) # 列名列表 print(df.head(5)) # 前5行数据 print(df.dtypes) # 每列的数据类型 print(df.describe()) # 数值列的统计摘要(均值/最大/最小等)

访问数据

df["姓名"] # 获取"姓名"列(返回 Series) df[["姓名", "薪资"]] # 获取多列(返回 DataFrame) df.iloc[0] # 第一行(按位置) df.loc[df["部门"] == "销售部"] # 按条件筛选行

保存回 Excel

df.to_excel("output.xlsx", index=False, sheet_name="结果")

案例1:合并12个 CSV 文件(pd.concat)

import pandas as pd import glob import os

def merge_csv_files(folder_path, output_path): """合并文件夹中所有 CSV 文件(或 xlsx)""" # 找到所有 csv 文件 csv_files = glob.glob(os.path.join(folder_path, "*.csv"))

if not csv_files:
    print("没有找到 CSV 文件!")
    return

all_dfs = []
for file in csv_files:
    df = pd.read_csv(file, encoding="utf-8-sig")  # utf-8-sig 处理中文 BOM
    df["来源文件"] = os.path.basename(file)        # 记录来源
    all_dfs.append(df)
    print(f"已读取:{os.path.basename(file)}({len(df)} 行)")

# 纵向合并所有 DataFrame
merged_df = pd.concat(all_dfs, ignore_index=True)

# 保存为 Excel
merged_df.to_excel(output_path, index=False)
print(f"\n合并完成!共 {len(all_dfs)} 个文件,{len(merged_df)} 行数据。")
print(f"输出:{output_path}")

运行

merge_csv_files("C:/MonthlyData/", "C:/MonthlyData/merged_all.xlsx")

案例2:数据清洗(去重 / 填充空值 / 类型转换)

import pandas as pd

def clean_data(input_path, output_path): """标准化的数据清洗流程""" df = pd.read_excel(input_path) original_rows = len(df)

print(f"原始数据:{original_rows} 行")
print(f"空值统计:\n{df.isnull().sum()}")

# 1. 删除完全重复的行
df = df.drop_duplicates()
print(f"去重后:{len(df)} 行(删除了 {original_rows - len(df)} 条重复)")

# 2. 填充空值
df["部门"].fillna("未分配", inplace=True)       # 文字列:填"未分配"
df["薪资"].fillna(df["薪资"].median(), inplace=True)  # 数值列:填中位数

# 3. 类型转换(确保薪资是数字)
df["薪资"] = pd.to_numeric(df["薪资"], errors="coerce")

# 4. 去掉姓名列的首尾空格
df["姓名"] = df["姓名"].str.strip()

# 5. 日期格式标准化
df["入职日期"] = pd.to_datetime(df["入职日期"], errors="coerce")

# 6. 删除关键字段仍为空的行
df = df.dropna(subset=["姓名", "薪资"])

print(f"清洗后:{len(df)} 行")
df.to_excel(output_path, index=False)
print(f"已保存:{output_path}")

clean_data("raw_hr_data.xlsx", "cleaned_hr_data.xlsx")

案例3:分组统计(groupby,相当于透视表)

import pandas as pd

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

按部门统计薪资(均值/最大/最小/人数)

dept_summary = df.groupby("部门")["薪资"].agg( 平均薪资="mean", 最高薪资="max", 最低薪资="min", 人数="count" ).round(0).reset_index()

多列分组:按部门和职级统计

dept_level = df.groupby(["部门", "职级"]).agg( 平均薪资=("薪资", "mean"), 总人数=("姓名", "count"), 总薪资=("薪资", "sum") ).round(0).reset_index()

按月份统计销售额(透视表效果)

假设有"月份"列和"销售额"列

monthly = df.groupby("月份")["销售额"].sum().reset_index() monthly.columns = ["月份", "月销售额"] monthly["环比增长%"] = monthly["月销售额"].pct_change().round(4) * 100

把多个统计结果写到同一个 Excel 的不同 Sheet

with pd.ExcelWriter("statistics_report.xlsx", engine="openpyxl") as writer: dept_summary.to_excel(writer, sheet_name="部门薪资汇总", index=False) dept_level.to_excel(writer, sheet_name="部门职级明细", index=False) monthly.to_excel(writer, sheet_name="月度销售趋势", index=False)

print("统计报告已生成:statistics_report.xlsx")

案例4:多条件筛选后导出

import pandas as pd

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

单条件筛选

sales_dept = df[df["部门"] == "销售部"]

AND 条件(多条件同时满足)

high_earner_sales = df[(df["部门"] == "销售部") & (df["薪资"] > 10000)]

OR 条件(满足任意一个)

multi_dept = df[(df["部门"] == "销售部") | (df["部门"] == "市场部")]

包含某字符串(模糊匹配)

managers = df[df["职位"].str.contains("经理", na=False)]

日期范围筛选

df["入职日期"] = pd.to_datetime(df["入职日期"]) recent_hires = df[ (df["入职日期"] >= "2023-01-01") & (df["入职日期"] 8000) & (df["入职日期"].dt.year == 2023) ]

导出结果

result.to_excel("filtered_result.xlsx", index=False) print(f"筛选结果:{len(result)} 条记录")

案例5:AI 帮你写 pandas 数据处理代码

自动化工作流案例(完整项目)

案例1:每天自动下载数据 → 处理 → 生成报表 → 发邮件

import pandas as pd import openpyxl from openpyxl.styles import Font, PatternFill import smtplib from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.text import MIMEText from email import encoders import os from datetime import date

def daily_report_pipeline(): """每日数据报表自动化流程""" today = date.today().strftime("%Y-%m-%d") print(f"[{today}] 开始生成日报...")

# ========== 步骤1:读取源数据 ==========
# 实际场景可替换为:pd.read_sql(sql, connection) 从数据库读取
# 或 pd.read_csv(url) 从 URL 读取在线数据
source_path = f"C:/DailyData/raw_{today}.xlsx"
if not os.path.exists(source_path):
    print(f"错误:源文件不存在:{source_path}")
    return

df = pd.read_excel(source_path)
print(f"读取数据:{len(df)} 行")

# ========== 步骤2:数据处理 ==========
df = df.drop_duplicates()
df["销售额"] = pd.to_numeric(df["销售额"], errors="coerce").fillna(0)
df["日期"] = pd.to_datetime(df["日期"], errors="coerce")

# 按部门汇总
dept_summary = df.groupby("部门").agg(
    订单数=("订单号", "count"),
    总销售额=("销售额", "sum"),
    平均单价=("销售额", "mean")
).round(2).reset_index()

# 找出今日 Top 5 销售员
top_sales = df.groupby("销售员")["销售额"].sum().nlargest(5).reset_index()
top_sales.columns = ["销售员", "今日销售额"]

# ========== 步骤3:生成格式化 Excel 报表 ==========
output_path = f"C:/Reports/日报_{today}.xlsx"
with pd.ExcelWriter(output_path, engine="openpyxl") as writer:
    dept_summary.to_excel(writer, sheet_name="部门汇总", index=False)
    top_sales.to_excel(writer, sheet_name="Top5销售员", index=False)
    df.to_excel(writer, sheet_name="原始明细", index=False)

print(f"报表已生成:{output_path}")

# ========== 步骤4:发送邮件 ==========
send_report_email(
    recipients=["[email protected]", "[email protected]"],
    subject=f"每日销售报表 {today}",
    body=f"请查收 {today} 的每日销售报表,详见附件。\n\n"
         f"今日汇总:共 {len(df)} 条订单,"
         f"总销售额 ¥{df['销售额'].sum():,.2f}",
    attachment_path=output_path
)

def send_report_email(recipients, subject, body, attachment_path): """发送带附件的邮件(使用 SMTP)""" smtp_server = "smtp.company.com" # 替换为你的 SMTP 服务器 smtp_port = 587 sender_email = "[email protected]" sender_password = os.environ.get("EMAIL_PASSWORD", "") # 密码从环境变量读取

msg = MIMEMultipart()
msg["From"] = sender_email
msg["To"] = ", ".join(recipients)
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain", "utf-8"))

# 添加附件
if attachment_path and os.path.exists(attachment_path):
    with open(attachment_path, "rb") as f:
        part = MIMEBase("application", "octet-stream")
        part.set_payload(f.read())
    encoders.encode_base64(part)
    part.add_header(
        "Content-Disposition",
        f'attachment; filename="{os.path.basename(attachment_path)}"'
    )
    msg.attach(part)

try:
    with smtplib.SMTP(smtp_server, smtp_port) as server:
        server.starttls()
        server.login(sender_email, sender_password)
        server.send_message(msg)
    print(f"邮件已发送至:{', '.join(recipients)}")
except Exception as e:
    print(f"邮件发送失败:{e}")

运行

daily_report_pipeline()

案例2:批量处理文件夹里的所有 Excel 文件

import pandas as pd import glob import os from pathlib import Path

def batch_process_folder(input_folder, output_folder): """ 批量处理文件夹中所有 xlsx 文件 每个文件:数据清洗 + 计算新列 + 保存到输出文件夹 """ input_folder = Path(input_folder) output_folder = Path(output_folder) output_folder.mkdir(parents=True, exist_ok=True)

xlsx_files = list(input_folder.glob("*.xlsx"))
print(f"发现 {len(xlsx_files)} 个文件待处理...")

success_count = 0
error_count = 0

for file_path in xlsx_files:
    try:
        df = pd.read_excel(file_path)

        # ---- 在这里添加你的处理逻辑 ----
        # 示例:清洗 + 计算总金额
        df = df.drop_duplicates()
        df["数量"] = pd.to_numeric(df["数量"], errors="coerce").fillna(0)
        df["单价"] = pd.to_numeric(df["单价"], errors="coerce").fillna(0)
        df["总金额"] = df["数量"] * df["单价"]
        df = df[df["数量"] > 0]  # 过滤无效行
        # ---- 处理逻辑结束 ----

        output_path = output_folder / file_path.name
        df.to_excel(output_path, index=False)
        success_count += 1
        print(f"  ✓ {file_path.name} → {len(df)} 行")

    except Exception as e:
        error_count += 1
        print(f"  ✗ {file_path.name} 处理失败:{e}")

print(f"\n处理完成:成功 {success_count} 个,失败 {error_count} 个")
print(f"输出目录:{output_folder}")

batch_process_folder("C:/InputFiles/", "C:/OutputFiles/")

案例3:对比两个 Excel 文件的差异

import pandas as pd

def compare_excel_files(file1_path, file2_path, key_column, output_path): """ 对比两个 Excel 文件的差异 key_column:用于匹配两个文件中相同行的键列(如"员工ID") """ df1 = pd.read_excel(file1_path).set_index(key_column) df2 = pd.read_excel(file2_path).set_index(key_column)

# 找出新增行(在 df2 中有,df1 中没有)
new_rows_idx = df2.index.difference(df1.index)
new_rows = df2.loc[new_rows_idx].copy()
new_rows["变更类型"] = "新增"

# 找出删除行(在 df1 中有,df2 中没有)
deleted_rows_idx = df1.index.difference(df2.index)
deleted_rows = df1.loc[deleted_rows_idx].copy()
deleted_rows["变更类型"] = "删除"

# 找出修改行(两个文件都有,但内容不同)
common_idx = df1.index.intersection(df2.index)
df1_common = df1.loc[common_idx]
df2_common = df2.loc[common_idx]

# 找出两个 DataFrame 中不同的行
diff_mask = (df1_common != df2_common).any(axis=1)
changed_idx = common_idx[diff_mask]

changed_rows_list = []
for idx in changed_idx:
    for col in df1_common.columns:
        if col in df2_common.columns:
            val1 = df1_common.at[idx, col]
            val2 = df2_common.at[idx, col]
            if val1 != val2:
                changed_rows_list.append({
                    key_column: idx,
                    "字段": col,
                    "原值": val1,
                    "新值": val2,
                    "变更类型": "修改"
                })

changed_df = pd.DataFrame(changed_rows_list)

# 输出到 Excel
with pd.ExcelWriter(output_path, engine="openpyxl") as writer:
    if not new_rows.empty:
        new_rows.reset_index().to_excel(writer, sheet_name="新增", index=False)
    if not deleted_rows.empty:
        deleted_rows.reset_index().to_excel(writer, sheet_name="删除", index=False)
    if not changed_df.empty:
        changed_df.to_excel(writer, sheet_name="修改明细", index=False)

print(f"差异分析完成:新增 {len(new_rows)} 行,删除 {len(deleted_rows)} 行,修改 {len(changed_df)} 处")
print(f"报告已保存:{output_path}")

运行示例

compare_excel_files( "employee_2024_Q1.xlsx", "employee_2024_Q2.xlsx", key_column="员工ID", output_path="diff_report.xlsx" )

案例4:AI 帮你把手动流程转为 Python 脚本

我每周需要手动完成以下操作,请帮我写一个 Python 脚本自动完成:

手动流程(按步骤描述):
1. 打开 "C:/WeeklyData/" 文件夹,找到本周所有日期命名的 xlsx 文件(格式:YYYY-MM-DD.xlsx)
2. 把这7个文件的第一个工作表的数据合并到一张表里
3. 删除"状态"列值为"取消"的行
4. 按"销售员"分组,计算每人本周的"销售额"总和和"订单数"
5. 按"销售额总和"从高到低排序
6. 在第一列加上排名(1, 2, 3...)
7. 把结果保存为 "C:/WeeklyReports/周报_YYYY年第W周.xlsx"
8. 用邮件把文件发给 [email protected],邮件主题包含本周时间范围

数据结构:表头在第一行,字段包括:日期、销售员、产品、数量、单价、销售额、状态

请写完整的可运行 Python 脚本,包含必要的 import 语句和错误处理。

常见错误与调试

Python 处理 Excel 时的高频错误

错误信息 通常原因 快速解决
FileNotFoundError 文件路径不存在或拼写错误 检查路径,用 os.path.exists() 验证,Windows 路径用 \ 或原始字符串 r"C:\path"
KeyError: '列名' DataFrame 中没有这个列名 先 print(df.columns) 查看实际列名,注意空格和大小写
UnicodeDecodeError CSV 文件编码不匹配 read_csv 加 encoding="utf-8-sig" 或 encoding="gbk"
ValueError: Excel file format cannot be determined 文件损坏或不是真正的 xlsx 用 openpyxl 单独打开验证,或重新保存文件
PermissionError 文件被 Excel 或其他程序打开中 关闭 Excel 中打开的该文件
ModuleNotFoundError 库未安装 执行 pip install 库名

Python + Excel 速查表

操作 代码
读取 Excel(pandas) df = pd.read_excel("file.xlsx")
读取指定 Sheet df = pd.read_excel("file.xlsx", sheet_name="Sheet1")
保存到 Excel df.to_excel("out.xlsx", index=False)
写多个 Sheet with pd.ExcelWriter("out.xlsx") as w: df.to_excel(w, sheet_name="S1")
读取 CSV(含中文) df = pd.read_csv("file.csv", encoding="utf-8-sig")
查看列名 df.columns.tolist()
筛选行 df[df["列"] == "值"]
去重 df.drop_duplicates()
填充空值 df["列"].fillna("默认值")
分组统计 df.groupby("列")["值"].agg(["sum","mean","count"])
合并多个 DataFrame pd.concat([df1, df2], ignore_index=True)
左连接 pd.merge(df1, df2, on="ID", how="left")
列类型转换 df["列"] = pd.to_numeric(df["列"], errors="coerce")
日期解析 df["日期"] = pd.to_datetime(df["日期"])
遍历所有文件 glob.glob(os.path.join(folder, "*.xlsx"))
打开 openpyxl 工作簿 wb = openpyxl.load_workbook("file.xlsx")
新建 openpyxl 工作簿 wb = openpyxl.Workbook()
获取工作表 ws = wb["Sheet1"] 或 ws = wb.active
读写单元格 ws["A1"].value = "x" / val = ws["A1"].value
遍历行 for row in ws.iter_rows(min_row=2, values_only=True):

✅ Tip

本章核心总结:

Python 是 Excel 自动化的终极工具,尤其适合跨文件批处理、复杂数据处理和定时自动化。openpyxl 负责精细的 Excel 文件操作,pandas 负责大规模数据处理。两者结合,配合 AI 生成代码,几乎可以完成任何 Excel 自动化任务。记住:描述清楚需求 → AI 写代码 → 复制运行 → 错误给 AI 修复。

上一章 ← 第15章:VBA 入门 下一章 第17章:AI 驱动的 Excel 工作流 →

本章评分
4.5  / 5  (14 评分)

💬 留言讨论