当应用为样式时,为什么to_excel()中的'vertical-align:middle'对OpenPyXL有效,而对xlsxWriter引擎无效?

时间:2019-12-06 07:03:11

标签: python pandas openpyxl xlsxwriter

我在pandas GitHub issue tracker上找不到与我的问题有关的匹配问题,在提出一个问题之前,我只是想确保自己不会错过任何(显而易见的)错误。此处和其他地方的大多数问答均侧重于标题以及该范围内的特定问题。

因此,基本上我想使用pandas styling,尤其是export to Excel。对于链接的文档,支持vertical-align,根据this test for the to_excel() function,居中垂直对齐的正确用法是'vertical-align: middle'

如果我在to_excel()中使用OpenPyXL引擎,那实际上效果很好,请参见以下示例(不是那么少):

import pandas as pd

def align(data):
    return pd.DataFrame('text-align: center', index=data.index, columns=data.columns)

def valign(data):
    return pd.DataFrame('vertical-align: middle', index=data.index, columns=data.columns)

def whitespace(data):
    return pd.DataFrame('white-space: normal', index=data.index, columns=data.columns)

d = {'col1': ['first\nsecond', 'only one'], 'col2': ['only one', 'first\nsecond']}
df = pd.DataFrame(data=d)

df = df.style.apply(align, axis=None).apply(valign, axis=None).apply(whitespace, axis=None)

with pd.ExcelWriter('test.xlsx', engine='openpyxl') as writer:
    df.to_excel(writer, sheet_name='Test sheet')

我应用了三种不同的样式:

  • 水平居中对齐;就像一般测试一样,样式有效
  • 垂直居中对齐;如上所述
  • 'whitespace: normal';因为这对于在Excel中具有适当的“扩展”单元格以及居中的垂直对齐方式是必要的(请参阅下面的图片以了解我的意思)

如上所述,OpenPyXL引擎的输出很好:

OpenPyXL

现在,让我们将引擎切换为XlsxWriter:

with pd.ExcelWriter('test.xlsx', engine='xlsxwriter') as writer:
    df.to_excel(writer, sheet_name='Test sheet')

结果如下:

XlsxWriter

如您所见,垂直对齐设置为底部。尽管如此,水平对齐方式以及空白/包装还是正确设置的。另外,'vertical-align: top'可以正常工作。看来,'vertical-align: middle'特别不适用于XlsxWriter引擎。

我还有什么可以进一步测试的吗?或者这仅仅是熊猫中的一个普通错误?

更多说明:

  • 当然,OpenPyXL引擎可以工作。但是,我想使用XlsxWriter引擎,因为从我的角度来看,后处理变得更加容易。
  • 我可以使用XlsxWriter手动生成整个Excel文档,这是事实。但是,最终代码的使用/维护必须尽可能地容易,因为使用此代码的同事不应该是Python / pandas专家。
  • 如果这是一个实际的错误,则应将其修复。 :-)

编辑:我应该首先提到这一点;因此,这是对Hans' comment的答案:我可以仅使用XlsxWriter引擎来显式生成正确的输出,如下所示:

import pandas as pd

d = {'col1': ['first\nsecond', 'only one'], 'col2': ['only one', 'first\nsecond']}
df = pd.DataFrame(data=d)

with pd.ExcelWriter('test.xlsx', engine='xlsxwriter') as writer:
    df.to_excel(writer, sheet_name='Test sheet')
    workbook = writer.book
    worksheet = writer.sheets['Test sheet']
    fmt = workbook.add_format({'align': 'center', 'valign': 'vcenter', 'text_wrap': True})
    worksheet.set_column('B:C', None, fmt)

注意:没有df.style.apply

这里的问题是,我特别需要另一种非平凡的熊猫样式,该样式会根据某些约束更改背景颜色,这些约束不能被(XlsxWriter)conditional formatting攻击-或至少不能和熊猫风格一样容易。因此,所有单元格都已经具有样式,因此以后无法覆盖它,请参见。以下代码:

import pandas as pd

def whitespace(data):
    return pd.DataFrame('white-space: normal', index=data.index, columns=data.columns)

d = {'col1': ['first\nsecond', 'only one'], 'col2': ['only one', 'first\nsecond']}
df = pd.DataFrame(data=d)

df = df.style.apply(whitespace, axis=None)

with pd.ExcelWriter('test.xlsx', engine='xlsxwriter') as writer:
    df.to_excel(writer, sheet_name='Test sheet')
    workbook = writer.book
    worksheet = writer.sheets['Test sheet']
    fmt = workbook.add_format({'align': 'center', 'valign': 'vcenter'})
    worksheet.set_column('B:C', None, fmt)

This doesn't work.

如您所见,应用了pandas样式的换行,而忽略了XlsxWriter格式的水平和垂直对齐方式。

0 个答案:

没有答案