pandas + openpyxl 生成excel,并设置样式

本文介绍如何使用Pandas和Openpyxl库自动化创建复杂报表,包括生成特定格式的DataFrame,添加计算列和汇总行,以及设置Excel样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期,利用pandas+openpyxl,做了一个关于报表的项目,写个博客,就当作笔记记录一下吧。
一、举个例子,如下图:
在这里插入图片描述
需要实现,如上的报表,稍作分析下,我们可以从以下几个方面入手:
1、生成一个,shape是,(12,2)的pandas对象,列索引是多重索引,其他三列是计算列,以后再加。
2、axis=1 方向,添加 AA-BB 就是 AA列减去BB列,其他类似。
3、axis=0 方向,添加 total行 是计算总和。
4、数据格式,数值需要格式话千分位; A列靠左对齐;column居中显示;前四行,加粗靠左显示;total行有上下单双边框;第五行还有背景颜色;行列折叠等等。

ok,写代码,按步骤实现。
一、

import pandas as pd
import numpy as np
import openpyxl
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill

# 设置pandas对象全部显示
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)


def get_df():
    """
    生成目标pandas对象
    生成一个,shape是,(12,2)的pandas对象,列索引是多重索引,其他三列是计算列,以后再加
    :return:
    """
    # axis=0索引
    indexs = [
        'aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg',
        'hhh', 'iii', 'jjj', 'kkk', 'lll'
    ]
    # axis = 1 是一个多层索引
    column_index_level_1 = ['CC'] * 2
    column_index_level_2 = ['AA', 'BB']
    # 多层索引,可以用多维数组创建
    column_all = [column_index_level_1, column_index_level_2]

    # 数据准备
    df = pd.DataFrame(data=np.random.rand(12, 2), index=indexs, columns=column_all)

    # 将数据扩大100万倍
    df = df * 100000
    return df


def add_column_and_row(df):
    """
    添加行和列,并且格式化百分位的数据
    :param df:
    :return:
    """
    # 添加 CC, 'AA-BB' 'AA+BB' 'AA/BB' 列
    df[('CC', 'AA-BB')] = df.apply(lambda x: x[('CC', 'AA')] - x[('CC', 'BB')], axis=1)
    df[('CC', 'AA+BB')] = df.apply(lambda x: x[('CC', 'AA')] + x[('CC', 'BB')], axis=1)
    df[('CC', 'AA/BB')] = df.apply(lambda x: x[('CC', 'AA')] / x[('CC', 'BB')] if x[('CC', 'BB')] != 0 else np.NAN, axis=1)

    # 添加 total行
    df.loc['total'] = df.apply(lambda x: x.sum(), axis=0)

    # AA/BB 格式化,并且保留两位小数
    df[('CC', 'AA/BB')] = df[('CC', 'AA/BB')].apply(lambda x: format(x, '.2%'))

def generate_excel(df, excel_name='./test.xlsx', sheet_name='total'):
    """
    生成excel
    :param sheet_name:
    :param excel_name:
    :param df:
    :return:
    """
    # 如果文件存在,直接添加sheet;不存在则创建新的文件
    excel_writer = pd.ExcelWriter(excel_name, engine='openpyxl')
    if not os.path.exists(excel_name):
        df.to_excel(excel_writer, sheet_name=sheet_name)
    else:
        book = openpyxl.load_workbook(excel_writer.path)
        excel_writer.book = book
    df.to_excel(excel_writer, sheet_name=sheet_name)
    excel_writer.save()
    excel_writer.close()

