超超长篇 - 手把手带你用python玩转Excel

文章目录

  • pandas库读取excel
      • 1、按行读取 Excel 文件
      • 2、按列读取 Excel 文件
      • 3、总结示例
  • openpyxl操作excel
    • 1、基础使用
      • 创建一个新的 Excel 工作簿
      • 打开一个现有的 Excel 文件
      • 写入数据到工作表
      • 读取工作表中的数据
      • 操作行和列
      • 合并和拆分单元格
    • 2、按行写入Excel
    • 3、按列写入Excel
    • 4、追加写入
    • 5、按行读取Excel
    • 6、按列读取Excel
    • 7、认识sheet
      • 遍历sheet的值
    • 8、样式大全介绍
      • 1. 设置字体(Font)
      • 2. 设置填充(Fill)
      • 3. 设置边框(Border)
        • Side 类
        • Border 类
        • 边框代码示列
      • 4. 设置对齐方式(Alignment)
      • 作用
      • 5. 设置数字格式(Number Format)
      • 6. 设置单元格保护(Protection)
      • 7.设置列宽
      • 8、设置行高
    • 9、样式组合使用封装
    • 10、复制他表数据到新的sheet页
    • 11、复制他表数据到新的sheet页-保留样式

本文配套代码及笔记地址:

gitee:https://gitee.com/xiaozai-van-liu/mwj_utils

github:https://github.com/Lvan826199/mwj_utils

求star,求star,求star ~

pandas库读取excel

使用 pandas 库读取 Excel 文件时,可以按行或按列读取数据。以下是分别实现这两种读取方式的方法。

1、按行读取 Excel 文件

按行读取 Excel 文件通常是指读取整个工作表并按行处理数据。以下是一个示例方法:

import pandas as pd

def read_excel_by_rows(file_path, sheet_name=0):
    """
    按行读取 Excel 文件。

    参数:
    - file_path (str): Excel 文件路径
    - sheet_name (str or int): 工作表名称或索引,默认读取第一个工作表

    返回:
    - DataFrame: 包含 Excel 数据的 DataFrame
    """
    # 读取 Excel 文件
    df = pd.read_excel(file_path, sheet_name=sheet_name)
    
    # 按行处理数据
    for index, row in df.iterrows():
        print(f"Row {index}: {row.to_dict()}")
    
    return df

# 示例使用
file_path = 'example.xlsx'
df_rows = read_excel_by_rows(file_path)

2、按列读取 Excel 文件

按列读取 Excel 文件通常是指读取整个工作表并按列处理数据。以下是一个示例方法:

import pandas as pd

def read_excel_by_columns(file_path, sheet_name=0):
    """
    按列读取 Excel 文件。

    参数:
    - file_path (str): Excel 文件路径
    - sheet_name (str or int): 工作表名称或索引,默认读取第一个工作表

    返回:
    - DataFrame: 包含 Excel 数据的 DataFrame
    """
    # 读取 Excel 文件
    df = pd.read_excel(file_path, sheet_name=sheet_name)
    
    # 按列处理数据
    for column in df.columns:
        print(f"Column {column}: {df[column].tolist()}")
    
    return df

# 示例使用
file_path = 'example.xlsx'
df_columns = read_excel_by_columns(file_path)
  1. 按行处理数据
    • 使用 df.iterrows() 方法按行迭代 DataFrame。
    • 在每次迭代中,index 是行索引,row 是包含该行数据的 Series。
    • 示例中使用 row.to_dict() 将每行数据转换为字典格式并打印。
  2. 按列处理数据
    • 遍历 df.columns 获取每一列的名称。
    • 使用 df[column] 获取列数据,并使用 tolist() 将列数据转换为列表格式并打印。

3、总结示例

假设 example.xlsx 文件包含以下数据:

NameAgeCity
梦小仔30深圳
无矶25上海
无妨35北京

运行上述代码后:

  • 按行读取 方法将输出每一行的数据:

    Row 0: {'Name': '梦小仔', 'Age': 30, 'City': '深圳'}
    Row 1: {'Name': '无矶', 'Age': 25, 'City': '上海'}
    Row 2: {'Name': '无妨', 'Age': 35, 'City': '北京'}
    
  • 按列读取 方法将输出每一列的数据:

    Column Name: ['梦小仔', '无矶', '无妨']
    Column Age: [30, 25, 35]
    Column City: ['深圳', '上海', '北京']
    

openpyxl操作excel

openpyxl 是一个用于读写 Excel 文件(xlsx/xlsm/xltx/xltm 格式)的 Python 库。

安装openpyxl库

pip install openpyxl

1、基础使用

导入openpyxl库

import openpyxl

创建一个新的 Excel 工作簿

# 1、创建一个新的工作簿
wb = openpyxl.Workbook()

# 2、获取当前激活的工作表
ws = wb.active

# 3、给工作表命名
ws.title = "Sheet1"

# 4、保存工作簿
wb.save("excelPath/demo1.xlsx")

打开一个现有的 Excel 文件

# 打开一个已存在的工作簿
wb = openpyxl.load_workbook("excelPath/demo1.xlsx")

# 获取活跃的工作表
ws = wb.active

# 或者通过名称获取工作表
ws = wb["Sheet1"]

写入数据到工作表

# 写入单个单元格
ws['A1'] = "Hello"
ws['B1'] = "World"

# 写入多个单元格
data = [
    ["Name", "Age", "City"],
    ["雷神", 30, "稻妻"],
    ["申鹤", 25, "我家"],
    ["凝光", 35, "璃月"]
]

for row in data:
    ws.append(row)

# 保存工作簿
wb.save("excelPath/demo1.xlsx")

读取工作表中的数据

读取单个单元格

print(ws['A1'].value)

读取多个单元格

for row in ws.iter_rows(min_row=1, max_row=4, min_col=1, max_col=3):
    for cell in row:
        print(cell.value, end=" ")
    print()

读取所有数据

