Python讀取多格式Excel并實現(xiàn)跨表匹配合并的完整示例
在數(shù)據(jù)處理中,經(jīng)常會遇到這樣一個需求:
我們有兩份 Excel:一份是主數(shù)據(jù)表,另一份是學生/員工/客戶的完整信息表。 需要按姓名匹配,把完整信息補充到主表中。
聽起來簡單,但實際操作中常會踩坑,比如:
- 主表是 XLS,信息表是 XLSX
- 兩個表的表頭不在第一行
- 信息表第一列是序號,真正數(shù)據(jù)在第二列開始
- 合并后需要把新字段插入到指定位置,而不是簡單拼在末尾
本文就分享一次真實項目中的解決方案: 使用 Python + Pandas + xlrd + openpyxl,實現(xiàn)多格式 Excel 讀取 + 靈活表頭處理 + 按姓名匹配合并 + 自定義列順序輸出。
一、需求拆解
最終目標是:
- 無論是 XLS 還是 XLSX,都能讀取
- 支持跳過表頭行
- 支持跳過第一列(常見為序號)
- 按姓名進行匹配
- 把匹配結(jié)果插入主表的指定列后(例如 I 列)
- 輸出一個新的 XLSX 文件
為了做到這點,我們需要寫一個“通用 Excel 讀取函數(shù)”。
二、通用 Excel 讀取函數(shù)(支持 XLS / XLSX)
核心難點在于:
pandas無法直接讀取帶舊格式.xls的合并單元格或特殊格式xlrd只能讀取.xls(新版不支持.xlsx)
所以策略是:
- xls → xlrd
- xlsx → pandas(openpyxl)
并手動實現(xiàn)跳過行、跳過列等功能。
三、跨表匹配的整體流程
整個數(shù)據(jù)處理邏輯如下:
- 讀取主表(XLS/XLSX 均可)
- 讀取信息表(可以從第二行是真表頭)
- 把信息表按“姓名”設置為索引
- 循環(huán)主表每一行,根據(jù)姓名取對應信息
- 把匹配結(jié)果拼成新的 DataFrame
- 插入到主表指定列之后
- 輸出最終的合并表
這個流程能適配各種不同的 Excel 格式,健壯性很高。
四、完整示例代碼(已脫敏)
以下是通用示例代碼,你可以直接復用:
import pandas as pd
import xlrd
import openpyxl
def read_excel_any(path, sheet_name=None, skip_header_rows=0, skip_first_column=False):
"""
支持 XLS/XLSX 的通用讀取函數(shù)
- skip_header_rows: 跳過前 N 行
- skip_first_column: 是否跳過第一列(序號)
"""
if path.lower().endswith(".xls"):
book = xlrd.open_workbook(path)
sheet = book.sheet_by_name(sheet_name) if sheet_name else book.sheet_by_index(0)
data = []
for r in range(sheet.nrows):
if r < skip_header_rows:
continue
row = sheet.row_values(r)
if skip_first_column:
row = row[1:]
data.append(row)
df = pd.DataFrame(data[1:], columns=data[0])
return df
else: # XLSX
df = pd.read_excel(
path,
sheet_name=sheet_name,
engine="openpyxl",
skiprows=skip_header_rows
)
if skip_first_column:
df = df.iloc[:, 1:]
return df
# ===== 配置區(qū)(示例) ===== #
main_file = "主表.xls"
main_sheet = "數(shù)據(jù)表"
info_file = "信息表.xlsx"
info_sheet = "全部信息"
info_skip_header = 1
info_skip_first_col = True
# ======================== #
# 讀取主表
df_main = read_excel_any(main_file, sheet_name=main_sheet)
# 讀取信息表
df_info = read_excel_any(
info_file,
sheet_name=info_sheet,
skip_header_rows=info_skip_header,
skip_first_column=info_skip_first_col
)
# 確保兩張表都有“姓名”列
if "姓名" not in df_main.columns or "姓名" not in df_info.columns:
raise ValueError("兩份表格必須都包含“姓名”列!")
# 設置信息表的索引
df_info_index = df_info.set_index("姓名")
# 按姓名匹配
matched_data = []
for name in df_main["姓名"]:
if name in df_info_index.index:
matched_data.append(df_info_index.loc[name].to_dict())
else:
# 不存在則填空
matched_data.append({col: None for col in df_info.columns if col != "姓名"})
df_match = pd.DataFrame(matched_data)
# 匹配內(nèi)容插入到指定位置(示例:插入到第 8 列之后)
insert_pos = 8
cols_main = df_main.columns.tolist()
new_cols = cols_main[:insert_pos + 1] + df_match.columns.tolist() + cols_main[insert_pos + 1:]
df_out = pd.concat([df_main, df_match], axis=1)[new_cols]
df_out.to_excel("輸出結(jié)果.xlsx", index=False)
五、關鍵技術(shù)點解釋
① 通用讀取函數(shù)封裝的意義
很多項目里主表和信息表格式不同、位置不同、列不同。 封裝通用函數(shù)之后:
- 腳本可復用性強
- 更換 Excel 只需修改文件名
- 結(jié)構(gòu)更清晰、利于維護
② 使用set_index做匹配
df_info.set_index("姓名")
這樣查找效率極高,相當于字典查詢。
③ 保持原表字段順序不變
很多業(yè)務表格是“固定模板”,不能隨意打亂列。 這里通過自定義 new_cols 保證了最終順序完全可控。
六、效果示例
最終輸出的 Excel 將會:
- 保留主表原有字段順序
- 在指定列(如 I 列)后插入信息表的字段
- 按姓名逐行匹配
- 如果信息表中沒有該姓名,填充為空白
整個流程自動化,不需要人工篩選、復制、粘貼。
七、總結(jié)
通過 Python 的數(shù)據(jù)處理能力,我們可以輕松實現(xiàn):
- 跨格式 Excel 讀?。╔LS/XLSX)
- 靈活處理表頭位置與列結(jié)構(gòu)
- 按姓名精準匹配信息表
- 保持主表字段順序
- 自動生成合并后的最終數(shù)據(jù)
在實際業(yè)務場景(學籍管理、人事數(shù)據(jù)、客戶數(shù)據(jù)等)中,這類腳本非常實用,大幅提升效率。
如果你有更復雜的需求,比如:
- 多字段匹配
- 多表聯(lián)查
- 模糊匹配(拼音/首字母)
- 學生重復名自動識別
- 批量處理多個文件夾
以上就是Python讀取多格式Excel并實現(xiàn)跨表匹配合并的完整示例的詳細內(nèi)容,更多關于Python讀取多格式Excel并合并的資料請關注腳本之家其它相關文章!
相關文章
使用Python實現(xiàn)TCP/IP客戶端和服務端通信功能
TCP/IP(傳輸控制協(xié)議/互聯(lián)網(wǎng)協(xié)議)是互聯(lián)網(wǎng)的基礎協(xié)議,用于在網(wǎng)絡中的計算機之間進行可靠的數(shù)據(jù)傳輸,在Python中,可以使用socket模塊來實現(xiàn)TCP/IP通信,本文給大家介紹了使用Python實現(xiàn)TCP/IP客戶端和服務端通信功能,需要的朋友可以參考下2024-12-12

