前言
Python 文件导出最简单方法是 pandas中的 to_excel。如何生成具有一定简单格式的文本?个人感觉 xlsxwriter 无论是文档还是使用方法个人感觉都很赞。
目标
- 适用web文件流导出
- 适用脚本化导出
- 具备和pandas结合
代码
实现
- 支持 pandas DataFrame 、tuple或者list(根据行或者列)写入
- 大文件推荐保存到本地后读取,web小文件推荐文件流方式。个人感觉web文件保存到本地后通过静态文件方式很low。
from io import BytesIO
import xlsxwriter
from typing import Union
import pandas as pd
import os
class Style:
""" 格式类 """
def __init__(self,
title_style: dict = None,
content_style: dict = None,
sheet_name: str = 'Sheet1'
):
local_title_style = {
'font': '仿宋',
'align': 'center',
'valign': 'center',
'bold': True,
'border': None,
'font_size': 12
}
self.title_style = local_title_style if not title_style else title_style
local_content_style = {
'font': '仿宋',
'align': 'center',
'valign': 'center'
}
self.content_style = local_content_style if not content_style else content_style
self.sheet_name = sheet_name
def cell_format(self, wb):
return wb.add_format(self.title_style), wb.add_format(self.content_style)
class DTBase(Style):
"""
行写入或者列写入数据
"""
def __init__(self,
columns: Union[tuple, list], # 表头
content_w_row: int = 1, # 预留表头位置 默认从第二行开始写入
column_width: int = None, # 设置列宽 默认不设置
is_w_col: bool = True, # 是否列写入数据 # 默认列
data: Union[tuple, list] = None, # 数据
*args, **kwargs):
super().__init__(*args, **kwargs)
self.content_w_row = content_w_row
self.column_width = column_width
self.is_w_col = is_w_col
self.data = data
self.columns = columns
def write_column(self, ws, data, content_format):
"""列写入"""
for index, item in enumerate(data):
ws.write_column(self.content_w_row, index, item, cell_format=content_format)
def write_row(self, ws, data, content_format):
"""行写入"""
for index, item in enumerate(data):
ws.write_row(self.content_w_row + index, 0, item, cell_format=content_format)
def set_column(self, ws, col_i):
"""设置列宽"""
ws.set_column(0, col_i, self.column_width)
def worksheet(self, wb):
ws = wb.add_worksheet(self.sheet_name)
# 生成 样式
columns_format, content_format = self.cell_format(wb)
# 写入 头
ws.write_row(0, 0, self.columns, cell_format=columns_format)
# 写入 内容
if self.is_w_col:
self.write_column(ws, self.data, content_format)
else:
self.write_row(ws, self.data, content_format)
if self.column_width:
self.set_column(ws, len(self.columns) - 1)
class DTFile(DTBase):
"""生成文件"""
def __init__(self,
file_name: str,
path: str,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.file_path = os.path.join(path, file_name)
def write(self):
with xlsxwriter.Workbook(self.file_path, {'in_memory': True}) as wb:
self.worksheet(wb)
class DTBytesIO(DTBase):
""" 文件流 """
def write(self):
output = BytesIO()
with xlsxwriter.Workbook(output) as wb:
self.worksheet(wb)
return output.getvalue()
class PDBase(Style):
"""pandas to excel 修改样式 """
def __init__(self,
df: pd.DataFrame,
columns: Union[list, tuple] = None,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.df = df
self.columns = columns
def set_style(self, writer):
workbook = writer.book
worksheet = writer.sheets[self.sheet_name]
# 生成样式
columns_format, content_format = self.cell_format(workbook)
# 设置样式
worksheet.set_column(0, len(self.df) - 1, None, content_format)
columns = self.df.columns.values if not self.columns else self.columns
for col_num, value in enumerate(columns):
worksheet.write(0, col_num, value, columns_format)
class PDFile(PDBase):
""" DataFrame 生成文件 """
def __init__(self,
file_name: str,
path: str,
*args, **kwargs):
super().__init__(*args, **kwargs)
self.file_path = os.path.join(path, file_name)
def write(self):
writer = pd.ExcelWriter(self.file_path, engine='xlsxwriter')
self.df.to_excel(writer, index=False, header=False, sheet_name=self.sheet_name)
self.set_style(writer)
writer.save()
class PDBytes(PDBase):
""" DataFrame 文件流 """
def writer(self):
output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
self.df.to_excel(writer, index=False, header=False, sheet_name=self.sheet_name)
self.set_style(writer)
writer.save()
return output.getvalue()
if __name__ == '__main__':
# d = (('a', 'b', 'c', 'd'), ('e', 'f', 'g', 'h'), ('j', 'k', 'l', 'm'))
#
# t = ('A', 'B', 'C')
# obj = WorkBookLocalFile(data=d, title=t, path=p, write_col=False, column_width=20)
# obj.write()
pass
requirements.txt
numpy==1.23.4
pandas==1.5.1
python-dateutil==2.8.2
pytz==2022.5
six==1.16.0
XlsxWriter==3.0.3
未来
- 目前只支持一个sheet创建,下个版本考虑支持多个sheet导出,为每个sheet导出不同格式。
- 目前只支持简单样式设置。后期准备加入更多的内容
gitee
未完待续...
标签:__,xlsx,style,格式化,format,Python,self,content,columns From: https://blog.51cto.com/u_14967494/5834263