for row in ws.iter_rows(values_only=True):
    print(row)

操作行和列

插入行

ws.insert_rows(1)

删除行

ws.delete_rows(1)

插入列

ws.insert_cols(1)

删除列

ws.delete_cols(1)

合并和拆分单元格

这个用的比较少,我在工作中反正是没有用到过。

# 合并单元格
ws.merge_cells('A1:C1')
ws['A1'] = "Merged Cell"

# 拆分单元格
ws.unmerge_cells('A1:C1')

# 保存工作簿
wb.save("excelPath/demo1.xlsx")

样式的操作我们放到后面讲,并且我们开始一边写一边封装,这样以后需要使用就不用看教程,直接CV代码就可以啦。

2、按行写入Excel

按照我们基础使用的步骤走:

1、创建表

2、指定sheet页

3、写入数据

4、保存表

示列

def write_rows_to_excel(file_path, rows):
    """
    按行写入数据到Excel文件。
    :param file_path: (str)Excel文件路径
    :param rows :(list of list)要写入的行数据,每行是一个列表
    """
    # 创建一个新的工作簿
    wb = Workbook()
    ws = wb.active
    # 按行写入数据
    for row in rows:
        ws.append(row)
    # 保存工作簿
    wb.save(file_path)

直接封装成一个方法,后续可以直接调用。

if __name__ == '__main__':
    # 示例使用
    file_path = 'excelPath/demo2.xlsx'
    rows = [
        ['Name', 'Age', 'City'],
        ['无矶', 30, '黄山'],
        ['无妨', 25, '泰山'],
        ['无妨游志', 35, '华山']
    ]
    write_rows_to_excel(file_path, rows)
    print(f"文件已保存到 {file_path}")

3、按列写入Excel

一列一列写入excel里面,我们可以字典的格式写入,也可以使用列表的格式写入。

  • 字典格式:使用字典,键为列标,值为该列的数据列表。适合已知列标的情况。
  • 列表格式:使用嵌套列表,每个内部列表代表一列的数据。适合动态生成列标的情况。
# -*- coding: utf-8 -*-
"""
@Time : 2024/6/5 17:55
@Email : Lvan826199@163.com
@公众号 : 梦无矶的测试开发之路
@File : 03_按列写入Excel.py
"""
__author__ = "梦无矶小仔"

import openpyxl
from openpyxl.utils import get_column_letter


def write_data_by_column(data, filename):
    """
    将数据按列写入 Excel 文件。
    :param data: (dict): 包含列标和对应数据的字典,或者包含列数据的嵌套列表。
    :param filename: (str): 要保存的文件名。
    """
    # 创建一个新的工作簿
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "Sheet1"

    # 检查数据类型并写入数据
    if isinstance(data, dict):
        for col, values in data.items():
            for row, value in enumerate(values, start=1):
                ws[f'{col}{row}'] = value

    elif isinstance(data, list):
        for col_idx, col_data in enumerate(data, start=1):
            col_letter = get_column_letter(col_idx)
            for row_idx, value in enumerate(col_data, start=1):
                ws[f'{col_letter}{row_idx}'] = value
    else:
        raise ValueError("数据格式不正确,请提供字典或嵌套列表。")

    # 保存工作簿
    wb.save(filename)

使用示列

if __name__ == '__main__':
    data_dict = {
        'A': ["Name", "梦无矶", "小仔", "沐默"],
        'B': ["Age", 30, 25, 35],
        'C': ["City", "潮汕", "银川", "台北"]
    }

    data_list = [
        ["Name", "梦无矶", "小仔", "沐默"],
        ["Age", 30, 25, 35],
        ["City", "香港", "璃月", "阿尔及利亚"]
    ]

    # 使用字典数据写入
    write_data_by_column(data_dict, "excelPath/demo3_dict.xlsx")

    # 使用列表数据写入
    write_data_by_column(data_list, "excelPath/demo3_list.xlsx")

4、追加写入

假设你有一个已经存在的Excel文件demo1.xlsx(使用的是前面的excel),你想在其中追加一些新的行数据。

首先我们要理清楚步骤,再根据步骤一步步写代码:

1、加载现有excel

2、获取需要写入的sheet页

3、追加行数据

4、保存excel

# -*- coding: utf-8 -*-
"""
@Time : 2024/6/5 18:21
@Email : Lvan826199@163.com
@公众号 : 梦无矶的测试开发之路
@File : 04_追加写入.py
"""
__author__ = "梦无矶小仔"

from openpyxl import load_workbook


def append_rows_to_excel(file_path, rows, sheet_name=None):
    """
    追加行数据到现有的Excel文件。
    :param:file_path: (str): Excel文件路径
    :param:rows: (list of list): 要追加的行数据,每行是一个列表
    :param:sheet_name: (str): 要追加数据的表格名称,可选参数,默认为None,表示追加到当前活动表格
    """
    # 加载现有的工作簿
    wb = load_workbook(file_path)

    if sheet_name:
        # 检查工作表是否存在
        if sheet_name in wb.sheetnames:
            ws = wb[sheet_name]
        else:
            raise ValueError(f"工作表 '{sheet_name}' 不存在")
    else:
        # 获取活动工作表
        ws = wb.active

        # 追加行数据
    for row in rows:
        ws.append(row)

    # 保存工作簿
    wb.save(file_path)

示列使用

if __name__ == '__main__':
    file_path = 'excelPath/demo1.xlsx'
    rows = [
        ['申鹤', 40, '成都'],
        ['甘雨', 28, '哈尔滨']
    ]

    append_rows_to_excel(file_path, rows)

    print(f"数据已追加到 {file_path}")

假设demo1.xlsx文件最初包含以下数据:

NameAgeCity
雷神30稻妻
申鹤25我家
凝光35璃月

运行上述代码后,文件将被更新为:

NameAgeCity
雷神30稻妻
申鹤25我家
凝光35璃月
申鹤40成都
甘雨28哈尔滨

