Python批量提取Excel工作簿中所有工作表的唯一值

 更新时间:2026年07月01日 08:59:44   作者:杨利杰YJlio  
本文详细讲解了使用Python批量提取Excel工作簿中所有工作表的唯一值值,并介绍了其适用场景、核心原理及常见问题,强调输出结果验证的重要性,适合办公自动化初学者学习

1. 问题背景:为什么要批量提取所有工作表的唯一值

本文主题是 批量提取一个工作簿中所有工作表的唯一值。这个案例看起来像是“去重”,但在真实办公场景里,它经常对应一个很高频的需求:从多个 sheet 中整理出一份标准清单。

比如一个工作簿里有 1 月、2 月、3 月、4 月等多个销售表,每张表里都有“产品名称”这一列。现在我们不关心每一行销量,只想整理出这个工作簿里出现过哪些产品。手工做法通常是:逐个 sheet 复制产品列,粘贴到一张新表,再使用 Excel 的“删除重复项”。如果 sheet 很多、文件很大,这个过程既慢,也容易漏。

这张图展示了本文的核心目标:用 Python + Excel 自动化,从一个工作簿的所有工作表中提取唯一值,并输出为一份清单。

从这张图中我们可以看出,数据来源不是单个工作表,而是一个工作簿内的多个工作表。程序会从多个 sheet 中收集“产品名称”,经过汇总、去重后,生成右侧的“产品名称清单”。这就是本文最核心的自动化链路:多表扫描 → 列数据收集 → 去重 → 写入新工作簿。

原理说明:这类任务的本质不是“操作 Excel 界面”,而是把 Excel 表格看成结构化数据:工作簿是容器,工作表是数据块,目标列是字段,唯一值清单是最终输出。

2. 适用场景:什么时候适合用这个脚本

这个脚本最适合用于“多个工作表结构类似,并且都包含同一个目标列”的场景。比如每个月一张销售表,每个部门一张人员表,每个区域一张客户表,只要表头字段一致,就可以批量提取某一列的唯一值。

这张图展示了一个典型场景:多张月度销售表中都有产品名称,现在需要整理出一份产品名称清单。

从这张图中我们可以看出,1 月、2 月、3 月、4 月这些工作表中都存在重复产品名称,例如“背包”“水杯”“钱包”“耳机”等。最终我们并不需要重复记录,而是只需要一份去重后的产品清单。这种场景如果靠复制粘贴,操作步骤很机械;用 Python 处理,则可以一次性完成。

适合使用这个方法的场景包括:

1. 从多张销售表中提取产品名称清单;

2. 从多个部门表中提取员工姓名清单;

3. 从多个客户表中提取客户名称清单;

4. 从多个设备表中提取型号、城市、部门、资产类别等去重字段。

限制条件:如果每张工作表的表头名称不统一,例如有的叫“产品名称”,有的叫“商品名称”,有的叫“产品名”,脚本就需要额外做字段映射,否则会漏掉部分工作表。

推荐做法:正式运行前,先统一表头字段。如果业务表格确实来源混乱,也可以在代码里维护一个候选字段列表,例如 ["产品名称", "商品名称", "产品名"],逐个匹配。

3. 核心原理:set() 去重 + 纵向写入 Excel

这一节真正要理解的不是某一行代码,而是数据从“重复列表”变成“唯一值清单”的过程。脚本会先把所有工作表中的目标列数据收集到一个列表里,这个列表允许重复;然后用 set() 去掉重复值;最后再写入新的 Excel 工作簿。

这张图展示了本文的关键原理:左侧是含重复的原始数据,中间通过 set() 去重,右侧得到唯一值清单,并通过纵向写入方式输出到 Excel。

从这张图中我们可以看出,原始数据中“背包”“行李箱”等值可能出现多次,但经过 set() 后,每个值只保留一份。随后使用 insert(0, 表头) 在列表最前面加入表头,再用 options(transpose=True) 按列纵向写入 Excel。

原理说明:set 的特点是天然不允许重复元素,所以它非常适合做唯一值提取。但 set 去重后默认不保证原始顺序,因此如果希望输出结果更整齐,通常会再配合 sorted() 做排序。

values = ["背包", "行李箱", "背包", "钱包", "水杯", "行李箱"]

