日期出现在单元格的右下角,显然忽略了 xlsxwriter 的对齐设置。一个MWE:
import pandas
df = pandas.DataFrame(
{
"ints": [1, 2, 3]
, 'primes': [2, 3, 5]
, 'odds': [1, 3, 5]
, 'fechas': ['2017-04-07', '2017-05-09', '2017-11-30']
}
)
df['fechas'] = pandas.to_datetime(df['fechas']).dt.date
print(df)
xlsx_writer = pandas.ExcelWriter(
'test.xlsx'
, engine='xlsxwriter'
, date_format='mm/dd/yyyy'
)
df.to_excel(xlsx_writer, sheet_name='Sheet1', index=False)
wb = xlsx_writer.book
ws = xlsx_writer.sheets['Sheet1']
dollar_format = '_($* #,##0.00" "_);_($* (#,##0.0);_($* "-"??_);_(@_)'
dollar_format_wb = wb.add_format({'num_format': dollar_format, 'valign': 'vcenter'})
centre_format_wb = wb.add_format({'align': 'center', 'valign': 'vcenter'})
ws.set_column('A:A', 25, centre_format_wb)
ws.set_column('B:B', 20, centre_format_wb)
ws.set_column('C:C', 15, centre_format_wb)
ws.set_column('D:D', 10, dollar_format_wb)
# The code below was included to generate the screenshot, but isn't
# strictly necessary for the MWE
shadedrow_format_wb = wb.add_format(
{
'bg_color': '#EEEEEE'
, 'left': 1
, 'left_color': '#FFFFFF'
}
)
for r in range(0, 2 + df.shape[0]):
ws.set_row(r + 1, 45)
print(r)
if r % 2 == 0:
# a kludge as we can't change cell range formats after the fact without re-entering cell contents
ws.conditional_format('A{:}:D{:}'.format(r, r), {'type': 'no_errors', 'format': shadedrow_format_wb})
print("\t", r)
xlsx_writer.save()
A、B 和 C 列应水平居中,除标题外的所有行的高度应为 45,所有单元格内容垂直居中。
一切正常,除了日期栏。有充分的理由认为这不起作用吗?有没有使日期居中的正确方法?这是一个错误吗?有解决办法吗?
我也尝试过先格式化工作表,最后执行
df.to_excel()
,但没有效果。
非常感谢!
我提供了一个示例,说明如何使用 pandas 在 .xlsx 输出中实现所需的日期格式。 它还需要添加日期时间模块。
正如@jmcnamara提到的,我认为最好、最灵活的解决方案是直接使用xlsxwriter。
这里有一个链接到另一个SO答案,它提供了有关Excel“串行日期”格式以及从Python中的日期时间对象获取它的进一步背景。 这与我将列转换为 Excel 日期的操作基本相同。 我还添加了一种附加格式(称为“centre_date_format_wb”)。
这是包含我的添加/更改的完整代码:
import pandas
import datetime
df = pandas.DataFrame(
{
"ints": [1, 2, 3]
, 'primes': [2, 3, 5]
, 'odds': [1, 3, 5]
, 'fechas': ['2017-04-07', '2017-05-09', '2017-11-30']
}
)
df['fechas'] = pandas.to_datetime(df['fechas']).dt.date
excel_start_date = datetime.date(1899, 12, 30)
df['fechas'] = df['fechas'] - excel_start_date
df.fechas = df.fechas.dt.days
print(df)
xlsx_writer = pandas.ExcelWriter(
'test.xlsx'
, engine='xlsxwriter'
)
df.to_excel(xlsx_writer, sheet_name='Sheet1', index=False)
wb = xlsx_writer.book
ws = xlsx_writer.sheets['Sheet1']
dollar_format = '_($* #,##0.00" "_);_($* (#,##0.0);_($* "-"??_);_(@_)'
dollar_format_wb = wb.add_format({'num_format': dollar_format, 'valign': 'vcenter'})
centre_format_wb = wb.add_format({'align': 'center', 'valign': 'vcenter'})
#additional format added below
centre_date_format_wb = wb.add_format({'align': 'center', 'valign': 'vcenter', 'num_format' : 'mm/dd/yyyy' })
ws.set_column('A:A', 25, centre_date_format_wb)
ws.set_column('B:B', 20, centre_format_wb)
ws.set_column('C:C', 15, centre_format_wb)
ws.set_column('D:D', 10, dollar_format_wb)
# The code below was included to generate the screenshot, but isn't
# strictly necessary for the MWE
shadedrow_format_wb = wb.add_format(
{
'bg_color': '#EEEEEE'
, 'left': 1
, 'left_color': '#FFFFFF'
}
)
for r in range(0, 2 + df.shape[0]):
ws.set_row(r + 1, 45)
print(r)
if r % 2 == 0:
# a kludge as we can't change cell range formats after the fact without re-entering cell contents
ws.conditional_format('A{:}:D{:}'.format(r, r), {'type': 'no_errors', 'format': shadedrow_format_wb})
print("\t", r)
xlsx_writer.save()
以及生成的工作表的图像:
问题在于 Pandas 正在为日期应用单元格格式,这会覆盖列格式。
解决此问题的唯一方法是迭代数据帧并直接写入 XlsxWriter,应用您想要的所有格式。
只需将日期作为字符串存储在数据框中:不要将其转换为日期,或者如果它已经是日期格式,则将其转换回来,例如使用
strftime('%Y-%m-%d')
。
这样,您可以将其作为文本导出到excel,然后使用
num_format
将其cell_format设置为日期:
…
df.to_excel(xlsx_writer, sheet_name='Sheet1', index=False)
wb = xlsx_writer.book
ws = xlsx_writer.sheets['Sheet1']
…
centre_date_format_wb = wb.add_format({
'align': 'center',
'valign': 'vcenter',
'num_format' : 'mm/dd/yyyy'
})
ws.set_column('A:A', width=25, cell_format=centre_date_format_wb)
…