5、按行读取Excel

1、加载对应工作簿(表)

2、加载对应sheet页

3、遍历sheet[row]

from openpyxl import load_workbook

def read_row(file_path, sheet_name, row):
    wb = load_workbook(file_path)
    sheet = wb[sheet_name]

    row_values = []
    for cell in sheet[row]:
        row_values.append(cell.value)

    return row_values

示列:

if __name__ == '__main__':
    # 调用方法读取特定行的数据
    file_path = 'excelPath/demo1.xlsx'
    sheet_name = 'Sheet1'
    row_number = 3  # 假设要读取第3行
    row_data = read_row(file_path, sheet_name, row_number)
    print(row_data)

输出:

['雷神', 30, '稻妻']

6、按列读取Excel

1、加载对应工作簿(表)

2、加载对应sheet页

3、遍历sheet[column]

from openpyxl import load_workbook


def read_column(file_path, sheet_name, column):
    wb = load_workbook(file_path)
    sheet = wb[sheet_name]

    column_values = []
    for cell in sheet[column]:
        column_values.append(cell.value)

    return column_values

示列:

if __name__ == '__main__':
    # 调用方法读取特定列的数据
    file_path = 'excelPath/demo1.xlsx'
    sheet_name = 'Sheet1'
    column_letter = 'A'  # 假设要读取A列
    column_data = read_column(file_path, sheet_name, column_letter)
    print(column_data)

输出:

if __name__ == '__main__':
    # 调用方法读取特定列的数据
    file_path = 'excelPath/demo1.xlsx'
    sheet_name = 'Sheet1'
    column_letter = 'A'  # 假设要读取A列
    column_data = read_column(file_path, sheet_name, column_letter)
    print(column_data)

注意事项:

  • sheet[row]、sheet[column],这个参数是A、B、C就代表是列参数是数字就代表行,行是1开始。

7、认识sheet

我们直接wb = load_workbook(file_path),再sheet= wb[sheet_name],之后使用sheet的时候会发现不能自动点出属性,这里引入一个知识点,解决不自动联想属性。

解决方案:

1、我们可以直接print(sheet),发现是<Worksheet "Sheet1">,由此我们知道这个sheet是Worksheet实例

2、那么我们就可以引入这个实例(直接在代码里面写Worksheet,鼠标放上去会然你导入,直接点击就会自动导入对应的类)

3、并且给sheet声明是属于这个实例,之后我们使用sheet的时候就可以自动联想出它所有的属性了。

4、声明格式,属性:类型,sheet: Worksheet,效果如下代码。

在这里插入图片描述

遍历sheet的值

wb = load_workbook(file_path)
    sheet: Worksheet = wb[sheet_name]
    for i in sheet.values:
        print(i)

输出:

('Merged Cell', None, None)
('Name', 'Age', 'City')
('雷神', 30, '稻妻')
('申鹤', 25, '我家')
('凝光', 35, '璃月')
('申鹤', 40, '成都')
('甘雨', 28, '哈尔滨')

8、样式大全介绍

可以用来设置 Excel 单元格的字体、颜色、边框、对齐方式等。下面介绍一些常见的Excel样式操作,至于在工作中用不用得到,纯看你需不需要花里胡哨的表。

1. 设置字体(Font)

你可以设置字体的名称、大小、粗体、斜体、下划线等属性。

字体样式:

  • name: 字体名称,如 'Arial'
  • size: 字体大小,如 14
  • bold: 是否加粗,布尔值。
  • italic: 是否斜体,布尔值。
  • underline: 下划线样式,如 'single'
  • strike: 是否删除线,布尔值。
  • color: 字体颜色。
from openpyxl import Workbook
from openpyxl.styles import Font

wb = Workbook()
ws = wb.active

# 设置字体
font = Font(name='Arial', size=12, bold=True, italic=True, underline='single', color='FF0000')
ws['A1'].font = font
ws['A1'] = "Hello, World!"

wb.save("excelPath/demo08.xlsx")

效果展示:

在这里插入图片描述

2. 设置填充(Fill)

设置单元格的背景颜色。

填充模式:

  • 填充模式 (fill_type),如 solidpattern
from openpyxl import Workbook
from openpyxl.styles import PatternFill

wb = Workbook()
ws = wb.active
# 设置填充
fill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
ws['A2'].fill = fill
ws['A2'] = "Background Color"

wb.save("excelPath/demo08_2.xlsx")

在这里插入图片描述

在源码里面openpyxl->styles->fills.py里面有所有参数,想深入研究的可以看源码。

FILL_NONE = 'none'
FILL_SOLID = 'solid'
FILL_PATTERN_DARKDOWN = 'darkDown'
FILL_PATTERN_DARKGRAY = 'darkGray'
FILL_PATTERN_DARKGRID = 'darkGrid'
FILL_PATTERN_DARKHORIZONTAL = 'darkHorizontal'
FILL_PATTERN_DARKTRELLIS = 'darkTrellis'
FILL_PATTERN_DARKUP = 'darkUp'
FILL_PATTERN_DARKVERTICAL = 'darkVertical'
FILL_PATTERN_GRAY0625 = 'gray0625'
FILL_PATTERN_GRAY125 = 'gray125'
FILL_PATTERN_LIGHTDOWN = 'lightDown'
FILL_PATTERN_LIGHTGRAY = 'lightGray'
FILL_PATTERN_LIGHTGRID = 'lightGrid'
FILL_PATTERN_LIGHTHORIZONTAL = 'lightHorizontal'
FILL_PATTERN_LIGHTTRELLIS = 'lightTrellis'
FILL_PATTERN_LIGHTUP = 'lightUp'
FILL_PATTERN_LIGHTVERTICAL = 'lightVertical'
FILL_PATTERN_MEDIUMGRAY = 'mediumGray'

