python实现pandas+openpyxl导出excel报表


由于数据的繁杂和日渐增多,报表成为工作上必不可少的一部分,报表的实现既能将数据有规划的整理也能把一大串繁琐的数据变得更加简洁可观。但是用excel处理大量的报表,工作量可想而知,每次都需要在月头和周头花费大量的时间来整理报表。自从学了python,就方便多了,将数据导入用python整理好后,保存为excel文件简直不要太简单,每次有需要的时候点点运行,更改下需求(比如时间)就可以了,可是单纯的用pandas导出的表格却不太美观,这时我就接触到了一个新的库——openpyxl,这个库也可以往excel中写入数据,但个人还是喜欢用pandas来导出excel,再用openpyxl库来修改excel的样式。
openpyxl只支持对xlsx、xlsm文件进行读、写操作,不支持xls文件

# 所需要的库
import itertools
import pandas as pd
from openpyxl.styles import *
from openpyxl.utils import get_column_letter

1.导出excel文件

自行准备一份数据,这里采用的数据是双索引双表头的。
代码实现:

writer = pd.ExcelWriter('文件名.xlsx', engine='openpyxl')
data.to_excel(writer)
worksheet = writer.sheets['Sheet1']    # 默认创建的表格的工作簿名为Sheet1,若不需要进行openpyxl操作,可不写

用pandas导出的表格如下图:

可以发现这份表格看着着实不美观,想要实现的报表样式如下图:

2.隐藏或删除行、列

因为是双索引双表头的表格,导出都会有一行索引名的行,暂时没有找到方法怎么在导出的时候去掉,只能在后续实现删除该行或隐藏该行。

代码实现:

worksheet.delete_rows(3)  # 删除单行
worksheet.delete_cols(3)   # 删除单列
worksheet.delete_cols(6, 3)    # 多列删除,从第六列开始,删除3列即(F:H),行类似

worksheet.row_dimensions[3].hidden = 1  # 隐藏行
worksheet.column_dimensions[3].hidden = 1  # 隐藏列

3.合并单元格并填入数据


代码实现:

worksheet.merge_cells('A1:A2')
worksheet['A1'].value = '部门'
worksheet.merge_cells('B1:B2')
worksheet['B1'].value = '姓名'

4.添加边框

因为pandas导出的表格除了表头处有明显的边框,其他地方都没有,所以需要通过添加边框来美化表格。
注意这里需要导入Border和Side两个函数
代码实现:

# 设置单元格边框
border_set = Border(Side(style='thin', color='FF000000'),
                    right=Side(style='thin', color='FF000000'),
                    top=Side(style='thin', color='FF000000'),
                    bottom=Side(style='thin', color='FF000000'))    # style的参数有很多,可自行搜索
# 设置所有单元格边框
for i in range(1, worksheet.max_row + 1):
    for j in range(1, worksheet.max_column + 1):
        worksheet.cell(row=i, column=j).border = border_set

5.调整行、列宽

因为默认行列宽的原因,使有些单元格的字显示不全,所以需要调整行列宽。
代码实现:

# 更改行高,这里是只有第二行为50,其他行为20
for i in range(1, worksheet.max_row + 1):
    if i == 2:
        worksheet.row_dimensions[i].height = 50
    else:
        worksheet.row_dimensions[i].height = 20
# 更改列的列宽
for i in range(3, worksheet.max_column + 1):   # 从第三列开始
    worksheet.column_dimensions[get_column_letter(i)].width = 20
    # get_column_letter 获取数字对应的字母,例如 get_column_letter(1),输出 A

6.更改表格样式

代码实现:

# 根据需求设置字体、颜色、是否加粗、是否居中、是否换行等
title_font = Font(name="微软雅黑", bold=True)  # 字体加粗
data_font = Font(name="微软雅黑")
alignment = Alignment(horizontal='center', vertical="center", wrapText=True)  # 设置为单元格居中和自动换行
# 设置所有列的格式
for cell in itertools.chain(*worksheet[f"A:{get_column_letter(worksheet.max_column)}"]):
    cell.font = data_font
    cell.alignment = alignment