unique_values = list(set(values))
unique_values = sorted(unique_values)

unique_values.insert(0, "产品名称")

注意:如果你需要保留“第一次出现的顺序”,不要直接依赖 set()。可以使用 dict.fromkeys() 保留原始顺序。

values = ["背包", "行李箱", "背包", "钱包", "水杯", "行李箱"]

unique_values = list(dict.fromkeys(values))

这两个写法没有绝对谁更好。set() 简单直接,适合只关心唯一值;dict.fromkeys() 更适合保留原始出现顺序。真实写脚本时,要根据业务结果选择。

4. 实现流程:遍历、收集、去重、写入

在写代码之前,先把流程拆开看。这个案例可以分成四步:遍历工作表、收集目标列、去重、写入新工作簿。只要这四步理解清楚,后面的代码就不难。

这张图展示了完整执行流程:从左侧多工作表开始,经过目标列收集和 set() 去重,最后写入新的工作簿。

从这张图中我们可以看出,脚本不是直接“删除重复项”,而是先把每张表的目标列值全部收集起来,再统一去重。这个顺序很重要:先完整收集,再统一处理,比边遍历边零散处理更清晰,也更方便排查问题。

推荐做法:第一次运行脚本时,建议先打印每张工作表是否命中目标列,以及提取到了多少个值。这样能快速发现表头不一致、空表、隐藏表等问题。

5. 完整代码:xlwings 批量提取唯一值

下面是一个完整可运行版本。这个版本会遍历源工作簿中的所有工作表,查找指定表头列,把该列非空值收集起来,去除重复后输出到新的 Excel 文件中。

import xlwings as xw

# ====== 需要根据实际情况修改的参数 ======
file_path = r"e:\file\销售数据.xlsx"       # 源工作簿
target_col = "产品名称"                    # 要提取唯一值的列名
out_file = r"e:\file\产品名称清单.xlsx"    # 输出文件
# =====================================

app = xw.App(visible=False, add_book=False)

try:
    wb = app.books.open(file_path)

    all_values = []

    for sht in wb.sheets:
        table = sht.range("A1").current_region.value

        if not table or len(table) < 2:
            print(f"跳过:{sht.name},没有可处理的数据")
            continue

        header = table[0]
        rows = table[1:]

        if target_col not in header:
            print(f"跳过:{sht.name},未找到列:{target_col}")
            continue

        col_idx = header.index(target_col)
        count = 0

        for row in rows:
            if col_idx >= len(row):
                continue

            value = row[col_idx]

            if value is None or str(value).strip() == "":
                continue

            all_values.append(str(value).strip())
            count += 1

        print(f"已读取:{sht.name},提取 {count} 个值")

    wb.close()

    # 去重并排序
    unique_values = sorted(list(set(all_values)))

    # 插入表头
    unique_values.insert(0, target_col)

    # 写入新工作簿
    out_wb = app.books.add()
    out_sht = out_wb.sheets[0]
    out_sht.name = "唯一值清单"

    # 按列纵向写入
    out_sht.range("A1").options(transpose=True).value = unique_values
    out_sht.autofit()

    out_wb.save(out_file)
    out_wb.close()

    print(f"清单生成完成:{out_file}")
    print(f"唯一值数量:{len(unique_values) - 1}")

finally:
    app.quit()

这段代码里最关键的是 all_values.append(str(value).strip())。我在这里做了两个处理:第一,把值转成字符串,避免不同类型混在一起;第二,使用 strip() 去掉前后空格,避免“背包”和“背包 ”被识别成两个不同值。

风险提醒:如果你的目标列里既有纯数字,又有文本编号,比如 001、1、1.0,直接转字符串可能会影响结果判断。遇到编号类字段时,要先确认 Excel 中的真实数据格式。

原理说明:out_sht.range("A1").options(transpose=True).value = unique_values 的作用是把 Python 列表纵向写入 Excel。如果不加 transpose=True,列表默认会横向写入一行,不符合清单类表格的阅读习惯。

6. 效果验证:清单生成不代表结果一定正确

脚本运行完成后,不要只看控制台是否提示成功。对唯一值提取任务来说,真正要验证的是:目标列是否全部扫描到了,空值是否正确排除,重复值是否真正去掉,输出清单数量是否符合预期。

我一般会从三个角度验证:

