首页 > 编程语言 >Python xlsx 导出格式化

Python xlsx 导出格式化

时间:2022-11-09 11:02:20浏览次数:61  
标签:__ xlsx style 格式化 format Python self content columns

前言

Python 文件导出最简单方法是 pandas中的 to_excel。如何生成具有一定简单格式的文本?个人感觉 xlsxwriter 无论是文档还是使用方法个人感觉都很赞。

目标

  • 适用web文件流导出
  • 适用脚本化导出
  • 具备和pandas结合

代码

实现

  1. 支持 pandas DataFrame 、tuple或者list(根据行或者列)写入
  2. 大文件推荐保存到本地后读取,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

相关文章

  • Python|使用Flask进行Web开发
    基础知识Flask是一个用Python编写的Web应用程序框架。它由ArminRonacher开发,他领导一个名为Pocco的国际Python爱好者团队。Flask基于WerkzeugWSGI工具包和Jinja2模......
  • python应用——借助tinify库实现批量压缩图片
    说在前面的话:转到移动组之后,干起了移动端混合开发,虽说现在的混合开发技术在不断的迭代了,但对比起网页应用来说有一些先天的不足,诸如,硬件性能就是很大的一方面。在pc上调......
  • python(27)反射机制
    1.什么是反射?它的核心本质其实就是基于字符串的事件驱动,通过字符串的形式去操作对象的属性或者方法 2.反射的优点一个概念被提出来,就是要明白它的优点有哪些,这样我......
  • Python 判断字符串是否为数字
    最近的一个小软件,遇到了一个问题就是需要把字符串转成数字,可字符串中有时候会出来特殊字符。所以只需要做一个转换函数才可以的。下面这个函数比较凑效。这里做一个笔记本......
  • python3执行pip list出现警告
    python3执行piplist出现警告WARNING:Youareusingpipversion21.2.3;however,version22.3.1isavailable.Youshouldconsiderupgradingviathe'F:\Python39......
  • 利用python数据分析
    利用python进行数据分析本书由Pythonpandas项目创始人WesMcKinney亲笔撰写,详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。第2版针对P......
  • Linux学习笔记(8)——正则表达式与文件格式化处理
    正则表达式与文件格式化处理正则表达式与文件格式化处理一、什么是正则表达式?二、基础正则表达式2.1语系对正则表达式的影响2.2grep的一些高级选项2.3基础正则......
  • 盘点一个Python处理Excel两列单元格中有类似字符串就返回1,没有就返回0的操作
    大家好,我是Python进阶者。一、前言前几天在才哥的Python交流群遇到了一个粉丝提问,提问截图如下:觉得还挺有意思的,都是Pandas基础操作,这里拿出来给大家一起分享下。二、......
  • python get请求传array数组
    前言使用传统的http发get请求时,如果传参为array数组,参数名称为a时,可以这样传值a=1&a=2&a=3,但是当只有一个时,这种方式就不合理了。get请求还有另外一种方式传array数组,在......
  • 字符串类型如何格式化保留小数点后两位【ToString("0.00")】
    废话都不想写了,直接上图遇到将decimal字段或者double字段转换成字符串string类型字段时想直接保留小数点后面两位的时候可以有个比较简易的格式化写法也就是str.ToStr......