Pandas基于StyleFrame设置表格样式

对于Excel样式设置库——StyleFrame,也做简单介绍:

1、安装:
pip install StyleFrame
2、基础数据暂时都用data(模拟数据)做测试。
from StyleFrame import StyleFrame, Styler
for sheet in data.keys():
    sf = StyleFrame(data[sheet]) #实例化数据对象

sf不同于DataFrame表的df,是不可以预览的。

3、Styler——样式设置对象:详情可前去官网查看: StyleFrame官网
Styler(bg_color=None, bold=False, font=utils.fonts.arial, font_size=12, font_color=None, number_format=utils.number_formats.general, protection=False,
underline=None, border_type=utils.borders.thin, horizontal_alignment=utils.horizontal_alignments.center, vertical_alignment=utils.vertical_alignments.center,
wrap_text=True, shrink_to_fit=True, fill_pattern_type=utils.fill_pattern_types.solid, indent=0, comment_author=None, comment_text=None, text_rotation=0)
解释:
参数 说明
bg_color 单元格背景色
bold 字体加粗与否设置
font 字体类型
font_size 字体大小
font_color 字体颜色
number_format 数值格式
protection 保护表格不被修改
underline 下划线设置
border_type 边框线设置
horizontal_alignment 水平方向对齐设置
vertical_alignment 垂直方向对齐设置
wrap_text 是否自动换行
shrink_to_fit 是否根据字符长度缩小以适应单元格
fill_pattern_type 背景填充模式
indent 缩进距离
comment_author 批注作者
comment_text 批注内容
a)在某一列上使用样式时需要用到如下方法:
apply_column_style(cols_to_style,styler_obj,style_header)

1、cols_to_style:要设置样式的列名
2、styler_obj:样式对象,即上面设置过的Styler
3、style_header:是否将表头也设置样式
实例:

sf.apply_column_style(cols_to_style=["列名",'列名1'],
					  styler_obj=Styler(number_format="0"),
                      style_header=True)
b)在行上使用
apply_style_by_indexes(indexes_to_style,styler_obj,cols_to_style)

1、indexes_to_style: 要设置样式的行,sf[sf[‘col1’] = 20]表示设置col1列等于20的行
2、styler_obj: 样式对象
3、cols_to_style: 要设置通过indexes_to_style选出那些行对应的哪些列
实例:

indexes_to_style=sf[sf['列名'] < '10'] # 列名列数值小于10的单元格
#sf.apply_style_by_indexes(indexes_to_style=sf[sf['列名'] < '10'],
        cols_to_style=['列名'],styler_obj=Styler(font_color="#FF0000"))
c)字体大小:font_size\加粗:bold
sf.apply_column_style(cols_to_style=["col_2"], 
                      styler_obj=Styler(font_size=12, bold=True),
                      style_header=True)
d)背景色:bg_colors
sf.apply_column_style(cols_to_style=["col_2"], 
                      styler_obj=Styler(bg_color='red'),
                      style_header=True)
e)对齐方式:horizontal_alignment
general = 'general' #一般
left = 'left' #左对齐
center = 'center' #居中对齐
right = 'right' #右对齐
fill = 'fill' #填满单元格对齐
justify = 'justify' #两端对齐
center_continuous = 'centerContinuous'
distributed = 'distributed' #分散对齐

实例:

sf.apply_column_style(cols_to_style=["col_3"], 
                      styler_obj=Styler(horizontal_alignment="center"),
                      style_header=True)
f)垂直方向对齐:vertical_alignment
top = 'top' #靠上对齐
center = 'center' #靠中对齐
bottom = 'bottom' #靠下对齐
justify = 'justify' #两端对齐
distributed = 'distributed' #分散对齐

实例:

sf.apply_column_style(cols_to_style=["col_3"], 
                      styler_obj=Styler(vertical_alignment="center"),
                      style_header=True)
g)数字显示:number_format
general = 'General' #对应Excel中的常规
general_integer = '0' #不保留小数点 
general_float = '0.00' #保留两位小数点
percent = '0.0%' #百分数
thousands_comma_sep = '#,##0' #千位分隔样式
date = 'DD/MM/YY' #年月日
time_24_hours = 'HH:MM' #小时分钟
time_24_hours_with_seconds = 'HH:MM:SS' #小时分钟秒
time_12_hours = 'h:MM AM/PM' #12小时分钟 上下午区分
time_12_hours_with_seconds = 'h:MM:SS AM/PM' #12小时分钟秒 上下午区分
date_time = 'DD/MM/YY HH:MM' #年月日时分
date_time_with_seconds = 'DD/MM/YY HH:MM:SS' #年月日时分秒

