python xlsxwriter 不会对齐日期

问题描述 投票:0回答:3

日期出现在单元格的右下角,显然忽略了 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,所有单元格内容垂直居中。

excel screen shot

一切正常,除了日期栏。有充分的理由认为这不起作用吗?有没有使日期居中的正确方法?这是一个错误吗?有解决办法吗?

我也尝试过先格式化工作表,最后执行

df.to_excel()
,但没有效果。

非常感谢!

python pandas xlsxwriter
3个回答
5
投票

我提供了一个示例,说明如何使用 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()

以及生成的工作表的图像:

Solution image


5
投票

问题在于 Pandas 正在为日期应用单元格格式,这会覆盖列格式。

解决此问题的唯一方法是迭代数据帧并直接写入 XlsxWriter,应用您想要的所有格式。


0
投票

只需将日期作为字符串存储在数据框中:不要将其转换为日期,或者如果它已经是日期格式,则将其转换回来,例如使用

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)
…
© www.soinside.com 2019 - 2024. All rights reserved.