fills = (FILL_SOLID, FILL_PATTERN_DARKDOWN, FILL_PATTERN_DARKGRAY,
         FILL_PATTERN_DARKGRID, FILL_PATTERN_DARKHORIZONTAL, FILL_PATTERN_DARKTRELLIS,
         FILL_PATTERN_DARKUP, FILL_PATTERN_DARKVERTICAL, FILL_PATTERN_GRAY0625,
         FILL_PATTERN_GRAY125, FILL_PATTERN_LIGHTDOWN, FILL_PATTERN_LIGHTGRAY,
         FILL_PATTERN_LIGHTGRID, FILL_PATTERN_LIGHTHORIZONTAL,
         FILL_PATTERN_LIGHTTRELLIS, FILL_PATTERN_LIGHTUP, FILL_PATTERN_LIGHTVERTICAL,
         FILL_PATTERN_MEDIUMGRAY)

3. 设置边框(Border)

openpyxl 中,边框样式通过 BorderSide 类来定义。每个边框可以分别设置顶部、底部、左侧和右侧的样式和颜色。

Side 类

Side 类用于定义边框的样式和颜色。它的主要参数包括:

  • border_style: 边框的样式。常见的样式有:
    • "thin": 细边框
    • "medium": 中等宽度边框
    • "thick": 厚边框
    • "dashed": 虚线边框
    • "dotted": 点线边框
    • "double": 双线边框
    • "hair": 极细边框
    • "mediumDashed": 中等宽度虚线边框
    • "dashDot": 虚线点边框
    • "mediumDashDot": 中等宽度虚线点边框
    • "dashDotDot": 双点虚线边框
    • "mediumDashDotDot": 中等宽度双点虚线边框
    • "slantDashDot": 斜虚线点边框
  • color: 边框的颜色,使用 RGB 颜色代码表示,例如 "FF0000" 表示红色。
Border 类

Border 类用于组合各个边框(左、右、上、下、对角线)的 Side 实例。它的主要参数包括:

  • left: 左侧边框的 Side 实例。
  • right: 右侧边框的 Side 实例。
  • top: 顶部边框的 Side 实例。
  • bottom: 底部边框的 Side 实例。
  • diagonal: 对角线边框的 Side 实例。
  • diagonal_direction: 对角线方向,取值可以是 0(无对角线)、1(从左上到右下)、2(从右上到左下)。
边框代码示列
# -*- coding: utf-8 -*-
"""
@Time : 2024/6/6 18:56
@Email : Lvan826199@163.com
@公众号 : 梦无矶测开实录
@File : 08_样式大全_03设置边框.py
"""
__author__ = "梦无矶小仔"

from openpyxl import Workbook
from openpyxl.styles import Border, Side

# 创建一个新的工作簿和工作表
workbook = Workbook()
sheet = workbook.active

# 定义不同的边框样式
thin_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")
)

thick_border = Border(
    left=Side(border_style="thick", color="FF0000"),
    right=Side(border_style="thick", color="FF0000"),
    top=Side(border_style="thick", color="FF0000"),
    bottom=Side(border_style="thick", color="FF0000")
)

dashed_border = Border(
    left=Side(border_style="dashed", color="00FF00"),
    right=Side(border_style="dashed", color="00FF00"),
    top=Side(border_style="dashed", color="00FF00"),
    bottom=Side(border_style="dashed", color="00FF00")
)

double_border = Border(
    left=Side(border_style="double", color="0000FF"),
    right=Side(border_style="double", color="0000FF"),
    top=Side(border_style="double", color="0000FF"),
    bottom=Side(border_style="double", color="0000FF")
)

# 应用边框样式到不同的单元格
sheet["A1"].value = "Thin Border"
sheet["A1"].border = thin_border

sheet["B1"].value = "Thick Border"
sheet["B1"].border = thick_border

sheet["C1"].value = "Dashed Border"
sheet["C1"].border = dashed_border

sheet["D1"].value = "Double Border"
sheet["D1"].border = double_border

