使用 Pandas Excel Writer 时日期列会覆盖边框格式

Date Column overrides border formatting when using Pandas Excel Writer

这一直困扰着我,因为我不太清楚为什么会这样。我没能找到其他有这个问题的人,所以希望这不是重复的。基本上,当使用格式将 pandas 数据框导出到 Excel 时,我的日期列似乎覆盖了我的边框格式。请参阅下面的一些示例代码:

import numpy as np
import pandas as pd

#Example dataframe
df = pd.DataFrame({'Col 1' : [1, 1, 1, 1, 1, 1],
                   'Date' : [np.nan, '2021-09-23', '2021-09-23', np.nan, '2021-09-23', np.nan],
                   'Col 2' : [2, 2, 2, 2, 2, 2]})
df['Date'] = pd.to_datetime(df['Date'])

#Writing to excel
writer = pd.ExcelWriter('Example.xlsx', datetime_format = 'dd/mm/yyyy')
df.to_excel(writer, 'Sheet 1', index=False)

workbook = writer.book
worksheet = writer.sheets['Sheet 1']

center = workbook.add_format({'align' : 'center'})
center_rborder = workbook.add_format({'align' : 'center', 'right' : True})

worksheet.set_column('A:A', 10, center_rborder)
worksheet.set_column('B:B', 10, center_rborder)
worksheet.set_column('C:C', 10, center_rborder)

writer.save()

下面是生成的电子表格的样子。如您所见,对于日期列,只要有日期,右边框就会有间隙:

如果有人知道为什么会发生这种情况and/or任何方式来防止这种情况,那就太好了。

发生这种情况的原因是,在 Excel 中,单元格格式覆盖了列格式,而 Pandas 正在使用日期时间对象的格式。因此,单元格日期格式将覆盖您的列格式。

据我所知,告诉 Pandas 不使用那种日期时间格式是不可能的。

在这种特殊情况下,您可以通过设置左边框和右边框来解决此问题:

center_rborder = workbook.add_format({'align' : 'center', 'right' : True, 'left': True})

输出:

更新:

这是另一种方法,它使用 XlsxWriter 函数将数据框列中的日期时间对象转换为 Excel 序列号。然后它使用数字格式对其进行格式化(这实际上是 Excel 中的日期)。

import pandas as pd
from xlsxwriter.utility import datetime_to_excel_datetime

# Example dataframe
df = pd.DataFrame({'Col 1' : [1, 1, 1, 1, 1, 1],
                   'Date' : ['2021-09-23'] * 6,
                   'Col 2' : [2, 2, 2, 2, 2, 2]})
df['Date'] = pd.to_datetime(df['Date'])
df['Date'] = [datetime_to_excel_datetime(x, False, False) for x in df['Date']]

# Writing to excel
writer = pd.ExcelWriter('Example.xlsx', datetime_format = 'dd/mm/yyyy')
df.to_excel(writer, 'Sheet 1', index=False)

workbook = writer.book
worksheet = writer.sheets['Sheet 1']

center = workbook.add_format({'align' : 'center'})
center_rborder = workbook.add_format({'align' : 'center', 'right' : True})
center_rborder_date = workbook.add_format({'align' : 'center',
                                           'right' : True,
                                           'num_format':'dd/mm/yyyy'})

worksheet.set_column('A:A', 10, center_rborder)
worksheet.set_column('B:B', 10, center_rborder_date)
worksheet.set_column('C:C', 10, center_rborder)

writer.save()

输出与上图相同

请注意,为了简单起见,我在本示例中避免处理 np.nan 元素。此外,我修复了 set_column() 范围内的一个小语法错误(被忽略)。