第一,检查每个 sheet 是否都被读取。控制台输出里应该能看到每张工作表的处理情况。如果某张表提示“未找到列”,就要回头看表头是否写错。

第二,检查唯一值数量。如果原数据里大概只有 20 个产品,结果输出了 200 个,那大概率是字段里有空格、错别字、编码差异或表头选错了。

第三,打开输出文件,确认清单是纵向排列,并且第一行有表头。如果表头缺失,后续别人拿到这个文件时会不知道这一列代表什么。

print(f"原始收集值数量:{len(all_values)}")
print(f"去重后唯一值数量:{len(unique_values) - 1}")

推荐做法:如果是正式交付文件,可以额外输出一份“处理日志”,记录每张工作表读取到多少条数据、是否存在目标列、最终唯一值数量是多少。这样后续别人质疑结果时,可以回溯。

7. 举一反三:唯一值后再做统计汇总

提取唯一值只是第一层能力。很多时候,业务真正要的不是“有哪些产品”,而是“每个产品的销量是多少”。这时就要从 set() 去重升级到 dict 统计。

这张图展示了进阶思路:先从多个工作表中提取产品名称,再用字典累计销量,最后输出产品销量汇总表。

从这张图中我们可以看出,set() 适合回答“有哪些”,而 dict 更适合回答“每个有多少”。如果只做唯一值清单,输出结果只有产品名称;如果继续做统计汇总,就可以得到“产品名称 + 累计销量”的报表。

下面是一个按“产品名称”累计“销量”的示例:

import xlwings as xw

file_path = r"e:\file\销售数据.xlsx"
col_product = "产品名称"
col_qty = "销量"
out_file = r"e:\file\产品销量汇总.xlsx"

app = xw.App(visible=False, add_book=False)

try:
    wb = app.books.open(file_path)

    stat = {}

    for sht in wb.sheets:
        table = sht.range("A1").current_region.value

        if not table or len(table) < 2:
            continue

        header = table[0]
        rows = table[1:]

        if col_product not in header or col_qty not in header:
            continue

        idx_p = header.index(col_product)
        idx_q = header.index(col_qty)

        for row in rows:
            if idx_p >= len(row) or idx_q >= len(row):
                continue

            product = row[idx_p]
            qty = row[idx_q]

            if product is None or str(product).strip() == "":
                continue

            product = str(product).strip()

            if qty is None or qty == "":
                qty = 0

            qty = float(qty)

            stat[product] = stat.get(product, 0) + qty

    wb.close()

    out_wb = app.books.add()
    out_sht = out_wb.sheets[0]
    out_sht.name = "产品销量汇总"

    out_sht.range("A1").value = [["产品名称", "累计销量"]]

    result = sorted(stat.items(), key=lambda x: x[0])
    out_sht.range("A2").value = result
    out_sht.autofit()

    out_wb.save(out_file)
    out_wb.close()

    print(f"统计完成:{out_file}")
    print(f"产品数量:{len(stat)}")

finally:
    app.quit()

原理说明:stat.get(product, 0) + qty 是字典累计的常用写法。如果产品第一次出现,就从 0 开始累计;如果已经出现过,就在原有销量基础上继续加。

注意:统计金额、销量、数量这类字段时,一定要确认数据能转成数字。如果单元格里混入“无”“-”“N/A”等文本,float() 会报错,需要提前清洗。

8. 常见问题与踩坑记录

这个案例虽然代码不长,但真实使用时容易踩几个坑。第一个坑是表头不一致。脚本是按表头名称查找列索引的,如果表头写错,代码不会自动知道你想要哪一列。

坑 1:目标列不存在。如果某张工作表没有“产品名称”列,脚本会跳过。这个行为本身没问题,但你必须知道它跳过了哪些表。否则最后清单少数据,你还以为脚本正常完成了。

坑 2:空格导致重复。“背包”和“背包 ”肉眼看起来差不多,但程序会认为是两个不同值。所以读取时建议统一使用 strip()。

坑 3:set 去重后顺序变化。如果你希望结果按字母、拼音或原始顺序展示,不能只写 list(set(values))。可以使用 sorted() 排序,或者使用 dict.fromkeys() 保留首次出现顺序。

