如何通过Python结合正则表达式提取Excel中的会计账户数据?
实现方案:Python + 正则表达式处理会计Excel数据
核心工具准备
先安装所需依赖库:
pip install pandas openpyxl pyodbc
1. 提取账户名称与编号(正则表达式)
假设账户信息单元格格式为"账户名称:XX有限公司 (编号:12345)",可通过正则精准匹配提取:
import re import pandas as pd # 读取Excel文件 df = pd.read_excel("zeus_accounts.xlsx", engine="openpyxl") # 定义正则模式(根据实际格式调整,比如编号含字母就把\d+改成\w+) account_pattern = re.compile(r"账户名称:(.*?) \(编号:(\w+)\)") accounts = [] for idx, row in df.iterrows(): # 遍历每行单元格,定位账户信息 for cell in row: if isinstance(cell, str): match = account_pattern.search(cell) if match: accounts.append({ "account_name": match.group(1).strip(), "account_number": match.group(2).strip(), "start_row": idx # 记录行号用于关联后续明细 })
2. 关联账户明细与账户信息
假设每个账户信息后紧跟明细行,直到下一个账户信息出现:
account_details = [] # 遍历每个账户,提取对应明细 for i in range(len(accounts)): current_acc = accounts[i] # 确定明细结束行:下一个账户的起始行,或表格末尾 end_row = accounts[i+1]["start_row"] if i+1 < len(accounts) else len(df) # 提取明细行(跳过标题行,根据实际情况调整偏移量) detail_rows = df.iloc[current_acc["start_row"] + 1 : end_row] # 清理空行 detail_rows = detail_rows.dropna(how="all") # 为每条明细绑定账户信息 for _, detail in detail_rows.iterrows(): account_details.append({ "account_name": current_acc["account_name"], "account_number": current_acc["account_number"], "date": detail.get("日期"), # 替换为实际明细列名 "amount": detail.get("金额"), "description": detail.get("摘要") })
3. 导出数据到MS Access
用pyodbc连接Access数据库,创建关联表并插入数据:
import pyodbc # 连接Access(不存在则自动创建) conn_str = r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\path\to\your\account_db.accdb;' conn = pyodbc.connect(conn_str) cursor = conn.cursor() # 创建账户表(编号唯一,自增ID为主键) cursor.execute(""" CREATE TABLE IF NOT EXISTS Accounts ( account_id AUTOINCREMENT PRIMARY KEY, account_name TEXT, account_number TEXT UNIQUE ) """) # 创建明细表(关联账户表的account_id) cursor.execute(""" CREATE TABLE IF NOT EXISTS AccountDetails ( detail_id AUTOINCREMENT PRIMARY KEY, account_id INTEGER, date DATE, amount DOUBLE, description TEXT, FOREIGN KEY (account_id) REFERENCES Accounts(account_id) ) """) # 插入账户数据(避免重复插入) for acc in accounts: cursor.execute(""" INSERT INTO Accounts (account_name, account_number) SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM Accounts WHERE account_number = ?) """, (acc["account_name"], acc["account_number"], acc["account_number"])) # 建立账户编号与ID的映射 account_id_map = {} cursor.execute("SELECT account_id, account_number FROM Accounts") for row in cursor.fetchall(): account_id_map[row[1]] = row[0] # 插入明细数据 for detail in account_details: acc_id = account_id_map[detail["account_number"]] cursor.execute(""" INSERT INTO AccountDetails (account_id, date, amount, description) VALUES (?, ?, ?, ?) """, (acc_id, detail["date"], detail["amount"], detail["description"])) conn.commit() conn.close()
4. 生成Excel报表
用pandas整理数据并导出:
# 转换为DataFrame并调整列顺序 report_df = pd.DataFrame(account_details)[["account_name", "account_number", "date", "amount", "description"]] # 导出报表 report_df.to_excel("account_report.xlsx", index=False, engine="openpyxl")
关键注意事项
- 若Excel含合并单元格,需先用
openpyxl的merged_cells属性展开合并内容,避免数据遗漏。 - 正则表达式需根据实际账户格式微调,可先打印样本单元格内容测试匹配效果。
- 处理超大规模Excel时,建议用
pd.read_excel(chunksize=1000)分块读取,防止内存溢出。
内容的提问来源于stack exchange,提问作者Angel Viera
相关产品推荐
相关产品推荐