实例:

sf.apply_column_style(cols_to_style=["col_1"], 
                      styler_obj=Styler(number_format="0"),
                      style_header=True)
sf.apply_column_style(cols_to_style=["col_2"], 
                      styler_obj=Styler(number_format="0.000"),
                      style_header=True)
sf.apply_column_style(cols_to_style=["col_3"], 
                      styler_obj=Styler(number_format="0.0%"),
                      style_header=True)
h)条件格式:add_color_scale_conditional_formatting
num = 'num' #根据具体数值
percent = 'percent' #根据百分数
max = 'max' #根据最大值
min = 'min' #根据最小值
formula = 'formula' #根据公式
percentile = 'percentile' #根据分位数
i)设置列宽:set_column_width\set_column_width_dict
sf.set_column_width(columns = ["col_1","col_2","col_3"],width=10)
sf.set_column_width_dict(col_width_dict = {"col_1":10,"col_2":20,"col_3":30})
j)设置行高:set_row_height\set_row_height_dict

最近需要做一些数据汇总,并存储在Excel表格中,又想外观看过去好看一点,那怎么办呢,找到一个StyleFrame库可以很容易的解决这问题。
正对pandas处理合并单元格暂未去测试,下次有空查阅一下资料看看能否解决。
利用pandas存储数据的前提是先组织好数据:
数据格式可以整理成以下格式:
数据 = {表名:{‘列名称’:数据(列表格式),…}}
data = {‘test’:{‘name’:[‘小明’,‘小红’,…]}}
为了方便调用数据存储,封装个类:

