python xlsxwriter不会对齐日期

Gon*_*ync 5 python pandas xlsxwriter

日期最终出现在单元格的右下角,显然忽略了 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()
Run Code Online (Sandbox Code Playgroud)

A、B 和 C 列应水平居中,除标题外的所有行的高度应为 45,所有单元格内容垂直居中。

Excel 屏幕截图

除了日期列之外,一切都按预期工作。有充分的理由认为这不起作用吗?有没有使日期居中的正确方法?这是一个错误吗?有解决方法吗?

我也尝试过先格式化工作表,然后执行df.to_excel()最后一个,但没有效果。

非常感谢!

jmc*_*ara 5

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

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


pat*_*ng1 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()
Run Code Online (Sandbox Code Playgroud)

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

解决方案图片