Pandas调用read_excel转CSV时如何保留Excel自定义数字格式
问题解答
纯Pandas原生接口无法实现该需求。
Pandas的read_excel方法默认仅读取单元格的底层存储值,不会解析单元格绑定的自定义数字格式元数据,因此既无法感知原文件中日期列设置的显示格式,也不可能自动按照原格式输出内容,手动给to_csv传固定date_format参数确实没法适配多文件的差异化格式要求。
可行实现方案
借助可读取Excel单元格格式元数据的解析引擎(xlsx格式用openpyxl,xls格式用xlrd),动态提取每个单元格/列的数字格式,自动识别日期列后按原格式转换值即可,无需提前为每个文件硬编码格式规则,核心实现逻辑如下:
- 加载Excel文件时保留格式读取权限,不要只拿单元格值
- 逐列/逐单元格提取绑定的数字格式字符串,判断是否为日期类格式(格式串包含y、m、d等日期占位符即可判定,注意区分代表分钟的m,这类m一般紧跟在小时h占位符后)
- 写一个通用的Excel格式串转Python strftime格式串的映射函数,覆盖常用日期占位符的转换规则即可
- 遍历单元格值时,对日期类型且绑定日期格式的单元格,按提取到的格式将日期转为对应显示字符串,非日期值保留原始内容
- 整理完所有数据后导出为CSV即可
核心参考代码
import pandas as pd from openpyxl import load_workbook from datetime import datetime def excel_fmt_to_strftime(excel_fmt: str) -> str: # 可按需扩展更多格式占位符映射 fmt_mapping = { 'yyyy': '%Y', 'mmm': '%b', 'mm': '%m', 'dd': '%d', 'hh': '%H', 'ss': '%S' } py_fmt = excel_fmt for excel_placeholder, py_placeholder in fmt_mapping.items(): py_fmt = py_fmt.replace(excel_placeholder, py_placeholder) return py_fmt # 加载工作簿,data_only=False保留格式信息 wb = load_workbook(excel_file, data_only=False) ws = wb.active # 读取表头 headers = [cell.value for cell in ws[1]] all_rows = [] # 逐行读取处理数据 for row in ws.iter_rows(min_row=2, values_only=False): current_row = [] for cell in row: cell_val = cell.value cell_fmt = cell.number_format # 判定为日期值+日期格式则按原显示格式转字符串 if isinstance(cell_val, datetime) and ('y' in cell_fmt.lower() or 'd' in cell_fmt.lower()): target_fmt = excel_fmt_to_strftime(cell_fmt) current_row.append(cell_val.strftime(target_fmt)) else: current_row.append(cell_val) all_rows.append(current_row) # 导出CSV result_df = pd.DataFrame(all_rows, columns=headers) result_df.to_csv(csv_file, index=None, header=True, float_format='%.0f')
补充说明
- 上述方案的格式规则全部从原Excel文件中动态提取,无需提前针对单个文件配置格式参数,可适配不同文件的自定义日期格式
- 若遇到特殊的自定义日期占位符,只需在
fmt_mapping中补充对应的映射规则即可,维护成本极低 - 若单列内存在不同单元格应用不同日期格式的情况,上述逐单元格判断格式的逻辑也可正常适配,无需额外修改
- 处理.xls格式文件时,替换为xlrd引擎即可,读取单元格数字格式的逻辑基本一致
内容的提问来源于stack exchange,提问作者JM G.
相关产品推荐
相关产品推荐