import pandas as pd
from StyleFrame import StyleFrame, Styler
class ExcelData(object):
    '''
    Excel操作

    '''
    def __init__(self):
        self.sheet_data = {}

    def addSheet(self, sheetname, DataFrame):
        self.sheet_data[sheetname] = DataFrame

    def readFile(self, filename, sheetnames):
    	'''
    	根据表名读取数据-前提得先知道sheetname
    	'''
        for sheet in sheetnames:
            self.sheet_data[sheet] = pd.read_excel(filename, sheetname=sheet)
        return self.sheet_data

    def readDimFile(self, filename, sheetnames):
    	'''
    	读取文件所有表数据
    	'''
    	data = pd.read_excel(filename, None)
        return data
    def addSumFile(self, public_asin):
        datas = {'合计':[''],
        '=SUM(C4:C'+ str(len(public_asin) + 5)+')':[''],
        '=SUM(D4:D'+ str(len(public_asin) + 5)+')':[''],
        '=IF(C2=0,0,ROUND(D2*100/C2,1))&"%"':[''],
        '=SUM(F4:F'+ str(len(public_asin) + 5)+')':[''],
        '=SUM(G4:G'+ str(len(public_asin) + 5)+')':[''],
        '=IF(F2=0,0,ROUND(G2*100/F2,1))&"%"':[''],
        '=SUM(I4:I'+ str(len(public_asin) + 5)+')':[''],
        '=SUM(J4:J'+ str(len(public_asin) + 5)+')':[''],
        '=IF(I2=0,0,ROUND(J2*100/I2,1))&"%"':[''],
        '=SUM(L4:L'+ str(len(public_asin) + 5)+')':[''],
        '=SUM(M4:M'+ str(len(public_asin) + 5)+')':[''],
        '=IF(L2=0,0,ROUND(M2*100/L2,1))&"%"':[''],
        '=IF(C2=0,0,ROUND((I2-C2)*100/C2,1))&"%"':[''],
        '=IF(D2=0,0,ROUND((J2-D2)*100/D2,1))&"%"':[''],
        '=IF(E2=0,0,ROUND((K2-E2)*100/E2,1))&"%"':[''],
        '=IF(F2=0,0,ROUND((L2-F2)*100/F2,1))&"%"':[''],
        '=IF(G2=0,0,ROUND((M2-G2)*100/G2,1))&"%"':[''],
        '=IF(H2=0,0,ROUND((N2-H2)*100/H2,1))&"%"':['']}
        col_dicts = ['合计', '=SUM(C4:C'+ str(len(public_asin) + 5)+')',
                    '=SUM(D4:D'+ str(len(public_asin) + 5)+')',
                    '=IF(C2=0,0,ROUND(D2*100/C2,1))&"%"',
                    '=SUM(F4:F'+ str(len(public_asin) + 5)+')',
                    '=SUM(G4:G'+ str(len(public_asin) + 5)+')',
                    '=IF(F2=0,0,ROUND(G2*100/F2,1))&"%"',
                    '=SUM(I4:I'+ str(len(public_asin) + 5)+')',
                    '=SUM(J4:J'+ str(len(public_asin) + 5)+')',
                    '=IF(I2=0,0,ROUND(J2*100/I2,1))&"%"',
                    '=SUM(L4:L'+ str(len(public_asin) + 5)+')',
                    '=SUM(M4:M'+ str(len(public_asin) + 5)+')',
                    '=IF(L2=0,0,ROUND(M2*100/L2,1))&"%"',
                    '=IF(C2=0,0,ROUND((I2-C2)*100/C2,1))&"%"',
                    '=IF(D2=0,0,ROUND((J2-D2)*100/D2,1))&"%"',
                    '=IF(E2=0,0,ROUND((K2-E2)*100/E2,1))&"%"',
                    '=IF(F2=0,0,ROUND((L2-F2)*100/F2,1))&"%"',
                    '=IF(G2=0,0,ROUND((M2-G2)*100/G2,1))&"%"',
                    '=IF(H2=0,0,ROUND((N2-H2)*100/H2,1))&"%"']
        DataFrame = pd.DataFrame(data=datas)
        DataFrame = DataFrame.ix[:, col_dicts]
        return DataFrame

    def saveFile(self, filename, sheet_names, cols_dict):
        excel_writer = StyleFrame.ExcelWriter(filename)
        for sheet in sheet_names:
            #如果想在一个sheet表中写入多次数据,那么可以实例化多个sf对象,前提是写到不同的单元格。
            #如,需指定sheet_name为同一个表
            # 以下的sf2的目的是想在已有的数据表头部加一行合计汇总的数据
            #sf2 = StyleFrame(self.addSumFile(self.sheet_data[sheet]['数据列']))
            #sf2.to_excel(excel_writer, sheet_name=sheet, index=False, startcol=1, startrow=1) 
            #排序
            #sort_data = self.sheet_data[sheet].sort_values(by=['排序列'], ascending=[True])
            #sf = StyleFrame(self.sheet_data[sheet])
            sf = StyleFrame(self.sheet_data[sheet])
            key_len = get_maxlen(self.sheet_data[sheet]) # 获取单元格最长字符串
            style_cols = cols_dict[sheet] # 需要设置样式的列名
            for key in self.sheet_data[sheet]:
                if key == '列名':
                    withs = key_len[key]*1.5 # 设置宽度:每个字符的1.5倍
                else:
                    withs = key_len[key]*0.45 if key_len[key] > len(key) else len(key)*0.7
                sf.set_column_width(columns=[key], width=withs) # 设置列宽
            # 设置excel的样式:styler_obj的样式一列只能设置一次,所以重复设置会以后一个为准
            sf.apply_column_style(cols_to_style=style_cols, styler_obj=Styler(font_size=10.5, bg_color='#DDD9C4'), style_header=True)
            # apply_style_by_indexes:指定列添加样式,以下表示'列名'这一列数值小于10的把字体标注为红色
            sf.apply_style_by_indexes(indexes_to_style=sf[sf['列名'] < '10'],cols_to_style=['列名'],styler_obj=Styler(font_color="#FF0000"))
            # 格式化数字类型number_format:
            # general = 'General' #对应Excel中的常规
            # general_integer = '0' #不保留小数点 
            # general_float = '0.00' #保留两位小数点
            # percent = '0.0%' #百分数
            # thousands_comma_sep = '#,##0' #千位分隔样式
            # date = 'DD/MM/YY' #年月日
            # time_24_hours = 'HH:MM' #小时分钟
            # time_24_hours_with_seconds = 'HH:MM:SS' #小时分钟秒
            # time_12_hours = 'h:MM AM/PM' #12小时分钟 上下午区分
            # time_12_hours_with_seconds = 'h:MM:SS AM/PM' #12小时分钟秒 上下午区分
            # date_time = 'DD/MM/YY HH:MM' #年月日时分
            # date_time_with_seconds = 'DD/MM/YY HH:MM:SS' #年月日时分秒
            sf.apply_column_style(cols_to_style=["col_1"], 
                      styler_obj=Styler(number_format="0"),
                      style_header=True)
            sf.apply_column_style(cols_to_style=["col_2"], 
                      styler_obj=Styler(number_format="0.000"),
                      style_header=True)
            sf.apply_column_style(cols_to_style=["col_3"], 
                      styler_obj=Styler(number_format="0.0%"),
                      style_header=True)
            # row_to_add_filters=0 表示第一行加筛选条件,等于1则是第二行加筛选条件
            # startrow表示起始行,2表示第三行开始填充,默认为0,第一行开始
            sf.to_excel(excel_writer=excel_writer, row_to_add_filters=0, sheet_name=sheet, index=False, startrow=2)
        excel_writer.save()