坑 4:隐藏工作表也会被遍历。如果工作簿中存在隐藏 sheet,for sht in wb.sheets 也可能遍历到。正式场景下要确认是否需要处理隐藏表。

for sht in wb.sheets:
    print(sht.name)

推荐做法:处理正式文件前先复制一份测试文件,避免脚本写入异常影响原始数据。虽然本文主要是读取源文件、输出新文件,但养成备份习惯没有坏处。

9. 总结提升:把“唯一值提取”变成通用清单工具

这一节的核心,不是记住 set() 这个函数,而是掌握一种清单类自动化思路:从多个工作表中提取目标列,统一收集,去重处理,最后输出为标准清单。

这类脚本非常适合沉淀成通用工具。只要把源文件路径、目标列名、输出文件路径做成参数,就可以复用到产品清单、客户清单、部门清单、城市清单、设备型号清单等多个场景。

我认为这篇笔记最值得留下来的经验有三点。

第一,先明确目标列。脚本不是魔法,它只能按你指定的字段提取数据。字段选错,结果一定错。

第二,先清洗再去重。去重之前要处理空格、空值、类型差异,否则输出清单看似去重,实际仍然混乱。

第三,输出后必须验证。唯一值数量、表头、纵向写入格式、是否遗漏工作表,这些都要检查。自动化不是跑完就结束,而是要能交付、能复查、能复用。

从办公自动化学习路径看,这一节已经从“操作 Excel”进入了“整理数据结构”的阶段。后续如果继续扩展,可以把唯一值提取、分类统计、数据汇总、异常值检查组合起来,形成一个真正可用的 Excel 数据清洗工具箱。

以上就是Python批量提取Excel工作簿中所有工作表的唯一值的详细内容,更多关于Python提取Excel工作表唯一值的资料请关注脚本之家其它相关文章!

相关文章

  • Python使用coloredlogso库打造彩色日志的全攻略

    Python使用coloredlogso库打造彩色日志的全攻略

    想象一下,当你的服务突然报错时,在一堆灰色文本中快速定位到那个鲜红的ERROR信息,能节省多少排查时间?这就是coloredlogs库的价值所在,下面我们就来看看它的具体使用吧
    2026-02-02
  • 浅析Python WSGI的使用

    浅析Python WSGI的使用

    WSGI也称之为web服务器通用网关接口,全称是web server gateway interface。这篇文章主要为大家介绍了Python WSGI的使用,希望对大家有所帮助
    2023-04-04
  • 强烈推荐好用的python库合集(全面总结)

    强烈推荐好用的python库合集(全面总结)

    这篇文章主要为大家介绍了强烈推荐非常好用的python库合集(全面总结),有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • python机器学习基础线性回归与岭回归算法详解

    python机器学习基础线性回归与岭回归算法详解

    这篇文章主要为大家介绍了python机器学习基础线性回归与岭回归算法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Python之Sklearn使用入门教程

    Python之Sklearn使用入门教程

    这篇文章主要介绍了Python之Sklearn使用入门教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • python实现颜色rgb和hex相互转换的函数

    python实现颜色rgb和hex相互转换的函数

    这篇文章主要介绍了python实现颜色rgb和hex相互转换的函数,可实现将rgb表示的颜色转换成hex值的功能,非常具有实用价值,需要的朋友可以参考下
    2015-03-03
  • python项目--使用Tkinter的日历GUI应用程序

    python项目--使用Tkinter的日历GUI应用程序

    在 Python 中,我们可以使用 Tkinter 制作 GUI。如果你非常有想象力和创造力,你可以用 Tkinter 做出很多有趣的东西,希望本篇文章能够帮到你
    2021-08-08
  • Pandas导入导出excel、csv、txt文件教程

    Pandas导入导出excel、csv、txt文件教程

    Pandas 是一个强大的数据分析和处理库,可以用来读取和处理多种数据格式,本文主要介绍了Pandas导入导出excel、csv、txt文件教程,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • Python matplotlib可视化绘图详解

    Python matplotlib可视化绘图详解

    这篇文章主要介绍了Python matplotlib绘图可视化知识点整理(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09
  • Python实现滑动平均(Moving Average)的例子

    Python实现滑动平均(Moving Average)的例子

    今天小编就为大家分享一篇Python实现滑动平均(Moving Average)的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08

最新评论