def set_excel_style(df, excel_name='./sample.xlsx', sheet_name='total'):
    book = openpyxl.load_workbook(excel_name)
    sheet = book[sheet_name]

    # 初始化字体样式
    font_bold = Font(name='Arial',
                     size=8,
                     bold=True,
                     italic=False,
                     vertAlign=None,
                     underline='none',
                     strike=False,
                     color='FF000000',
                     outline='None')

    font_not_bold = Font(name='Arial',
                         size=8,
                         italic=False,
                         vertAlign=None,
                         underline='none',
                         strike=False,
                         color='FF000000',
                         outline='None')

    # 插入前四行
    for i in range(1, 5):
        sheet.insert_rows(i)

    # 删除第7行默认的空白
    for row in range(7, sheet.max_row):
        for column in range(sheet.max_column):
            sheet[row][column].value = sheet[row + 1][column].value
    for cell in list(sheet.rows)[sheet.max_row - 1]:
        cell.value = None

    # 格式化数字
    for r, row in enumerate(sheet.rows):
        for c, cell in enumerate(row):
            if cell.row > 6:
                cell.number_format = '#,##0;-#,##0'
                cell.alignment = Alignment(horizontal='left', vertical='center')

    border_none = Border(top=Side(), bottom=Side(), left=Side(), right=Side())
    border_double = Border(top=Side(border_style='thin'), bottom=Side(border_style='double'), left=Side(), right=Side())
    # 设置整体的字体
    for row in sheet.rows:
        for cell in row:
            cell.font = font_not_bold
            cell.border = border_none

    # 前四行的第一个cell,加粗靠左
    sheet.cell(1, 1, value='Tittle').font = font_bold
    sheet.cell(2, 1, value='Period: Jun 2019').font = font_bold
    sheet.cell(3, 1, value='2019 Financial YTD Summary').font = font_bold
    sheet.cell(4, 1, value="(CNY '000)").font = font_bold
    for cell in sheet['A']:
        cell.alignment = Alignment(horizontal='left', vertical='center')
        if cell.value == 'total':
            cell.font = font_bold
            for cell__ in sheet[cell.row]:
                if cell__.column > 1:
                    cell__.border = border_double
                    cell__.font = font_bold
    # 合并列
    sheet.merge_cells(start_row=5, start_column=2, end_row=5, end_column=6)

    # 第五行 第二列 设置背景颜色
    sheet.cell(5, 2).alignment = Alignment(horizontal='center', vertical='center')
    sheet.cell(5, 2).fill = PatternFill(fill_type='solid', fgColor="B4C6E7")

    # 列折叠
    sheet.column_dimensions.group('B', 'D', hidden=True)

    # 行折叠
    sheet.row_dimensions.group(7, 7 + len(df.index) - 2, hidden=True)
    book.save(excel_name)


if __name__ == '__main__':
    df = get_df()
    add_column_and_row(df)
    generate_excel(df)
    set_excel_style(df)

ok,运行代码,会在当前目录下生成 sample.xlsx,打开如下图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191006195042316.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hkbjU0MQ==,size_16,color_FFFFFF,t_70)
### 使用Python Pandas生成Excel表格 为了使用Pandas库创建Excel文件,首先需要安装`pandas`以及用于操作Excel文件的依赖包`openpyxl`或`xlsxwriter`。可以通过pip命令完成这些库的安装。 ```bash pip install pandas openpyxl ``` 下面是一个完整的例子展示如何利用给定的数据集构建保存到一个新的Excel文件中: #### 创建DataFrame对象 通过定义一个字典来表示列名及其对应的数据列表,可以方便地初始化一个DataFrame实例[^3]。 ```python import pandas as pd # 导入pandas模块,重命名为pd以便后续调用更简洁 data = { 'ID': [1, 2, 3], 'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [28, 24, 30] } df = pd.DataFrame(data) # 将字典转换成DataFrame结构 print(df) ``` 此段代码会打印出如下所示的内容: ``` ID Name Age 0 1 Alice 28 1 2 Bob 24 2 3 Charlie 30 ``` #### 写入Excel文件 一旦有了DataFrame对象之后,就可以很容易地将其写入Excel文件中。这里展示了两种不同的方式来控制是否包含索引和标题行[^1]。 ```python output_file = './example.xlsx' # 不带索引但保留表头的方式存储至指定路径下的Excel文档内 df.to_excel(output_file, sheet_name='Sheet1', index=False) # 如果希望不显示任何额外的信息(即既无索引也无表头),则可按以下方法执行 df.to_excel('no_header_index_example.xlsx', index=False, header=False) ``` 上述代码片段将会把名为`example.xlsx`的新Excel文件存放在当前目录下,默认情况下会在第一个工作表(`sheet`)里添加数据,且可以选择性地省略掉默认自动生成的第一列作为行标签的部分。 对于更加复杂的场景,比如向已有的Excel文件追加新的记录或是调整单元格样式等问题,则可能涉及到更多高级功能的应用[^5]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永不止步——

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值