# 保存工作簿
workbook.save("excelPath/demo08_3.xlsx")
  1. 创建 Side实例:
    • Side(border_style=“thin”, color=“000000”): 创建一个细边框,颜色为黑色。
    • Side(border_style=“thick”, color=“FF0000”): 创建一个厚边框,颜色为红色。
    • Side(border_style=“dashed”, color=“00FF00”): 创建一个虚线边框,颜色为绿色。
    • Side(border_style=“double”, color=“0000FF”): 创建一个双线边框,颜色为蓝色。
  2. 创建 Border 实例:
    • Border(left=…, right=…, top=…, bottom=…): 将 Side 实例组合成一个 Border`实例,分别设置左、右、上、下四个边框。
  3. 应用边框样式到单元格:
    • sheet[“A1”].border = thin_border: 将细边框应用到单元格 A1
    • sheet[“B1”].border = thick_border: 将厚边框应用到单元格 B1
    • sheet[“C1”].border = dashed_border: 将虚线边框应用到单元格 C1
    • sheet[“D1”].border = double_border: 将双线边框应用到单元格 D1

效果如下:

在这里插入图片描述

4. 设置对齐方式(Alignment)

设置单元格的水平和垂直对齐方式。

对齐方式:

  • 缩进 (indent)
  • 换行 (wrap_text),在表格里面是自动换行,如果你代码写入的时候强制换行只需要使用\n即可。
    • wrap_text 设置为 True 时,单元格中的文本会根据单元格的宽度自动换行,以便在单元格中完全显示内容。

作用

# -*- coding: utf-8 -*-
"""
@Time : 2024/6/7 11:26
@Email : Lvan826199@163.com
@公众号 : 梦无矶测开实录
@File : 08_样式大全_04对齐方式.py
"""
__author__ = "梦无矶小仔"

from openpyxl import Workbook
from openpyxl.styles import Alignment

wb = Workbook()
ws = wb.active
# 设置对齐方式
alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
ws['A4'].alignment = alignment
ws['A4'] = "Centered Text\n我是第二行"

# 保存工作簿
wb.save("excelPath/demo08_4.xlsx")

效果如下:

在这里插入图片描述

5. 设置数字格式(Number Format)

可以设置单元格的数字格式,比如日期、货币等。

数字格式:

  • 格式化数字、日期、时间等 (number_format),如 'YYYY-MM-DD HH:MM:SS'
  1. 常规数字格式:
    • 整数:'0'
    • 小数:'0.00'
    • 千分位:'#,##0'
    • 百分比:'0%'
    • 科学计数法:'0.00E+00'
  2. 日期和时间格式:
    • 日期(年-月-日):'yyyy-mm-dd'
    • 日期(月/日/年):'mm/dd/yyyy'
    • 时间(小时:分钟:秒):'hh:mm:ss'
    • 日期和时间:'yyyy-mm-dd hh:mm:ss'
  3. 货币格式:
    • 美元:'$#,##0.00'
    • 欧元:'€#,##0.00'
    • 人民币:'¥#,##0.00'
__author__ = "梦无矶小仔"

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# 设置数字格式
ws['A5'].number_format = 'YYYY-MM-DD'
ws['A5'] = '2024-06-05'

wb.save("excelPath/demo08_5.xlsx")

6. 设置单元格保护(Protection)

你可以设置单元格是否锁定和隐藏。

__author__ = "梦无矶小仔"

from openpyxl import Workbook
from openpyxl.styles import Protection

wb = Workbook()
ws = wb.active
# 设置单元格保护
protection = Protection(locked=True, hidden=False)
ws['A6'].protection = protection
ws['A6'] = "Protected Cell"

wb.save("excelPath/demo08_6.xlsx")

7.设置列宽

设置A列宽20,B列宽10,C列宽30

__author__ = "梦无矶小仔"

from openpyxl import  load_workbook

column_widths = {'A': 20, 'B': 10, 'C': 30}  # 设置列宽

file_path = "excelPath/demo1.xlsx"
# 加载现有的工作簿
wb = load_workbook(file_path)
ws = wb.active
# 设置列宽
for col, width in column_widths.items():
    ws.column_dimensions[col].width = width
# 保存工作簿
wb.save(file_path)

8、设置行高

将第 1 行的高度设置为 30,第 2 行的高度设置为 50)

__author__ = "梦无矶小仔"

import openpyxl

# 打开 Excel 文件
workbook = openpyxl.load_workbook('excelPath/demo1.xlsx')

# 选择一个工作表
sheet = workbook.active

# 设置行高 (将第 1 行的高度设置为 30)
sheet.row_dimensions[1].height = 30
# 设置行高 (将第 2 行的高度设置为 50)
sheet.row_dimensions[2].height = 50

# 保存修改后的 Excel 文件
workbook.save('excelPath/demo1.xlsx')

9、样式组合使用封装

将上述样式组合使用来设置单元格的样式。

# -*- coding: utf-8 -*-
"""
@Time : 2024/6/7 11:46
@Email : Lvan826199@163.com
@公众号 : 梦无矶测开实录
@File : 09_样式组合使用封装.py
"""
__author__ = "梦无矶小仔"

import os
from copy import copy

import openpyxl
from openpyxl import Workbook
from openpyxl.worksheet.worksheet import Worksheet
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from typing import List, Optional


class ExcelWriter:
    def __init__(self, filename):
        self.filename: str = filename
        self.workbook: Workbook = Workbook()
        self.sheet: Worksheet = self.workbook.active

    def save(self):
        self.workbook.save(self.filename)

    def create_excel(self):
        # 新建一个空表格
        self.save()

    def create_excel_with_row(self, row_data: list, has_title=True, styles=None):
        """
        新建一个带有标题的表格,单行写入
        :param row_data:list[]
        :param has_title:
        :param styles:
        :return:
        """
        self.append_row(row_data, has_title=has_title, styles=styles)

    def create_excel_with_rows(self, rows_data: list, has_title=True, styles=None):
        """
        新建一个带有标题的表格,多行写入
        :param rows_data: list[[],[],[]...]
        :param has_title:
        :param styles:
        :return:
        """
        self.append_rows(rows_data, has_title=has_title, styles=styles)

    def verfiy_row_data(self, row_data: list, excel_title):
        """
        校验行数据长度
        :param row_data:
        :param excel_title:
        :return:
        """
        if len(row_data) != len(excel_title):
            raise ValueError(f"{row_data}写入行的数据长度必须和标题行长度一致!")

    def append_row(self, row_data: list, has_title: bool = False, styles=None):
        """
        写入或追加一行数据并设置样式
        :param row_data: list[]
        :param has_title: 是否带有标题
        :param styles:
        :return:
        """
        if has_title:
            for col_num, value in enumerate(row_data, 1):
                cell = self.sheet.cell(row=1, column=col_num, value=value)
                self.write_with_styles(1, col_num, cell, styles)
                self.save()
        else:
            row_num = self.sheet.max_row + 1
            for col_num, value in enumerate(row_data, 1):
                cell = self.sheet.cell(row=row_num, column=col_num, value=value)
                self.write_with_styles(row_num, col_num, cell, styles)
            self.save()

    def append_rows(self, rows_data: list, has_title: bool = False, styles=None):
        """
        写入或追加多行数据并设置样式
        :param row_data: list[[],[],[]...]
        :param has_title: 是否带有标题
        :param styles:
        :return:
        """

        if has_title and isinstance(rows_data[0], list):
            for col_num, value in enumerate(rows_data[0], 1):
                cell = self.sheet.cell(row=1, column=col_num, value=value)
                self.write_with_styles(1, col_num, cell, styles)
                self.save()
            for row_data in rows_data[1:]:
                row_num = self.sheet.max_row + 1
                for col_num, value in enumerate(row_data, 1):
                    cell = self.sheet.cell(row=row_num, column=col_num, value=value)
                    self.write_with_styles(row_num, col_num, cell, styles)
                self.save()
        else:
            for row_data in rows_data:
                row_num = self.sheet.max_row + 1
                for col_num, value in enumerate(row_data, 1):
                    cell = self.sheet.cell(row=row_num, column=col_num, value=value)
                    self.write_with_styles(row_num, col_num, cell, styles)
                self.save()

    def copy_excel_to_sheet(self, source_excel_path, sheet_name):
        """
        复制表数据不包含样式到指定sheet页
        :param source_excel_path:
        :param sheet_name:
        :return:
        """
        # 打开源文件和目标文件
        source_wb = openpyxl.load_workbook(source_excel_path)
        destination_wb = openpyxl.load_workbook(self.filename)

        # 获取源文件中的第一个 sheet
        source_sheet = source_wb.active

        # 在目标文件中创建一个新的 sheet
        new_sheet = destination_wb.create_sheet(title=sheet_name)

        # 遍历源 sheet 中的所有单元格,并将其值复制到新 sheet 中
        for row in source_sheet.iter_rows(values_only=True):
            new_sheet.append(row)

        # 保存目标文件
        destination_wb.save(self.filename)
        run_dir = os.getcwd()
        excel_path = os.path.join(run_dir, self.filename)
        print(f"生成结果表格路径:{excel_path}")

    def copy_excel_to_sheet_with_styles(self, source_excel_path, sheet_name):
        """
        复制表数据包含样式到指定sheet页
        :param source_excel_path:
        :param sheet_name:
        :return:
        """
        # 打开源文件和目标文件
        source_wb = openpyxl.load_workbook(source_excel_path)
        destination_wb = openpyxl.load_workbook(self.filename)

        # 获取源文件中的第一个 sheet
        source_sheet = source_wb.active

        # 在目标文件中创建一个新的 sheet
        new_sheet = destination_wb.create_sheet(title=sheet_name)

        # 复制单元格的值和样式
        for row in source_sheet.iter_rows():
            for cell in row:
                new_cell = new_sheet.cell(row=cell.row, column=cell.col_idx, value=cell.value)
                # 复制样式
                if cell.has_style:
                    new_cell.font = copy(cell.font)
                    new_cell.border = copy(cell.border)
                    new_cell.fill = copy(cell.fill)
                    new_cell.number_format = copy(cell.number_format)
                    new_cell.protection = copy(cell.protection)
                    new_cell.alignment = copy(cell.alignment)

        # 复制列宽
        for col in source_sheet.column_dimensions:
            new_sheet.column_dimensions[col].width = source_sheet.column_dimensions[col].width

        # 复制行高
        for row in source_sheet.row_dimensions:
            new_sheet.row_dimensions[row].height = source_sheet.row_dimensions[row].height

        # 保存目标文件
        destination_wb.save(self.filename)
        run_dir = os.getcwd()
        excel_path = os.path.join(run_dir, self.filename)
        print(f"生成结果表格路径:{excel_path}")

    def write_with_styles(self, row_num, col_num, cell, styles=None):
        """
        对行的指定列进行样式设置,不支持多行不同列样式设置
        :param row_num:
        :param col_num:
        :param cell:
        :param styles:
        :return:
        """
        # 设置默认样式
        cell.font = Font(color="000000")
        cell.fill = PatternFill(start_color="FFFFFF", end_color="FFFFFF", fill_type="solid")
        cell.alignment = Alignment(wrap_text=True, horizontal="center", vertical="center")
        cell.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")
        )

        # 如果提供了样式,则应用样式
        if styles and col_num in styles:
            print(f"styles:{row_num},{col_num},{cell}")
            style = styles[col_num]
            if 'font_color' in style:
                cell.font = Font(color=style['font_color'])
            if 'bg_color' in style:
                cell.fill = PatternFill(start_color=style['bg_color'], end_color=style['bg_color'], fill_type="solid")
            if 'alignment' in style:
                cell.alignment = Alignment(
                    wrap_text=style['alignment'].get('wrap_text', True),
                    horizontal=style['alignment'].get('horizontal', "center"),
                    vertical=style['alignment'].get('vertical', "center"),
                    indent=style['alignment'].get('indent', 0)
                )
            if 'width' in style:
                self.sheet.column_dimensions[cell.column_letter].width = style['width']
            if 'height' in style:
                self.sheet.row_dimensions[row_num].height = style['height']
            if 'border' in style:
                cell.border = Border(
                    left=Side(border_style=style['border'].get('left', 'thin'), color=style['border'].get('left_color', '000000')),
                    right=Side(border_style=style['border'].get('right', 'thin'), color=style['border'].get('right_color', '000000')),
                    top=Side(border_style=style['border'].get('top', 'thin'), color=style['border'].get('top_color', '000000')),
                    bottom=Side(border_style=style['border'].get('bottom', 'thin'), color=style['border'].get('bottom_color', '000000'))
                )
            if 'font' in style:
                cell.font = Font(
                    name=style['font'].get('name', 'Calibri'),
                    size=style['font'].get('size', 11),
                    bold=style['font'].get('bold', False),
                    italic=style['font'].get('italic', False),
                    underline=style['font'].get('underline', 'none'),
                    strike=style['font'].get('strike', False),
                    color=style['font'].get('color', '000000')
                )
            if 'number_format' in style:
                cell.number_format = style['number_format']


if __name__ == '__main__':
    # 示例使用
    row_data = [["姓名", "年龄", "性别", "职业", "城市", "语言"],
                ["张三", 25, "男", "工程师", "北京", "中文"],
                ["李四", 30, "女", "设计师", "上海", "英文"],
                ["王五", 35, "男", "教师", "广州", "粤语"],
                ["赵六", 40, "女", "医生", "深圳", "国语"],
                ["钱七", 45, "男", "律师", "杭州", "英语"], ["孙八", 50, "女", "护士", "南京", "国语"]]

    styles = {
        1: {
            'font_color': 'FF0000',
            'bg_color': 'FFFF00',
            'alignment': {'horizontal': 'left', 'vertical': 'top', 'wrap_text': True, 'indent': 1},
            'width': 20,
            'height': 30,
            'border': {'left': 'thick', 'left_color': 'FF0000'},
            'font': {'name': 'Arial', 'size': 14, 'bold': True, 'italic': True, 'underline': 'single', 'strike': True, 'color': 'FF0000'}
        },
        3: {
            'font_color': '0000FF',
            'bg_color': '00FF00',
            'alignment': {'horizontal': 'center', 'vertical': 'center', 'wrap_text': True},
            'width': 15,
            'border': {'bottom': 'dashed', 'bottom_color': '00FF00'}
        },
        5: {
            'font_color': '00FF00',
            'bg_color': 'FF00FF',
            'alignment': {'horizontal': 'right', 'vertical': 'bottom', 'wrap_text': True},
            'height': 25,
            'border': {'top': 'double', 'top_color': '0000FF'},
            'number_format': 'YYYY-MM-DD HH:MM:SS'
        }
    }
    # 多行写入
    excel_writer = ExcelWriter("excelPath/demo09_多行写入.xlsx")
    excel_writer.create_excel_with_rows(row_data, True, styles)

    # 单行写入
    row_data2 = ["姓名", "年龄", "性别", "职业", "城市", "语言"]
    excel_writer2 = ExcelWriter("excelPath/demo09_单行写入.xlsx")
    excel_writer2.create_excel_with_row(row_data2, True, styles)

效果展示:

在这里插入图片描述

10、复制他表数据到新的sheet页

已封装到第九小节中

    def copy_excel_to_sheet(self, source_excel_path, sheet_name):
        # 打开源文件和目标文件
        source_wb = openpyxl.load_workbook(source_excel_path)
        destination_wb = openpyxl.load_workbook(self.filename)

        # 获取源文件中的第一个 sheet
        source_sheet = source_wb.active

        # 在目标文件中创建一个新的 sheet
        new_sheet = destination_wb.create_sheet(title=sheet_name)

        # 遍历源 sheet 中的所有单元格,并将其值复制到新 sheet 中
        for row in source_sheet.iter_rows(values_only=True):
            new_sheet.append(row)

        # 保存目标文件
        destination_wb.save(self.filename)
        run_dir = os.getcwd()
        excel_path = os.path.join(run_dir, self.filename)
        print(f"生成结果表格路径:{excel_path}")

11、复制他表数据到新的sheet页-保留样式

已封装到第九小节中

 def copy_excel_to_sheet_with_styles(self, source_excel_path, sheet_name):
        """
        复制表数据包含样式到指定sheet页
        :param source_excel_path:
        :param sheet_name:
        :return:
        """
        # 打开源文件和目标文件
        source_wb = openpyxl.load_workbook(source_excel_path)
        destination_wb = openpyxl.load_workbook(self.filename)

        # 获取源文件中的第一个 sheet
        source_sheet = source_wb.active

        # 在目标文件中创建一个新的 sheet
        new_sheet = destination_wb.create_sheet(title=sheet_name)

        # 复制单元格的值和样式
        for row in source_sheet.iter_rows():
            for cell in row:
                new_cell = new_sheet.cell(row=cell.row, column=cell.col_idx, value=cell.value)
                # 复制样式
                if cell.has_style:
                    new_cell.font = copy(cell.font)
                    new_cell.border = copy(cell.border)
                    new_cell.fill = copy(cell.fill)
                    new_cell.number_format = copy(cell.number_format)
                    new_cell.protection = copy(cell.protection)
                    new_cell.alignment = copy(cell.alignment)

        # 复制列宽
        for col in source_sheet.column_dimensions:
            new_sheet.column_dimensions[col].width = source_sheet.column_dimensions[col].width

        # 复制行高
        for row in source_sheet.row_dimensions:
            new_sheet.row_dimensions[row].height = source_sheet.row_dimensions[row].height

        # 保存目标文件
        destination_wb.save(self.filename)
        run_dir = os.getcwd()
        excel_path = os.path.join(run_dir, self.filename)
        print(f"生成结果表格路径:{excel_path}")

好,基本就这些了,有啥新的需求或者想法欢迎留言 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/712111.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

盘点国内外免费AI视频工具,助你先人一步拥抱AI

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 6月13日&#xff0c;Luma AI 在 X 平台&#xff08;原 Twitter&#xff09;宣布其视频生成模型 Dream Machine 开放测试&#xff0c;并提供免费试用&#xff0c;这在海外 AI 圈掀起了一…

有哪些常用ORM框架

ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;是一种编程技术&#xff0c;它允许开发者使用面向对象的编程语言来操作关系型数据库。ORM的主要目的是将数据库中的数据表映射到编程语言中的对象&#xff0c;从而使得开发者可以使用对象的方式来…

Kotlin编程实践-【Java如何调用Kotlin中带默认值参数的函数】

问题 如果你有一个带有默认参数值的 Kotlin 函数&#xff0c;如何从 Java 调用它而无须为每个参数显式指定值&#xff1f; 方案 为函数添加注解JvmOverloads。 也就是为Java添加重载方法&#xff0c;这样Java调用Kotlin的方法时就不用传递全部的参数了。 示例 在 Kotlin …

【ARM-Linux篇】智能家居语音模块配置

1. pin脚配置&#xff1a; 2. 命令词自定义基本信息&#xff1a; 3. 命令词自定控制详情: • 测试&#xff1a;串口模块可先通过串口助手验证每个指令的准确性&#xff0c; 然后运行wiringOP中的serialTest程序(需把/dev/ttyS2改成/dev/ttyS5) 然后语音接收到指令后(比如喊你好…

【CTF Web】CTFShow 数据库恶意下载 Writeup(目录扫描+mdb文件泄露+Access脱库)

数据库恶意下载 10 mdb文件是早期aspaccess构架的数据库文件&#xff0c;文件泄露相当于数据库被脱裤了。 解法 用 dirsearch 扫描。 dirsearch -u 4b9b415f-4062-4bba-a6f5-3b107804043f.challenge.ctf.show找到一个 db 目录。 扫描 db 目录。 dirsearch -u 4b9b415f-4062-…

深入理解Java中的synchronized关键字

目录 前言 一、什么是synchronized 二、synchronized的底层实现 三、synchronized与其他同步机制的比较 四、synchronized的使用方式 1. synchronized的重入 2.synchronized的异常 前言 Java是一种面向对象的编程语言&#xff0c;以其强大的并发处理能力而闻名。在多线程…

mini web框架示例

web框架&#xff1a; 使用web框架专门负责处理用户的动态资源请求&#xff0c;这个web框架其实就是一个为web服务器提供服务的应用程序 什么是路由&#xff1f; 路由就是请求的url到处理函数的映射&#xff0c;也就是说提前把请求的URL和处理函数关联好 管理路由可以使用一个…

浅谈网络通信(3)

文章目录 一、TCP[!]1.1、TCP协议报文格式1.2、TCP十大机制1.2.1、确认应答机制1.2.2、超时重传机制1.2.3、连接管理机制1.2.3.1、三次握手[其流程至关重要&#xff0c;面试必考]1.2.3.2.1、那为啥要建立连接&#xff1f;&#xff1f;建立连接的意义是啥&#xff1f;&#xff1…

数据库管理-第204期 数据库的IO掉速,也许是SSD的锅(20240615)

数据库管理204期 2024-06-15 数据库管理-第204期 数据库的IO掉速&#xff0c;也许是SSD的锅&#xff08;20240615&#xff09;1 SSD物理结构2 SSD颗粒类型3 DRAM & SLC Cache3.1 DRAM3.2 SLC Cache3.3 其他方式 4 缓外降速总结 数据库管理-第204期 数据库的IO掉速&#xff…

System-Verilog 实现DE2-115流水灯

文章目录 一、 SystemVerilog1. SystemVerilog简介2. 基本语法和特性 二、实验过程hello.v文件引脚分配 三、实验效果参考 一、 SystemVerilog 1. SystemVerilog简介 SystemVerilog是一种高级的硬件描述语言&#xff08;HDL&#xff09;&#xff0c;它不仅继承了Verilog语言的…

Qt项目天气预报(2) - 重写事件函数

鼠标右键实现退出界面 知识点QMenu: QMenu 弹出对话框 --> 相对QMessageBox 更加轻量点 QMenu是Qt库中用于创建弹出式菜单的类&#xff0c;它通常出现在应用程序的顶部菜单栏、按钮的右键菜单或自定义上下文菜单中。以下是关于QMenu的详细介绍&#xff1a; 1. 类的基本特…

JUnit 5学习笔记

JUnit 5 学习笔记 1.JUnit5的改变2.JUnit5常用注解及测试2.1 DisplayName/Disabled/BeforeEach/AfterEach/BeforeAll/AfterAll2.2 Timeout2.3 RepeatedTest 3.断言3.1 简单断言3.2 数组断言3.3 组合断言3.4 异常断言3.5 超时断言3.6 快速失败 4.前置条件5.嵌套测试6.参数化测试…

《Fundamentals of Power Electronics》——理想变压器基本公式推导

接下去推导理想变压器的基本公式。理想变压器满足以下三个条件&#xff1a; 1、无铜损。假设原副边线圈均无纯电阻&#xff0c;则不会因在铜导线中产生焦耳热引起能量损耗&#xff0c;另外也不考虑回路中的分布电容。 2、无铁损。忽略通过铁芯的磁通量变化引起的涡流损耗&…

DistilBertModel模型的简单解释

前言 DistilBertModel((embeddings): Embeddings((word\_embeddings): Embedding(30522, 768, padding\_idx0)(position\_embeddings): Embedding(512, 768)(LayerNorm): LayerNorm((768,), eps1e-12, elementwise\_affineTrue)(dropout): Dropout(p\0.1, inplaceFalse))(trans…

解决方案︱视频孪生智慧高速解决方案

系统概述 在交通强国战略的指导下&#xff0c;我国政府高度重视以数字化为核心的智慧高速公路建设与发展。2023年9月&#xff0c;交通运输部印发了《交通运输部关于推进公路数字化转型加快智慧公路建设发展的意见》&#xff0c;强调到2035年&#xff0c;全面实现公路数字化转型…

【多线程】Thread类及其基本用法

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. Java中多线程编程1.1 操作系统线程与Java线程1.2 简单使用多线程1.2.1 初步创建新线程代码1.2.2 理解每个…

IDEA创建lib目录,导入jar

IDEA创建lib目录&#xff0c;导入jar lib第一种创建方法&#xff1a; 当发现项目没有lib目录时&#xff0c;File>>>Project Structure 打开Artifacts目录 lib第二种创建方法&#xff1a; 按需选择需要的jar包或者全选即可 lib第三种创建方法&#xff1a;

MongoDB使用$addToSet向数组中添加元素

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第66篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…

为什么白昼最长的地方不是在太阳的直射点

因为地球的自传轴相对于地球的公转平面成23.5度的夹角&#xff0c;地球自转一周是24小时&#xff0c;只有白天和黑夜两种状态。白天就可以定义为我们坐在地球上&#xff0c;跟着地球一直转&#xff0c;穿过有光照的地方所花的时间。 假设太阳光正对北回归线&#xff08;这一天…

2024.ZCPC.M题 计算三角形个数

题目描述&#xff1a; 小蔡有一张三角形的格子纸&#xff0c;上面有一个大三角形。这个边长为 的大三角形&#xff0c; 被分成 个边长为 1 的小三角形(如图一所示)。现在&#xff0c;小蔡选择了一条水平边 删除&#xff08;如图二所示&#xff09;&#xff0c;请你找出图上剩余…