# 第一行加粗
for cell in itertools.chain(*worksheet[f"A1:{get_column_letter(worksheet.max_column)}1"]):
    cell.font = title_font    # 表头加粗
# 也可以直接用以下的代码,但因为示例表格含有多个合并的单元格,以下两行对该表格不起作用
worksheet.column_dimensions['A'].font = title_font   # A列加粗
worksheet.row_dimensions[1].font = title_font     # # 第一行加粗

7.单元格颜色

代码实现:

# 根据需求设置设置单元格颜色
for i in range(2, worksheet.max_row + 1):   # 从第二行开始到最后一行
    worksheet.cell(row=i, column=4).fill = PatternFill(fill_type='solid', fgColor="FFFFCC")  # 第4列的颜色
    worksheet.cell(row=i, column=8).fill = PatternFill(fill_type='solid', fgColor="FFEB9C")  # 第8列的颜色
    worksheet.cell(row=i, column=11).fill = PatternFill(fill_type='solid', fgColor="C6EFCE")  # 第11列的颜色

fill_type 参数:官方文档给出了很多种填充类型,一般纯色填充使用 solid ,其他样式自行尝试
‘none’、‘solid’、‘darkDown’、‘darkGray’、‘darkGrid’、‘darkHorizontal’、‘darkTrellis’、‘darkUp’、‘darkVertical’、‘gray0625’、‘gray125’、‘lightDown’、‘lightGray’、‘lightGrid’、‘lightHorizontal’、‘lightTrellis’、‘lightUp’、‘lightVertical’、‘mediumGray’

8.单元格插入公式、更改数字格式

因为有些表格涉及到有些数据需要手动填写,这时就需要设计一些公式进行计算
代码实现:

# 根据需求为单元格插入公式并更改数字格式
for i in range(4, worksheet.max_row + 1):
    worksheet[f'F{i}'] = f'=IFERROR((D{i}/C{i})," ")'
    worksheet[f'F{i}'].number_format = '0%'

9.实现

下面附上完整代码:

# 绩效报表
import itertools
import pandas as pd
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from openpyxl.utils import get_column_letter

