python用openpyxl操作excel-单元格操作

python用openpyxl操作excel-单元格操作

python 复制代码
import logging
import com.pro001.log.pro_log_config as pro_log_config #参见另一篇博文
from openpyxl import Workbook, load_workbook
from openpyxl.styles import  Font, Alignment, Side, PatternFill, Border
import os
import datetime
import random
import pandas as pd


def create_sn(prefix, output_len=4):
    '''生成含有前缀并至少带指定长度格式的序列号,
    格式:prefix_d0{output_len}1'''
    if output_len < 1:
        output_len = 1
    sn = 0
    while True:
        sn += 1
        if len(str(sn)) > output_len:
            # 当大于指定位数时直接加上位数
            yield f'{prefix}' + str(sn)
        else:
            yield f'{prefix}' + '{:0{}}'.format(sn, output_len)


def excel_cell_operate(base_file_path):
    """ excel文件指定sheet指定单元格操作 """
    try:
        if not os.path.exists(base_file_path):
            os.makedirs(base_file_path)
            logger.error(f'已创建文件路径:{base_file_path}')
        dt_str = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
        file_path_name = 'F' + dt_str + '.xlsx'
        file_path_name = os.path.join(base_file_path, file_path_name)

        wb =  Workbook()
        # 1,获取第一个sheet对象,并设置为活动sheet
        ws = wb.worksheets[0]
        wb.active = ws

        # 2,单元格写入值
        # 2.1,根据坐标逐个单元格写入值,完成一行数据
        ws['A1'] = '报案号'
        ws['B1'] = '姓名'
        ws['C1'] = '年龄'
        ws['D1'] = '行号'

        # 2.2,根据行列方式逐个单元格写入值一行数据,循环可写入多行数据
        cno = create_sn('UCN02000', 4)
        for i in range(1,5):
            new_max_num = ws.max_row + 1
            ws.cell(row=new_max_num, column=1, value=f'{next(cno)}')
            ws.cell(row=new_max_num, column=2, value=f'姓名{random.randint(1,99):03d}')
            ws.cell(row=new_max_num, column=3, value=str(random.randint(1,99)))
            ws.cell(row=new_max_num, column=4, value=str(new_max_num))

        # 3,读取单元格数据
        # 3.1,根据坐标方式读取单元格数据
        row02_cel01 = ws['A2'].value
        # 3.2,根据行列方式读取单元格数据
        row02_cel02 = ws.cell(row=2, column=2).value
        row02_cel03 = ws.cell(row=2, column=3).value
        row02_cel04 = ws.cell(row=2, column=4).value
        logger.info(f'row02 data:{row02_cel01} - {row02_cel02} - {row02_cel03} - {row02_cel04}')
        # 3.3,遍历当前活动sheet的所有单元格
        max_cell_num = ws.max_column
        max_row_num = ws.max_row
        for row in ws.iter_rows(min_row=2, max_row=max_row_num, min_col=1, max_col=max_cell_num):
            print('row data:', end='')
            for cell in row:
                print(cell.value, end=' - ')
            print('')

        # 4,单元格合并操作
        # 4.1,当前活动sheet中根据坐标合并单元格
        ws.merge_cells('A7:D8')
        ws['A7'] = f'合并之后单元格的值{random.randint(10,100)}'
        # 4.2,根据行列范围合并单元格方式
        ws.merge_cells(start_row=9, start_column=1, end_row=10, end_column=5)
        ws.cell(row=9, column=1, value=f'合并之后单元格的值{random.randint(90,200)}')

        # 5,拆分单元格
        # 5.1,方式一为指定坐标拆分单元格
        #ws.unmerge_cells('A7:D8')
        # 5.2,方式二为指定行列范围单元格
        ws.unmerge_cells(start_row=9, start_column=1, end_row=10, end_column=5)

        # 6,行数据的插入和删除
        # 6.1,在当前活动sheet中某行(如11行)之前插入 1 行数据,
        ws.cell(row=11, column=1, value=f'{next(cno)}')
        ws.cell(row=11, column=2, value=f'姓名{random.randint(1, 20):03d}')
        ws.cell(row=11, column=3, value=str(random.randint(1, 99)))
        ws.cell(row=11, column=4, value=str(11))
        # 6.2,在当前活动sheet中某行(如11行)之后插入 5 行数据,
        # 实际是在 12 行之前插入,插入都是在目标行之前插入,只是改变下标就可看作是目标位的前或后

        for i in range(12, 17):
            ws.cell(row=i, column=1, value=f'{next(cno)}')
            ws.cell(row=i, column=2, value=f'姓名{random.randint(1, 20):03d}')
            ws.cell(row=i, column=3, value=str(random.randint(1, 99)))
            ws.cell(row=i, column=4, value=str(i))
            print(f'第{i}数据:{[cell.value for cell in ws[i]]}')

        # 6.3,删除某行数据,例如第 3 行数据
        print(f'第3行删除前数据:{[cell.value for cell in ws[3]]}')
        ws.delete_rows(idx=3)
        # 6.4,删除多行数据,例如第 12 开始,删除 2 行数据
        print(f'第12行删除前数据:{[cell.value for cell in ws[12]]}')
        print(f'第13行删除前数据:{[cell.value for cell in ws[13]]}')
        ws.delete_rows(idx=12, amount=2)

        # 7,列数据的插入和删除
        # 7.1,在当前活动sheet中某列(如第5列)之前插入 1 列数据,
        ws.insert_cols(idx=5)
        ws.cell(row=1, column=5, value=f'Cell05')
        col_letter = ws.cell(row=1, column=5).column_letter
        ws.column_dimensions[col_letter].width = 13 #设定列宽
        # 初始化第5列数据
        for row_idx in range(2, ws.max_row+1):
            ws.cell(row=row_idx, column=5, value=f'val{row_idx:02d}-05')
        # 7.2,在当前活动sheet中某列(如第5列)之后插入 6 列数据,
        for cel_idx in range(5, 11):
            ws.insert_cols(idx=cel_idx)
            ws.cell(row=1, column=cel_idx, value=f'Cell{cel_idx:02d}')
            col_letter = ws.cell(row=1, column=cel_idx).column_letter
            ws.column_dimensions[col_letter].width = 13 #设定列宽
        # 给新添加的第5-11列进行初始化值
        for row_idx in range(2, ws.max_row+1):
            for col_idx in range(5, 11):
                ws.cell(row=row_idx, column=col_idx, value=f'val{row_idx:02d}-{col_idx:02d}')
                col_letter = ws.cell(row=row_idx, column=cel_idx).column_letter
                ws.column_dimensions[col_letter].width = 13  # 设定列宽
        # 7.3,从第 7 列开始,删除后面 2 列,无 amount 参数则默认删除后面1列
        ws.delete_cols(idx=7, amount=2)

        # 保存wb对象
        wb.save(file_path_name)
        logger.info(f'文件{file_path_name}单元格操作成功!')
    except Exception as e:
        logger.error(f'生成Excel文件见:{file_path_name},单元格操作失败,info:\n{e}')


def main():
    """主函数"""
    base_dir = r'F:\appData\tempExcel'    
    excel_cell_operate(base_dir)    


if __name__ == '__main__':
    print('-' * 60)
    main()
相关推荐
ekprada2 小时前
Day 39 - 图像数据与显存
人工智能·python
森焱森2 小时前
当八字命理遇上软件开发:一张“流派架构图”+ 实战爬虫指南
驱动开发·爬虫·python·flask·pygame
商bol452 小时前
答案解析5
excel
我的xiaodoujiao2 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 33--基础知识 8--切换窗口句柄
python·学习·测试工具·pytest
dhdjjsjs2 小时前
Day37 PythonStudy
python
艾莉丝努力练剑2 小时前
【Python基础:语法第六课】Python文件操作安全指南:告别资源泄露与编码乱码
大数据·linux·运维·人工智能·python·安全·pycharm
ACERT3332 小时前
05-矩阵理论复习第五章 向量与矩阵范数
python·算法·矩阵
workflower9 小时前
时序数据获取事件
开发语言·人工智能·python·深度学习·机器学习·结对编程
C++业余爱好者10 小时前
Java 提供了8种基本数据类型及封装类型介绍
java·开发语言·python