You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XlsxWriter格式化Excel:区域设置未生效问题求助

Excel格式化失效问题:货币与日期格式需手动触发才生效

问题背景

使用Python脚本处理CSV数据并导出Excel时,表头、前置零格式正常生效,但**VALOR(货币列)和VALIDADE_RMS、DT_ATUALIZACAO、PTU_LIMITE(日期列)**的格式设置后无效果,必须双击单元格回车才能显示正确格式。最初怀疑是虚拟机区域为美式英语导致,但实际核心问题是数据类型未正确转换。

问题根源

从CSV读取的日期和货币数据默认是字符串类型,而非Excel可识别的日期/数值类型。XlsxWriter的格式仅作用于对应数据类型的单元格,字符串即使设置了日期/货币格式也不会生效;手动双击时Excel会自动将字符串转为对应数据类型,格式才会正常显示。

解决方案

1. 转换日期列数据类型

读取CSV时直接解析日期列,或读取后将字符串转为datetime类型:

# 读取CSV时自动解析日期列(指定日期格式为DD/MM/YYYY)
csv_dataframe = pd.read_csv(
    report_csv_file,
    sep=',',
    encoding="ISO-8859-1",
    engine='python',
    index_col=None,
    names=['TIPO', 'CODIGO', 'PTU', 'DESCRICAO', 'FORNECEDOR', 'VALOR', 'COD_PRINCP_ATIVO', 'PRINCIPIO_ATIVO', 'ANVISA', 'VALIDADE_RMS', 'FABRICANTE', 'DT_ATUALIZACAO', 'PTU_LIMITE', 'COD_ESP', 'NOME_ESPEC', 'REFERENCIA', 'OBSERVACAO'],
    parse_dates=['VALIDADE_RMS', 'DT_ATUALIZACAO', 'PTU_LIMITE'],
    dayfirst=True
)

# 若读取时未解析,可后续批量转换
date_cols = ['VALIDADE_RMS', 'DT_ATUALIZACAO', 'PTU_LIMITE']
csv_dataframe[date_cols] = csv_dataframe[date_cols].apply(pd.to_datetime, dayfirst=True, errors='coerce')

2. 转换货币列数据类型

将VALOR列的字符串(可能包含R$或千分位分隔符)转为数值类型:

# 清理VALOR列的非数字字符,转为float类型
csv_dataframe['VALOR'] = csv_dataframe['VALOR'].replace(r'[R$\.]', '', regex=True)  # 移除R$和千分位点号
csv_dataframe['VALOR'] = csv_dataframe['VALOR'].replace(',', '.', regex=True)  # 替换逗号为小数分隔符
csv_dataframe['VALOR'] = pd.to_numeric(csv_dataframe['VALOR'], errors='coerce')

3. 优化XlsxWriter格式设置(可选)

删除重复的表头写入逻辑,同时统一日期格式设置:

# 移除原代码中手动写入表头的循环(to_excel已通过header参数写入表头,重复写入会覆盖格式)
# for i, j in enumerate(list(csv_dataframe.columns)):
#     worksheet.write(0, i, j, header_format)

# 创建ExcelWriter时统一指定日期格式,增强格式优先级
writer = pd.ExcelWriter(template_excel_file, engine='xlsxwriter', date_format='DD/MM/YYYY', datetime_format='DD/MM/YYYY')

完整修正后代码

import os
import pandas as pd
import xlsxwriter

template_excel_file = r"C:\CriarTabelaOpme\Modelo Material Alto Custo - Intranet.xlsx"
depara_nome_espec_file = r"C:\CriarTabelaOpme\Especialidade_Dicionario.csv"
report_csv_file = r"C:\CriarTabelaOpme\ReportServiceIntranet.csv"

# 读取主CSV并解析日期列,转换货币列
csv_dataframe = pd.read_csv(
    report_csv_file,
    sep=',',
    encoding="ISO-8859-1",
    engine='python',
    index_col=None,
    names=['TIPO', 'CODIGO', 'PTU', 'DESCRICAO', 'FORNECEDOR', 'VALOR', 'COD_PRINCP_ATIVO', 'PRINCIPIO_ATIVO', 'ANVISA', 'VALIDADE_RMS', 'FABRICANTE', 'DT_ATUALIZACAO', 'PTU_LIMITE', 'COD_ESP', 'NOME_ESPEC', 'REFERENCIA', 'OBSERVACAO'],
    parse_dates=['VALIDADE_RMS', 'DT_ATUALIZACAO', 'PTU_LIMITE'],
    dayfirst=True
)

# 处理VALOR列:清理字符并转为数值
csv_dataframe['VALOR'] = csv_dataframe['VALOR'].replace(r'[R$\.]', '', regex=True)
csv_dataframe['VALOR'] = csv_dataframe['VALOR'].replace(',', '.', regex=True)
csv_dataframe['VALOR'] = pd.to_numeric(csv_dataframe['VALOR'], errors='coerce')

csv_dataframe.insert(16, "", "")

# 读取辅助CSV
csv_depara_espec = pd.read_csv(depara_nome_espec_file, sep=',', header=None, encoding="ISO-8859-1", engine='python')

# 调整列顺序
csv_dataframe = csv_dataframe.iloc[:, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,16,14,15]]

# 填充NOME_ESPEC列
for row in range(len(csv_dataframe)):
    cod_esp_row = csv_dataframe.iloc[row, 13]
    csv_dataframe.iloc[row,14] = csv_depara_espec.iloc[cod_esp_row, 1]

# 创建ExcelWriter,指定日期格式
writer = pd.ExcelWriter(template_excel_file, engine='xlsxwriter', date_format='DD/MM/YYYY')

# 导出DataFrame到Excel
csv_dataframe.to_excel(
    writer,
    sheet_name='Material Alto Custo',
    index=False,
    header=['TIPO', 'CODIGO', 'PTU', 'DESCRICAO', 'FORNECEDOR', 'VALOR', 'COD_PRINCP_ATIVO', 'PRINCIPIO_ATIVO', 'ANVISA', 'VALIDADE_RMS', 'FABRICANTE', 'DT_ATUALIZACAO', 'PTU_LIMITE', 'COD_ESP', 'NOME_ESPEC', 'REFERENCIA', 'OBSERVACAO']
)

workbook = writer.book 
worksheet = writer.sheets['Material Alto Custo']

# 定义格式
header_format = workbook.add_format({'bold': True, 'font': 'Arial', 'size': 10})
font_and_size = workbook.add_format({'font': 'Arial', 'size': 10}) 
column_valor_format = workbook.add_format({'num_format': '[$R$-pt-BR] #.##0,00'}) 
column_date_format = workbook.add_format({'num_format': 'dd/mm/yyyy'}) 
column_left_zeroes_format = workbook.add_format({'num_format': '00000000'})

# 应用格式
worksheet.set_row(0, None, header_format)
worksheet.set_column(0, csv_dataframe.shape[1]-1, 20.0, font_and_size)

worksheet.set_column(1, 1, 20.0, column_left_zeroes_format)
worksheet.set_column(2, 2, 20.0, column_left_zeroes_format)

worksheet.set_column(5, 5, 20.0, column_valor_format)

worksheet.set_column(9, 9, 20.0, column_date_format)
worksheet.set_column(11, 11, 20.0, column_date_format)
worksheet.set_column(12, 12, 20.0, column_date_format)

writer.close()

内容的提问来源于stack exchange,提问作者Leonardo Leipnitz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:25:32