# 数据整理
def get_data(data, department, start_time, end_time):
	''''
    return ddd_sum

# 获取汇总所在的行数
def row(ddd_sum):
    sum_list = []
    for i in range(len(ddd_sum)):
        if (('组别小计:' in ddd_sum.index[i]) | ('总计1:' in ddd_sum.index[i]) |
            ('总计2:' in ddd_sum.index[i]) | ('公司总计:' in ddd_sum.index[i])):
            l = i + 4  # 加上0行、空行和双级表头行
            sum_list.append(l)
    return sum_list

# 制作报表格式
def excel(writer, sum_list):
    worksheet = writer.sheets['Sheet1']
    worksheet.row_dimensions[3].hidden = 1  # 隐藏空行
    # 合并单元格
    worksheet.merge_cells('A1:A2')
    worksheet['A1'].value = '部门'
    worksheet.merge_cells('B1:B2')
    worksheet['B1'].value = '姓名'
    for i in sum_list[-3:]:
        worksheet.merge_cells(f'A{i}:B{i}')
    title_font = Font(name="微软雅黑", bold=True)  # 字体加粗
    data_font = Font(name="微软雅黑")
    alignment = Alignment(horizontal='center', vertical="center", wrapText=True)  # 设置为单元格居中和自动换行
    # 设置单元格边框
    border_set = Border(Side(style='thin', color='FF000000'),
                        right=Side(style='thin', color='FF000000'),
                        top=Side(style='thin', color='FF000000'),
                        bottom=Side(style='thin', color='FF000000'))
    # 设置所有单元格边框
    for i in range(1, worksheet.max_row + 1):
        for j in range(1, worksheet.max_column + 1):
            worksheet.cell(row=i, column=j).border = border_set
    # 更改行高
    for i in range(1, worksheet.max_row + 1):
        if i == 2:
            worksheet.row_dimensions[i].height = 50
        else:
            worksheet.row_dimensions[i].height = 20
    # 更改列的列宽
    for i in range(3, worksheet.max_column + 1):
        worksheet.column_dimensions[get_column_letter(i)].width = 20
    # 设置所有格式
    for cell in itertools.chain(*worksheet[f"A:{get_column_letter(worksheet.max_column)}"]):
        cell.font = data_font
        cell.alignment = alignment
    # 设置表头格式
    for r in [1] + sum_list:
        for cell in itertools.chain(*worksheet[f"A{r}:{get_column_letter(worksheet.max_column)}{r}"]):
            cell.font = title_font
    worksheet.column_dimensions['A'].font = title_font
    # 设置单元格颜色
    for i in range(2, worksheet.max_row + 1):
        worksheet.cell(row=i, column=4).fill = PatternFill(fill_type='solid', fgColor="FFFFCC")
        worksheet.cell(row=i, column=8).fill = PatternFill(fill_type='solid', fgColor="FFEB9C")
        worksheet.cell(row=i, column=11).fill = PatternFill(fill_type='solid', fgColor="C6EFCE")
    # 为单元格插入公式并更改数字格式
    for i in range(4, worksheet.max_row + 1):
        worksheet[f'E{i}'] = '公式'
        worksheet[f'F{i}'] = '公式'
        worksheet[f'F{i}'].number_format = '0%'
        worksheet[f'I{i}'] = '公式'
        worksheet[f'J{i}'] = '公式'
        worksheet[f'J{i}'].number_format = '0%'
    # 手动填写统计
    for i in ['C', 'G']:
        worksheet[f'{i}{sum_list[0]}'] = '公式'
        worksheet[f'{i}{sum_list[1]}'] = '公式'
        worksheet[f'{i}{sum_list[2]}'] = '公式'
        worksheet[f'{i}{sum_list[3]}'] = '公式'
        worksheet[f'{i}{sum_list[4]}'] = '公式'
        worksheet[f'{i}{sum_list[5]}'] = '公式'
    return worksheet

if __name__ == '__main__':
	# 设置所需时间
    start_time = '2021.3.1'
    end_time = '2021.3.7'
    data = pd.read_csv('./成交明细.csv', parse_dates=['成交日期'])
    department = pd.read_excel('./部门.xlsx')
    dt = get_data(data, department, start_time, end_time)
    r = row(dt)
    with pd.ExcelWriter(f'./报表{start_time}-{end_time}.xlsx', engine='openpyxl') as writer:
        dt.to_excel(writer)
        excel(writer, r)
        writer.save()
    writer.close()
  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用pandasopenpyxl导出Excel文件时,可以通过格式设置来自定义工作表的样式和格式。 首先,可以使用pandas数据导出Excel文件,通过`to_excel()`方法指定文件路径和文件名。例如: ```python import pandas as pd data = {'Name': ['Tom', 'Nick', 'John'], 'Age': [28, 32, 25], 'Salary': [5000, 7000, 4500]} df = pd.DataFrame(data) df.to_excel('output.xlsx', index=False) ``` 然后,使用openpyxl库打开导出Excel文件,并进行格式设置。例如,可以设置单元格的字体、对齐方式、边框等。下面是一个设置示例: ```python from openpyxl import load_workbook from openpyxl.styles import Font, Alignment, Border, Side workbook = load_workbook('output.xlsx') worksheet = workbook.active # 设置字体样式 font = Font(name='Arial', size=12, bold=True) worksheet['A1'].font = font # 设置对齐方式 alignment = Alignment(horizontal='center', vertical='center') worksheet['A1'].alignment = alignment # 设置边框 border = Border(left=Side(border_style='thin'), right=Side(border_style='thin'), top=Side(border_style='thin'), bottom=Side(border_style='thin')) worksheet['A1'].border = border workbook.save('output.xlsx') ``` 以上示例使用了openpyxl的Font、Alignment和Border类来分别设置了字体样式、对齐方式和边框。 通过这些设置,可以根据需要自定义Excel表格的样式,使导出Excel文件更加美观和易读。需要注意的是,在进行格式设置时,需要先载入已存在的Excel文件,再对相应的单元格进行设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值