如何使用 xlsxwriter 格式化索引列?
Posted
技术标签:
【中文标题】如何使用 xlsxwriter 格式化索引列?【英文标题】:How can I format the index column(s) with xlsxwriter? 【发布时间】:2017-02-15 00:04:56 【问题描述】:我正在使用 xlsxwriter 和 set_column 函数来格式化我的 excel 输出中的列。
但是,当应用于索引列(或多索引情况下的索引列)时,格式似乎被忽略了。
我找到了一种解决方法,到目前为止是使用 reset_index 引入一个假索引,然后将 index=False 传递给 to_excel 函数,然后是多索引也将消失。
有什么想法吗?
import pandas as pd
import numpy as np
from Config import TEMP_XL_FILE
def temp():
' temp'
pdf = pd.DataFrame(np.random.randn(6,4), columns=list('ABCD'))
pdf.set_index('A', drop=True, inplace=True)
writer = pd.ExcelWriter(TEMP_XL_FILE, engine='xlsxwriter')
pdf.to_excel(writer, 'temp')
workbook = writer.book
worksheet = writer.sheets['temp']
tempformat = workbook.add_format('num_format': '0%', 'align': 'center')
worksheet.set_column(-1, 3, None, tempformat)
writer.save()
if __name__ == '__main__':
temp()
【问题讨论】:
您能提供给我们您的代码吗? 在 XlsxWriter 和 Excel 中,单元格格式覆盖行格式覆盖列格式。在这种情况下,Pandas 将单元格格式(合并)应用于索引单元格,因此set_column()
格式没有效果。我认为无法通过 API 覆盖或设置 Panda 的索引格式(datetime_format
和 date_format
除外),
【参考方案1】:
pandas ExcelWriter
会覆盖索引列中的 XlsxWriter
格式。
为防止这种情况,请将熊猫 header_style
更改为 None
header_style = "font": "bold": True,
"borders": "top": "thin",
"right": "thin",
"bottom": "thin",
"left": "thin",
"alignment": "horizontal": "center",
"vertical": "top"
这样做:
import pandas.io.formats.excel
pandas.io.formats.excel.header_style = None
另见
xlsxwriter not applying format to header row of dataframe - Python Pandas Pandas raising: AttributeError: module 'pandas.core' has no attribute 'format'【讨论】:
至少在 1.1.5 中,这是损坏的,header_style
符号在 excel
模块中不存在。【参考方案2】:
据我了解,Pandas 设置索引行的格式。有办法重置它,但这些解决方案不是很可靠。实际格式化也相当困难。
用所需格式写出索引列最适合我:
import pandas as pd
# The data that we're feeding to ExcelWriter
df = pd.DataFrame(
"Col A": ["a", "a", "b", "b"],
"Col B": ["a", "b", "c", "d"],
"Col C": [1, 2, 3, 4],
)
# The Excel file we're creating
writer = pd.ExcelWriter("pandas_out.xlsx", engine="xlsxwriter")
df.to_excel(writer, sheet_name="Sheet1", index=False) # Prevents Pandas from outputting an index
# The variables we'll use to do our modifications
workbook = writer.book
worksheet = writer.sheets["Sheet1"]
worksheet.set_row(0, 30) # Set index row height to 30
# Find more info here: https://xlsxwriter.readthedocs.io/format.html#format-methods-and-format-properties
header_format = workbook.add_format(
"bold": True,
"valign": "vcenter",
"align": "center",
"bg_color": "#d6d6d6",
"border": True,
)
# Write the column headers with the defined format.
for col_num, value in enumerate(df.columns.values):
worksheet.write(0, col_num, value, header_format)
# Set format of data
format1 = workbook.add_format("align": "center")
worksheet.set_column('A:Z', 10, format1) # Width of cell
writer.save()
【讨论】:
您不只是编写列,而是从 Pandas 已经设置的内容中覆盖它们。这并不理想。您可以改为定义自己的格式化程序并保留 Pandas 自己的默认列循环。【参考方案3】:要添加到@Max 的答案,这对我来说适用于 pandas 1.1.5:
import pandas.io.formats.excel
pandas.io.formats.excel.ExcelFormatter.header_style = None
【讨论】:
这似乎用静态覆盖了实例属性,这是个坏主意。 你能推荐一个更好的方法吗? 从 ExcelFormatter 派生并使用它来覆盖header_style
实现;不要做任何猴子补丁;并在需要时使用新的格式化程序类。【参考方案4】:
不要对库进行猴子补丁,从格式化程序类派生
不必费心重写所有代码来自己创建单元格
使用 Pandas 在内部为单元格内容定义的中间“类 CSS”格式化语言;这都写在pandas/io/excel/_xlsxwriter.py
这适用于 1.1.5:
import numpy as np
import pandas as pd
from pandas.io.formats.excel import ExcelFormatter
from typing import Dict, Any
# from Config import TEMP_XL_FILE
TEMP_XL_FILE = 'headers.xlsx'
class CenteredFormatter(ExcelFormatter):
@property
def header_style(self) -> Dict[str, Any]:
d = dict(super().header_style)
d.setdefault('alignment', )['horizontal'] = 'center'
d.setdefault('number_format', )['format_code'] = '0%'
return d
def temp() -> None:
with pd.ExcelWriter(TEMP_XL_FILE, engine='xlsxwriter') as writer:
pdf = pd.DataFrame(np.random.randn(6, 4), columns=list('ABCD'))
pdf.set_index('A', drop=True, inplace=True)
formatter = CenteredFormatter(pdf)
formatter.write(writer, sheet_name='temp')
if __name__ == '__main__':
temp()
【讨论】:
以上是关于如何使用 xlsxwriter 格式化索引列?的主要内容,如果未能解决你的问题,请参考以下文章
python xlsxwriter写excel并操作各种格式属性
python xlsxwriter 在同一个单元格写入不同的格式文本
如何使用 xlsxwriter - python 更改图例字体大小