保存excel:传入个sheetnames意在固定字表顺序

def save_excel(datas, path, cols_dict, sheet_names):
    excels = ExcelData()
    for i in range(len(sheet_names)):
        DataFrame = pd.DataFrame(data=datas[sheet_names[i]])
        DataFrame = DataFrame.ix[:, list(cols_dict[str(sheet_names[i])])] # 首列按照list(cols_dict[str(sheet_names[i])])列表顺序排序
        excels.addSheet(sheet_names[i], DataFrame)
    excels.saveFile(path, sheet_names, cols_dict)

获取单元格最长字符串

def get_maxlen(datas):
    b = {}
    for data in datas:
        b[data] = [len(str(d)) for d in datas[data]]
        b[data] = max(b[data])

    return b

样式设置:

sf = StyleFrame(data)
sf.apply_style_by_indexes(indexes_to_style=sf[sf['列名'] < -0.3],
							  cols_to_style=['列名'],
							  styler_obj=Styler(font_color="#FF0000", number_format="0.0%"))

sf[sf[‘列名’] < -0.2]这种无非也就是返回符合指定条件的索引列表,如果是单一的条件,没有多重条件,这种写法可以达到需求,如果想用多重条件,我一开始尝试着:

	sf[sf['列名'] < -0.2 , sf['列名'] > -0.3]
	sf[sf['列名'] < -0.2 and sf['列名'] > -0.3]
	sf[sf['列名'] < -0.2 & sf['列名'] > -0.3]

以上三种写法均会报错。后面我就想都是传入索引列表,那何不自己先把符合条件的索引先获取,然后再传入就可以了,所以修改后:

val_index_list = []
for idx,vals in enumerate(sheet_data['sheet名']['列名']):
	if vals < -0.2 and  vals > -0.3:
		val_index_list.append(idx)
sf.apply_style_by_indexes(indexes_to_style=val_index_list,
							  cols_to_style=['列名'],
							  styler_obj=Styler(font_color="#FF0000", number_format="0.0%"))

以下来一张结果图:
在这里插入图片描述
在这里插入图片描述

  • 9
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Pandas可以使用openpyxl库来设置Excel表格样式。具体步骤如下: 1. 导入openpyxl库和pandas库 ```python import openpyxl import pandas as pd ``` 2. 读取Excel文件 ```python df = pd.read_excel('example.xlsx') ``` 3. 创建ExcelWriter对象 ```python writer = pd.ExcelWriter('example.xlsx', engine='openpyxl') ``` 4. 将DataFrame写入Excel文件 ```python df.to_excel(writer, sheet_name='Sheet1', index=False) ``` 5. 获取工作簿和工作表对象 ```python workbook = writer.book worksheet = writer.sheets['Sheet1'] ``` 6. 设置单元格样式 ```python from openpyxl.styles import Font, Color, Alignment, Border, Side, colors # 设置字体 font = Font(name='Calibri', size=12, bold=True, italic=False, color=colors.BLACK) # 设置背景颜色 fill = PatternFill(start_color='FFC7CE', end_color='FFC7CE', fill_type='solid') # 设置边框 border = Border(left=Side(border_style='thin', color='000000'), right=Side(border_style='thin', color='000000'), top=Side(border_style='thin', color='000000'), bottom=Side(border_style='thin', color='000000')) # 设置对齐方式 alignment = Alignment(horizontal='center', vertical='center', wrap_text=True) # 设置单元格样式 cell_format = NamedStyle(name='cell_format') cell_format.font = font cell_format.fill = fill cell_format.border = border cell_format.alignment = alignment workbook.add_named_style(cell_format) # 设置单元格样式 for row in range(2, worksheet.max_row + 1): for col in range(1, worksheet.max_column + 1): cell = worksheet.cell(row=row, column=col) cell.style = cell_format ``` 7. 保存Excel文件 ```python writer.save() ``` 以上就是使用Pandas设置Excel表格样式的步骤。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值