Python Excel提取指定列到新表:按列名一键导出
用openpyxl从原表提取指定几列,写入新的xlsx文件,保留表头顺序,适合把宽表拆成窄表发给不同部门。
场景痛点
原表有 20 列敏感字段,财务只要「日期、区域、金额」三列,人事只要「姓名、部门、入职日期」。手动复制粘贴容易漏列、带错列。用 openpyxl 按列名把需要的列抽出来,生成一张新表,谁要什么发什么,敏感列不外露。
用到的库
pip install openpyxl
完整代码
from openpyxl import load_workbook, Workbook
def extract_columns(src_path: str, dst_path: str, columns: list[str]) -> None:
wb_src = load_workbook(src_path, data_only=True)
ws_src = wb_src.active
# 1) 读表头,找到目标列在原表中的列号
header = [c.value for c in ws_src[1]]
col_indexes = []
for name in columns:
if name not in header:
print(f"警告:原表没有列 [{name}],已跳过")
continue
col_indexes.append((name, header.index(name) + 1))
if not col_indexes:
print("没有可提取的列,退出")
return
# 2) 新建工作簿,写表头
wb_dst = Workbook()
ws_dst = wb_dst.active
ws_dst.title = "提取结果"
ws_dst.append([name for name, _ in col_indexes])
# 3) 逐行把目标列的值拷过去
for row in ws_src.iter_rows(min_row=2, values_only=True):
new_row = [row[idx - 1] for _, idx in col_indexes]
ws_dst.append(new_row)
wb_dst.save(dst_path)
wb_src.close()
print(f"已生成: {dst_path},共 {ws_dst.max_row - 1} 行数据")
if __name__ == "__main__":
extract_columns(
src_path=r"D:\reports\销售明细.xlsx",
dst_path=r"D:\reports\财务汇总.xlsx",
columns=["日期", "区域", "金额"],
)
代码讲解
- 先在源表第 1 行读表头,用
header.index(name) + 1把列名转成 openpyxl 列号;找不到的列打个警告跳过,不让脚本崩。 - 新建一个
Workbook(),把目标列名按顺序写成新表头。 - 用
iter_rows(min_row=2, values_only=True)逐行读源数据,按目标列号取值组成新行,append到新表。 - 输出顺序就是
columns列表里给的顺序,想重排列就改列表顺序。 data_only=True读源文件,拿到的是计算后的值而不是公式,新表是纯数据。
运行结果
生成 财务汇总.xlsx,里面只有「日期、区域、金额」三列,行数和原表一致(不含空行)。打开核对即可。
注意事项
- 新表是纯数据,原表的字体、颜色、公式都不会带过去;需要保留样式就改用复制单元格对象的方式,代码会复杂不少。
- 列名要和原表表头完全一致,多一个空格都匹配不上,建议先
print(header)看一眼。 - 源表有合并单元格时,非左上角格子读出来是
None,提取前最好先取消合并。 - 大表提取用
values_only=True性能最好,别再访问单元格对象的样式。 - 如果还要按行筛选(比如只要华东区域),在 append 前加一行
if row[...] == "华东":即可。

更新时间:2026-09-15 09:08:29