import openpyxl from openpyxl.utils import get_column_letter from tqdm import tqdm # 导入进度条库 # 输入和输出文件路径 input_file = r'C:\Users\Administrator\Desktop\收银机_商品信息_互传处理\商品资料.xlsx' output_file = r'C:\Users\Administrator\Desktop\收银机_商品信息_互传处理\已处理商品信息模板.xlsx' # 列名映射(确保顺序正确) column_mapping = { '名称(必填)': '名称', '条码': '条码', '规格': '规格', '主单位': '单位', '进货价(必填)': '进价', '销售价(必填)': '零售价' } # 打开输入文件(非只读模式,以获取列宽信息) input_wb = openpyxl.load_workbook(input_file) # 移除了 read_only=True input_ws = input_wb.active # 预计算列索引(性能关键!) col_indexes = {} for col_name in column_mapping: for cell in input_ws[1]: # 标题行 if cell.value == col_name: col_indexes[col_name] = cell.column # 保存列索引(数字) break # 创建新工作簿 output_wb = openpyxl.Workbook() output_ws = output_wb.active output_ws.append(list(column_mapping.values())) # 写入新标题 # 获取总行数(用于进度条) total_rows = input_ws.max_row - 1 # 减去标题行 # 批量复制数据(核心优化) for row in tqdm(input_ws.iter_rows(min_row=2, values_only=True), total=total_rows, desc="处理进度"): new_row = [ row[col_indexes[src_col] - 1] # 直接按列索引取数据 for src_col in column_mapping ] output_ws.append(new_row) # 复制数字格式(仅处理数值列) price_cols = ['进价', '零售价'] # 需要保留小数格式的列 for col_idx, col_name in enumerate(column_mapping.values(), 1): if col_name in price_cols: col_letter = get_column_letter(col_idx) for cell in output_ws[col_letter][1:]: # 跳过标题 if isinstance(cell.value, (int, float)): cell.number_format = '0.00' # 强制保留两位小数 # ---------------------- 修复列宽复制 ---------------------- # 遍历需要复制的原始列,按顺序复制到新列 for src_col_name in column_mapping.keys(): # 获取原始列的字母(如 "A") src_col_letter = get_column_letter(col_indexes[src_col_name]) # 获取目标列的索引(从1开始) dst_col_idx = list(column_mapping.keys()).index(src_col_name) + 1 dst_col_letter = get_column_letter(dst_col_idx) # 复制列宽 output_ws.column_dimensions[dst_col_letter].width = input_ws.column_dimensions[src_col_letter].width # 保存结果 output_wb.save(output_file) print(f"处理完成!保存路径:{output_file}")