思路
假设第一行是标题行,且两个文件的标题行内容一致(可能顺序不同)。
-
读取两个文件,获取DataFrame
- 假设csv或xlsx
-
检查两个DataFrame的形状(行数和列数)是否一致,如果不一致,则直接返回错误
-
检查两个DataFrame的列名是否包含相同的列(不考虑顺序)
- 如果列名集合不同,则返回错误。
- 如果列名相同但顺序不同,调整第二个DataFrame的列顺序与第一个相同。
-
比较两个DataFrame的内容
- 如果完全相同,则输出相同提示。
- 如果存在差异,则生成一个差异报告Excel文件,包含两个sheet:
- 第一个sheet:统计每个列中差异的数量。
- 第二个sheet:将两个表中存在差异的行整合到一起(显示两个表中对应的行,并标记出差异的单元格)。
V 1.0
import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.styles import PatternFill
def compare_dataframes(df1, df2):
"""
比较两个DataFrame,返回差异报告
参数:
df1: 第一个DataFrame
df2: 第二个DataFrame
返回:
如果相同返回True,否则返回差异报告DataFrame和列差异统计
"""
# 检查形状是否一致
if df1.shape != df2.shape:
return False, None, None
# 检查列名是否一致(不考虑顺序)
if set(df1.columns) != set(df2.columns):
return False, None, None
# 调整列顺序使其一致
df2 = df2[df1.columns]
# 比较内容
if df1.equals(df2):
return True, None, None
# 找出差异位置
diff_mask = df1 != df2
# 处理NaN情况 (NaN != NaN 会返回True)
both_nan = df1.isna() & df2.isna()
diff_mask = diff_mask & ~both_nan
# 创建差异统计
diff_stats = pd.DataFrame({
'列名': df1.columns,
'差异数量': diff_mask.sum(axis=0).values
})
# 创建详细差异报告
diff_rows = []
for row_idx in range(df1.shape[0]):
row_diffs = diff_mask.iloc[row_idx]
if row_diffs.any(): # 如果这一行有差异
for col_idx, col_name in enumerate(df1.columns):
if row_diffs.iloc[col_idx]:
diff_rows.append({
'行号': row_idx + 2, # +2是因为Excel行号从1开始,且第一行是标题
'列名': col_name,
'文件1值': df1.iloc[row_idx, col_idx],
'文件2值': df2.iloc[row_idx, col_idx]
})
diff_details = pd.DataFrame(diff_rows)
return False, diff_stats, diff_details
def create_difference_report(diff_stats, diff_details, output_file):
"""
创建差异报告Excel文件
"""
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
# 写入统计信息
diff_stats.to_excel(writer, sheet_name='差异统计', index=False)
# 写入详细信息
diff_details.to_excel(writer, sheet_name='详细差异', index=False)
# 获取工作簿和工作表对象
workbook = writer.book
stats_sheet = writer.sheets['差异统计']
details_sheet = writer.sheets['详细差异']
# 设置样式
red_fill = PatternFill(start_color="FFFF0000", end_color="FFFF0000", fill_type="solid")
# 在详细差异表中高亮差异值
for idx, row in diff_details.iterrows():
# 文件1值单元格 (C列)
details_sheet.cell(row=idx+2, column=3).fill = red_fill
# 文件2值单元格 (D列)
details_sheet.cell(row=idx+2, column=4).fill = red_fill
# 调整列宽
for sheet in [stats_sheet, details_sheet]:
for column in sheet.columns:
max_length = 0
column_letter = column[0].column_letter
for cell in column:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = min(max_length + 2, 50)
sheet.column_dimensions[column_letter].width = adjusted_width
def compare_files(file1, file2, file1_sheet=None, file2_sheet=None, output_file='difference_report.xlsx'):
"""
比较两个文件的主函数
"""
# 读取文件
if file1.endswith('.csv'):
df1 = pd.read_csv(file1)
else:
df1 = pd.read_excel(file1, sheet_name=file1_sheet)
if file2.endswith('.csv'):
df2 = pd.read_csv(file2)
else:
df2 = pd.read_excel(file2, sheet_name=file2_sheet)
# 比较DataFrame
is_same, diff_stats, diff_details = compare_dataframes(df1, df2)
if is_same is None:
print("文件结构不一致,无法比较")
return False
elif is_same:
print("两个表格内容完全相同!")
return True
else:
print("表格内容存在差异,生成差异报告中...")
create_difference_report(diff_stats, diff_details, output_file)
print(f"差异报告已保存至: {output_file}")
return False
# 使用示例
if __name__ == "__main__":
compare_files('file1.csv', 'file2.csv')
V2.0
主要改进点包括:
- 使用向量化操作替代循环提高性能
- 优化NaN值处理
- 改进列宽调整逻辑
- 增强错误处理
- 优化内存使用
import pandas as pd
import numpy as np
from openpyxl import Workbook
from openpyxl.styles import PatternFill
from openpyxl.utils import get_column_letter
def compare_dataframes(df1, df2):
"""
比较两个DataFrame,返回差异报告
参数:
df1: 第一个DataFrame
df2: 第二个DataFrame
返回:
如果相同返回True,否则返回差异报告DataFrame和列差异统计
"""
# 检查形状是否一致
if df1.shape != df2.shape:
return False, None, None
# 检查列名是否一致(不考虑顺序)
if set(df1.columns) != set(df2.columns):
return False, None, None
# 调整列顺序使其一致
df2 = df2[df1.columns]
# 比较内容 - 使用更高效的方法
if df1.equals(df2):
return True, None, None
# 找出差异位置 - 使用向量化操作
# 处理NaN情况: 使用pd.NA安全的比较方法
diff_mask = ~(df1.fillna('NA').astype(str) == df2.fillna('NA').astype(str))
# 创建差异统计 - 使用向量化操作
diff_counts = diff_mask.sum()
diff_stats = pd.DataFrame({
'列名': df1.columns,
'差异数量': diff_counts.values
})
# 如果没有差异,直接返回
if diff_counts.sum() == 0:
return True, None, None
# 创建详细差异报告 - 使用更高效的方法
# 获取差异位置的行列索引
diff_indices = np.argwhere(diff_mask.values)
# 构建差异详情DataFrame
diff_rows = []
for row_idx, col_idx in diff_indices:
col_name = df1.columns[col_idx]
diff_rows.append({
'行号': row_idx + 2, # +2是因为Excel行号从1开始,且第一行是标题
'列名': col_name,
'文件1值': df1.iloc[row_idx, col_idx],
'文件2值': df2.iloc[row_idx, col_idx]
})
diff_details = pd.DataFrame(diff_rows)
return False, diff_stats, diff_details
def create_difference_report(diff_stats, diff_details, output_file):
"""
创建差异报告Excel文件
"""
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
# 写入统计信息
diff_stats.to_excel(writer, sheet_name='差异统计', index=False)
# 写入详细信息
diff_details.to_excel(writer, sheet_name='详细差异', index=False)
# 获取工作簿和工作表对象
workbook = writer.book
stats_sheet = writer.sheets['差异统计']
details_sheet = writer.sheets['详细差异']
# 设置样式
red_fill = PatternFill(start_color="FFFF0000", end_color="FFFF0000", fill_type="solid")
# 在详细差异表中高亮差异值 - 使用更高效的方法
for row_idx in range(2, len(diff_details) + 2): # 从第2行开始(标题在第1行)
details_sheet.cell(row=row_idx, column=3).fill = red_fill
details_sheet.cell(row=row_idx, column=4).fill = red_fill
# 优化列宽调整 - 使用更高效的方法
for sheet in [stats_sheet, details_sheet]:
for col_idx, column in enumerate(sheet.columns, 1):
max_length = 0
col_letter = get_column_letter(col_idx)
# 检查标题和内容
header_length = len(str(column[0].value))
max_length = max(max_length, header_length)
# 只检查前100行以避免性能问题
for cell in column[1:101]:
try:
cell_length = len(str(cell.value))
if cell_length > max_length:
max_length = cell_length
except:
pass
adjusted_width = min(max_length + 2, 50)
sheet.column_dimensions[col_letter].width = adjusted_width
def compare_files(file1, file2, file1_sheet=None, file2_sheet=None, output_file='difference_report.xlsx'):
"""
比较两个文件的主函数
"""
try:
# 读取文件 - 添加更多错误处理
if file1.endswith('.csv'):
df1 = pd.read_csv(file1)
else:
df1 = pd.read_excel(file1, sheet_name=file1_sheet or 0, engine='openpyxl')
if file2.endswith('.csv'):
df2 = pd.read_csv(file2)
else:
df2 = pd.read_excel(file2, sheet_name=file2_sheet or 0, engine='openpyxl')
# 比较DataFrame
is_same, diff_stats, diff_details = compare_dataframes(df1, df2)
if is_same is None:
print("文件结构不一致,无法比较")
return False
elif is_same:
print("两个表格内容完全相同!")
return True
else:
print("表格内容存在差异,生成差异报告中...")
create_difference_report(diff_stats, diff_details, output_file)
print(f"差异报告已保存至: {output_file}")
return False
except Exception as e:
print(f"比较过程中发生错误: {str(e)}")
return False
# 使用示例
if __name__ == "__main__":
compare_files('file1.csv', 'file2.csv')
详细优化点:
- NaN值处理优化:
-
使用 fillna(‘NA’) 和 astype(str) 安全地比较包含NaN的值
-
避免了双重NaN检查逻辑
- 性能优化:
-
使用向量化操作替代循环(特别是 diff_mask 计算)
-
使用 np.argwhere 高效获取差异位置
-
限制列宽计算只检查前100行以避免性能问题
- 内存优化:
-
避免创建不必要的中间DataFrame
-
使用更高效的数据结构存储差异位置
- 错误处理增强:
-
添加了全局异常处理
-
明确了Excel读取引擎
-
处理了sheet_name为None的情况
- 列宽调整优化:
-
使用 get_column_letter 简化列索引转换
-
同时考虑标题长度
- 高亮逻辑优化:
- 直接根据行索引高亮,避免DataFrame迭代
V2.1
导入必要的库:
import pandas as pd
import numpy as np
from pathlib import Path
from openpyxl import Workbook
from openpyxl.styles import PatternFill
import warnings
warnings.filterwarnings('ignore')
1. 文件读取函数
def read_files(file1_path, file2_path, sheet1_name=None, sheet2_name=None):
"""
读取两个文件并返回DataFrame
参数:
file1_path: 第一个文件路径
file2_path: 第二个文件路径
sheet1_name: 第一个Excel文件的sheet名(如果是Excel文件)
sheet2_name: 第二个Excel文件的sheet名(如果是Excel文件)
返回:
两个DataFrame
"""
# 处理第一个文件
file1_ext = Path(file1_path).suffix.lower()
if file1_ext == '.csv':
df1 = pd.read_csv(file1_path, header=0)
elif file1_ext in ['.xlsx', '.xls']:
if sheet1_name:
df1 = pd.read_excel(file1_path, sheet_name=sheet1_name, header=0)
else:
df1 = pd.read_excel(file1_path, header=0)
else:
raise ValueError("不支持的文件格式")
# 处理第二个文件
file2_ext = Path(file2_path).suffix.lower()
if file2_ext == '.csv':
df2 = pd.read_csv(file2_path, header=0)
elif file2_ext in ['.xlsx', '.xls']:
if sheet2_name:
df2 = pd.read_excel(file2_path, sheet_name=sheet2_name, header=0)
else:
df2 = pd.read_excel(file2_path, header=0)
else:
raise ValueError("不支持的文件格式")
return df1, df2
2. DataFrame比较函数
def compare_dataframes(df1, df2, output_file):
"""
比较两个DataFrame并生成差异报告
参数:
df1: 第一个DataFrame
df2: 第二个DataFrame
output_file: 输出文件路径
"""
# 创建原始数据的副本,避免修改原始数据
df1_clean = df1.copy()
df2_clean = df2.copy()
# 第一步:删除全为空值的行和列
df1_clean = df1_clean.dropna(how='all').dropna(axis=1, how='all')
df2_clean = df2_clean.dropna(how='all').dropna(axis=1, how='all')
# 检查行列数是否一致
if df1_clean.shape != df2_clean.shape:
print(f"清理后数据形状不一致: df1 {df1_clean.shape}, df2 {df2_clean.shape}")
return False
# 第二步:检查列名是否一致
if not df1_clean.columns.equals(df2_clean.columns):
print("列名不一致,尝试按df1的顺序重排df2的列")
# 检查是否包含相同的列
if set(df1_clean.columns) != set(df2_clean.columns):
print("列名不完全相同,无法比较")
missing_in_df2 = set(df1_clean.columns) - set(df2_clean.columns)
missing_in_df1 = set(df2_clean.columns) - set(df1_clean.columns)
print(f"df2中缺少的列: {missing_in_df2}")
print(f"df1中缺少的列: {missing_in_df1}")
return False
# 按df1的顺序重排df2的列
df2_clean = df2_clean[df1_clean.columns]
print("已按df1的顺序重排df2的列")
# 第三步:比较数据内容
# 创建比较矩阵
comparison = df1_clean.values == df2_clean.values
# 检查是否所有数据都相同
if comparison.all():
print("两个表格内容完全相同")
return True
# 如果有差异,创建差异报告
print("发现差异,正在生成报告...")
# 创建Excel写入器
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
# Sheet1: 差异统计
diff_counts = []
for col in df1_clean.columns:
col_idx = df1_clean.columns.get_loc(col)
diff_count = np.sum(~comparison[:, col_idx])
diff_counts.append(diff_count)
summary_df = pd.DataFrame({
'列名': df1_clean.columns,
'差异数量': diff_counts
})
summary_df = summary_df[summary_df['差异数量'] > 0] # 只显示有差异的列
summary_df.to_excel(writer, sheet_name='差异统计', index=False)
# Sheet2: df1的差异行
# 找出有差异的行
diff_rows = np.any(~comparison, axis=1)
df1_diff = df1_clean[diff_rows].copy()
df1_diff.to_excel(writer, sheet_name='文件1差异', index=False)
# Sheet3: df2的差异行
df2_diff = df2_clean[diff_rows].copy()
df2_diff.to_excel(writer, sheet_name='文件2差异', index=False)
# 高亮显示差异单元格
highlight_differences(output_file, df1_clean, df2_clean, comparison, diff_rows)
print(f"差异报告已生成: {output_file}")
return False
def highlight_differences(output_file, df1, df2, comparison, diff_rows):
"""
高亮显示差异单元格
参数:
output_file: 输出文件路径
df1: 第一个DataFrame
df2: 第二个DataFrame
comparison: 比较矩阵
diff_rows: 有差异的行索引
"""
# 加载工作簿
wb = Workbook()
wb = pd.ExcelWriter(output_file, engine='openpyxl').book
# 黄色填充
yellow_fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
# 处理文件1差异sheet
ws1 = wb['文件1差异']
for row_idx in range(2, len(diff_rows) + 2): # Excel行从1开始,且第一行是标题
if diff_rows[row_idx - 2]: # 调整索引
for col_idx in range(1, len(df1.columns) + 1):
if not comparison[row_idx - 2, col_idx - 1]:
ws1.cell(row=row_idx, column=col_idx).fill = yellow_fill
# 处理文件2差异sheet
ws2 = wb['文件2差异']
for row_idx in range(2, len(diff_rows) + 2):
if diff_rows[row_idx - 2]:
for col_idx in range(1, len(df2.columns) + 1):
if not comparison[row_idx - 2, col_idx - 1]:
ws2.cell(row=row_idx, column=col_idx).fill = yellow_fill
# 保存工作簿
wb.save(output_file)
3. 主函数
def compare_tables(file1_path, file2_path, sheet1_name=None, sheet2_name=None, output_file=None):
"""
主函数:比较两个表格文件
参数:
file1_path: 第一个文件路径
file2_path: 第二个文件路径
sheet1_name: 第一个Excel文件的sheet名(可选)
sheet2_name: 第二个Excel文件的sheet名(可选)
output_file: 输出文件路径(可选)
"""
# 设置默认输出文件名
if output_file is None:
output_file = "比较结果.xlsx"
# 读取文件
df1, df2 = read_files(file1_path, file2_path, sheet1_name, sheet2_name)
# 比较DataFrame
result = compare_dataframes(df1, df2, output_file)
return result
4. 使用示例
# 示例1: 比较两个CSV文件
compare_tables('file1.csv', 'file2.csv', output_file='comparison_result.xlsx')
# 示例2: 比较Excel文件中的不同sheet
compare_tables('data.xlsx', 'data.xlsx', sheet1_name='Sheet1', sheet2_name='Sheet2', output_file='sheet_comparison.xlsx')
# 示例3: 比较CSV和Excel文件
compare_tables('data.csv', 'data.xlsx', sheet2_name='Sheet1', output_file='cross_format_comparison.xlsx')
代码说明
- 文件读取函数:支持CSV和Excel格式,可以指定sheet名称
- 数据清理:删除全为空值的行和列
- 列名检查:确保两个DataFrame的列名一致,如果不一致但包含相同的列,会按第一个文件的列顺序重排第二个文件
- 差异检测:使用NumPy进行高效比较,找出所有差异单元格
- 报告生成:
- 第一个sheet显示每列的差异数量
- 第二个和第三个sheet分别显示两个文件中存在差异的行,并高亮显示差异单元格
V2.2
思路检查:
- 文件读取:支持CSV/Excel(含多Sheet),使用
pathlib处理路径更健壮 - 预处理逻辑:增加全空行列删除功能,避免空白数据干扰比较
- 列名检查:严格检查列名集合一致性,自动标准化列顺序(按字母排序)
- 差异检测:使用向量化操作高效比较,正确处理NaN值(视为相等)
- 报告生成:
- 总结页:列名+差异数量统计
- 差异行页:高亮显示具体差异单元格(黄色背景)
- 支持无差异行时空Sheet处理
- 异常处理:关键步骤添加异常捕获,提供明确错误提示
import pandas as pd
from pathlib import Path
from typing import Optional, Tuple
import openpyxl
from openpyxl.styles import PatternFill
from openpyxl.utils.dataframe import dataframe_to_rows
def convert_to_dataframe(file_path: Path, sheet_name: Optional[str] = None) -> pd.DataFrame:
"""
将CSV/Excel文件转换为DataFrame(首行为列名)
:param file_path: 文件路径(Path对象)
:param sheet_name: Excel工作表名(仅Excel需要)
:return: DataFrame对象
"""
try:
if file_path.suffix.lower() == '.csv':
return pd.read_csv(file_path, header=0)
elif file_path.suffix.lower() in ('.xlsx', '.xls'):
return pd.read_excel(file_path, sheet_name=sheet_name, header=0)
else:
raise ValueError(f"不支持的文件格式: {file_path.suffix}")
except Exception as e:
raise RuntimeError(f"文件读取失败: {str(e)}") from e
def preprocess_dataframe(df: pd.DataFrame) -> pd.DataFrame:
"""
预处理DataFrame:删除全空行和全空列
:param df: 原始DataFrame
:return: 清洗后DataFrame
"""
# 删除所有值为空的行(how='all'表示整行全空才删除)
cleaned = df.dropna(axis=0, how='all')
# 删除所有值为空的列(how='all'表示整列全空才删除)
cleaned = cleaned.dropna(axis=1, how='all')
return cleaned
def validate_dataframe_shapes(df1: pd.DataFrame, df2: pd.DataFrame) -> None:
"""
验证两个DataFrame清洗后的形状是否一致
:param df1: 清洗后DataFrame1
:param df2: 清洗后DataFrame2
:raises ValueError: 形状不一致时抛出异常
"""
if df1.shape != df2.shape:
raise ValueError(
f"数据维度不一致(清洗后):
"
f"文件1: {df1.shape[0]}行 x {df1.shape[1]}列
"
f"文件2: {df2.shape[0]}行 x {df2.shape[1]}列"
)
def validate_and_align_columns(df1: pd.DataFrame, df2: pd.DataFrame) -> Tuple[pd.DataFrame, pd.DataFrame]:
"""
验证列名一致性并对齐列顺序
:param df1: 清洗后DataFrame1
:param df2: 清洗后DataFrame2
:return: 列顺序对齐后的两个DataFrame
:raises ValueError: 列名集合不一致时抛出异常
"""
cols1 = set(df1.columns)
cols2 = set(df2.columns)
if cols1 != cols2:
raise ValueError(
f"列名不一致:
"
f"文件1特有列: {cols1 - cols2}
"
f"文件2特有列: {cols2 - cols1}"
)
# 按字母顺序对齐列(保证比较顺序一致)
sorted_cols = sorted(cols1)
return df1[sorted_cols], df2[sorted_cols]
def detect_differences(df1: pd.DataFrame, df2: pd.DataFrame) -> Tuple[bool, pd.DataFrame, pd.Series]:
"""
检测两个DataFrame的差异
:param df1: 对齐后的DataFrame1
:param df2: 对齐后的DataFrame2
:return: (是否完全相同, 差异掩码, 列差异数量统计)
"""
# 快速检查是否完全相同(优化性能)
if df1.equals(df2):
return True, None, None
# 生成差异掩码(True表示对应位置不同)
# 注意:pandas中NaN != NaN,这里需要特殊处理(视为相同)
diff_mask = df1.fillna('__NULL__').ne(df2.fillna('__NULL__'))
# 统计每列的差异数量
col_diff_counts = diff_mask.sum()
return False, diff_mask, col_diff_counts
def apply_highlight_style(diff_mask: pd.DataFrame) -> callable:
"""
生成差异高亮样式函数
:param diff_mask: 差异掩码DataFrame
:return: 样式应用函数
"""
def style_func(row):
styles = []
for idx, value in enumerate(row):
# 检查当前位置是否是差异点
if diff_mask.iloc[row.name, idx]:
styles.append('background-color: #FFFF00') # 黄色背景
else:
styles.append('')
return styles
return style_func
def generate_comparison_report(
df1: pd.DataFrame,
df2: pd.DataFrame,
diff_mask: pd.DataFrame,
col_diff_counts: pd.Series,
output_path: Path
) -> None:
"""
生成完整的比较报告Excel文件
:param df1: 对齐后的DataFrame1(用于展示差异行)
:param df2: 对齐后的DataFrame2(用于展示差异行)
:param diff_mask: 差异掩码DataFrame
:param col_diff_counts: 列差异数量统计Series
:param output_path: 报告输出路径(Path对象)
"""
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
# ------------------------- 总结说明页 -------------------------
summary_data = col_diff_counts.reset_index()
summary_data.columns = ['列名称', '差异数量']
summary_data.to_excel(writer, sheet_name='总结说明', index=False)
# 设置总结页列宽(可选优化)
worksheet = writer.sheets['总结说明']
worksheet.column_dimensions['A'].width = 20
worksheet.column_dimensions['B'].width = 15
# ------------------------- 文件1差异行页 -------------------------
diff_rows = diff_mask.any(axis=1) # 找到有差异的行
df1_diff = df1[diff_rows].reset_index(drop=True)
if not df1_diff.empty:
# 应用高亮样式
styled_df1 = df1_diff.style.apply(
apply_highlight_style(diff_mask.loc[diff_rows]),
axis=1
)
# 写入Excel(保留标题)
styled_df1.to_excel(
writer,
sheet_name='文件1差异行',
index=False,
header=True,
startrow=0
)
else:
# 无差异时创建空页
pd.DataFrame(columns=df1.columns).to_excel(
writer,
sheet_name='文件1差异行',
index=False
)
# ------------------------- 文件2差异行页 -------------------------
df2_diff = df2[diff_rows].reset_index(drop=True)
if not df2_diff.empty:
styled_df2 = df2_diff.style.apply(
apply_highlight_style(diff_mask.loc[diff_rows]),
axis=1
)
styled_df2.to_excel(
writer,
sheet_name='文件2差异行',
index=False,
header=True,
startrow=0
)
else:
pd.DataFrame(columns=df2.columns).to_excel(
writer,
sheet_name='文件2差异行',
index=False
)
# 自动调整列宽(可选优化)
for sheet_name in writer.sheets:
worksheet = writer.sheets[sheet_name]
for idx, col in enumerate(worksheet.columns):
max_length = max(len(str(cell.value)) for cell in col if cell.value)
adjusted_width = (max_length + 2) * 1.2
worksheet.column_dimensions[chr(65 + idx)].width = min(adjusted_width, 50)
def compare_files(
file1_path: Path,
file2_path: Path,
sheet1_name: Optional[str] = None,
sheet2_name: Optional[str] = None,
output_path: Path = Path('表格比较结果.xlsx')
) -> None:
"""
主函数:执行完整的文件比较流程
:param file1_path: 文件1路径(CSV/Excel)
:param file2_path: 文件2路径(CSV/Excel)
:param sheet1_name: 文件1的Sheet名(仅Excel需要)
:param sheet2_name: 文件2的Sheet名(仅Excel需要)
:param output_path: 报告输出路径(默认当前目录)
"""
try:
# -------------------- 步骤1:读取文件 --------------------
print("正在读取文件...")
df1 = convert_to_dataframe(file1_path, sheet_name=sheet1_name)
df2 = convert_to_dataframe(file2_path, sheet_name=sheet2_name)
print("文件读取完成")
# -------------------- 步骤2:数据清洗 --------------------
print("正在清洗数据(删除全空行列)...")
df1_clean = preprocess_dataframe(df1)
df2_clean = preprocess_dataframe(df2)
print("数据清洗完成")
# -------------------- 步骤3:维度验证 --------------------
print("正在验证数据维度...")
validate_dataframe_shapes(df1_clean, df2_clean)
print("数据维度验证通过")
# -------------------- 步骤4:列名对齐 --------------------
print("正在对齐列名...")
df1_aligned, df2_aligned = validate_and_align_columns(df1_clean, df2_clean)
print("列名对齐完成")
# -------------------- 步骤5:差异检测 --------------------
print("正在检测数据差异...")
is_identical, diff_mask, col_diff_counts = detect_differences(df1_aligned, df2_aligned)
if is_identical:
print("结论:两个表格内容完全相同")
return
# -------------------- 步骤6:生成报告 --------------------
print("正在生成差异报告...")
generate_comparison_report(
df1_aligned,
df2_aligned,
diff_mask,
col_diff_counts,
output_path
)
print(f"结论:发现数据差异,报告已生成至:{output_path.absolute()}")
except Exception as e:
print(f"比较过程中发生错误: {str(e)}")
# 可选:添加调试断点(取消注释以下行)
# import pdb; pdb.set_trace()
# ------------------------- 使用示例 -------------------------
if __name__ == "__main__":
# 示例1:比较两个CSV文件
# compare_files(
# file1_path=Path("文件1.csv"),
# file2_path=Path("文件2.csv"),
# output_path=Path("CSV比较结果.xlsx")
# )
# 示例2:比较Excel的两个Sheet
compare_files(
file1_path=Path("文件1.xlsx"),
file2_path=Path("文件2.xlsx"),
sheet1_name="销售数据", # 文件1的Sheet名
sheet2_name="2025年销售", # 文件2的Sheet名
output_path=Path("ExcelSheet比较结果.xlsx")
)
1833

被折叠的 条评论
为什么被折叠?



