Files
SOMEIP/code_generator/someip_app/read_excel.py

733 lines
29 KiB
Python
Raw Normal View History

2026-06-09 20:16:47 +08:00
# -*- coding: utf-8 -*-
"""
===============================================================
Python模块Python操作excel.xlsx封装类MyPyXlsToXlsxmyPyXwBook和myPyXwSheet
Date2022年02月07日
我的博客https://datutu.blog.csdn.net/
===============================================================
"""
import re
import xlwings as xw
from openpyxl.utils import get_column_letter
import os
import os.path
class MyPyXlsToXlsx:
"""
类功能: Python使用xlwings操作将xls文件转换为xlsx文件格式类
"""
def __init__(self, strOpenFilePath: str):
xlsFilePath = strOpenFilePath
# 文件存在就加载,不存在就创建工作簿。
if os.path.exists(xlsFilePath):
# 文件存在就加载,加载失败就报错。
try:
app = xw.App(visible=False, add_book=False)
app.display_alerts = False # 关闭一些提示信息,可以加快运行速度。 默认为 True。
app.screen_updating = False # 更新显示工作表的内容。默认为 True。关闭它也可以提升运行速度。
workbook = app.books.open(xlsFilePath) # 打开现有excel
workbook.api.SaveAs(xlsFilePath + "x", FileFormat=51) # 参数 51 为xlsx格式56为 Excel 97-2003的xls版本
app.kill() # 使用kill()关闭进程
os.remove(xlsFilePath) # 删除老的xls文件
except IOError:
print("加载xls文件失败请检查")
else:
print("已成功将xls文件转换为xlsx文件!!!\n")
else:
print("加载的xls文件不存在请检查")
class myPyXwBook:
"""
类功能: Python使用xlwings操作excel.xlsx封装类myPyXwBook
"""
def __init__(self, strOpenFilePath: str):
"""
:function: 初始化
:param strOpenFilePath: 打开的文件绝对路径
"""
self.strFilePath = strOpenFilePath
self.app = None
# 工作簿对象
self.workbook = None
# 文件存在就加载,不存在就创建工作簿。
if os.path.exists(self.strFilePath):
# 文件存在就加载,加载失败就报错。
try:
self.app = xw.App(visible=False, add_book=False)
self.app.display_alerts = False # 关闭一些提示信息,可以加快运行速度。 默认为 True。
self.app.screen_updating = False # 更新显示工作表的内容。默认为 True。关闭它也可以提升运行速度。
self.workbook = self.app.books.open(self.strFilePath)
except IOError:
print("加载excel文件失败请检查")
else:
print("已成功加载excel文件.xlsx文件!!!\n")
else:
print("加载excel文件不存在自动创建文件")
self.app = xw.App(visible=False, add_book=False)
self.app.display_alerts = False # 关闭一些提示信息,可以加快运行速度。 默认为 True。
self.app.screen_updating = False # 更新显示工作表的内容。默认为 True。关闭它也可以提升运行速度。
self.workbook = self.app.books.add() # 创建工作簿
def openWorkSheet(self, strSheetName: str):
"""
:function: 打开工作表功能
:param strSheetName: 要打开的工作表名称
:return: 返回打开的工作表Worksheet对象
"""
worksheet = None # 工作表对象
listSheetNames = []
for i in range(0, len(self.workbook.sheets)):
listSheetNames.append(self.workbook.sheets[i].name)
if strSheetName in listSheetNames:
worksheet = self.workbook.sheets[strSheetName]
else:
print("表单名称在当前excel文件中不存在请检查表单名称")
return worksheet
def addSheet(self, strSheetName: str):
"""
:function: 新建或添加工作表
:param strSheetName: 工作表名称
"""
self.workbook.sheets.add(strSheetName)
def deleteSheet(self, strSheetName: str):
"""
:function: 删除工作表
:param strSheetName: 工作表名称
"""
if strSheetName in self.getAllSheetNames():
self.workbook.sheets[strSheetName].delete()
else:
print("表单名称在当前excel文件中不存在请检查表单名称")
def getAllSheetNames(self):
"""
:function: 获取一个工作簿所有工作表名称
"""
listSheetNames = []
for i in range(0, len(self.workbook.sheets)):
listSheetNames.append(self.workbook.sheets[i].name)
return listSheetNames
def getActiveSheet(self):
"""
:function: 获取当前活跃的sheet
"""
return self.workbook.sheets.active
def saveWorkBookData(self):
"""
:function: 保存工作簿数据
"""
self.workbook.save(self.strFilePath)
def saveAsWorkBookData(self, strNewFilePath: str):
"""
:function: 另存为工作簿数据
:param strNewFilePath: 新的工作簿名称
"""
self.workbook.save(strNewFilePath)
def closeWorkBook(self):
"""
:function: 关闭工作簿
"""
# 关闭此工作簿
self.workbook.close()
# 关闭app
self.app.quit()
class myPyXwSheet:
"""
类功能: Python使用xlwings操作excel.xlsx工作表封装类myPyXwSheet
"""
def __init__(self, worksheet):
# 工作表对象
self.worksheet = worksheet
def insertRows(self, strRowsRange):
"""
:function: 在strRowRange范围上方插入多行或一行
:param strRowsRange:
在第3行上方插入1行'3'
在第3行和第4行上方插入2行'3:4'
"""
self.worksheet.api.Rows(strRowsRange).Insert()
def deleteRows(self, strCellsRange: str):
"""
:function: 删除多行或一行
:param strCellsRange:
删除第4行和第5行'4:5'
删除第4行'4'
"""
self.worksheet.range(strCellsRange).api.EntireRow.Delete()
def insertCols(self, strColsRange: str):
"""
:function: 在strColsRange范围处左侧插入多列或一列
:param strColsRange:
在第C列处插入1列'C'
在第C列和第D列处插入2列'C:D'
"""
self.worksheet.api.Columns(strColsRange).Insert()
def deleteCols(self, strColsRange):
"""
:function: 删除多列或一列
:param strColsRange: 单元格范围'C:D''C'
"""
self.worksheet.range(strColsRange).api.EntireColumn.Delete()
def getSheetName(self):
"""
:function: 获取工作表名称
"""
return self.worksheet.name
def getMaxRows(self):
"""
:function: 获取工作表最大行数
"""
return self.worksheet.used_range.last_cell.row
def getUsedRangeData(self):
"""
:function: 获取工作表已使用区域的全部数据
:备注返回的是二维列表,[[1,2],[3,6]
"""
return self.worksheet.used_range.value
def getMaxColumns(self):
"""
:function: 获取工作表最大列数
"""
return self.worksheet.used_range.last_cell.column
def renameSheet(self, strNewSheetName: str):
"""
:function: 重命名工作表
:param strNewSheetName: 新的工作表名称
"""
self.worksheet.name = strNewSheetName
def clearSheetContentsAndFormat(self):
"""
:function: 清空表中所有内容和格式
"""
self.worksheet.clear()
def clearSheetContents(self):
"""
:function: 清除工作表的内容但保留格式
"""
self.worksheet.clear_contents()
def setCellFormula(self, strCellRange: str, strFormat: str):
"""
:function: 设置单元格公式
:param strCellRange: 单元格范围C6
:param strFormat: 单元格数字格式'=SUM(B6:B7)'
"""
self.worksheet[strCellRange].formula = strFormat
def getCellFormula(self, strCellRange: str):
"""
:function: 获取单元格公式
:param strCellRange: 单元格范围C6
"""
return self.worksheet[strCellRange].formula_array
def setCellNumberFormat(self, strCellRange: str, strNumberFormat: str):
"""
:function: 设置单元格数字格式
:param strCellRange: 单元格范围C6
:param strNumberFormat: 单元格数字格式'""#,##0.00;-""#,##0.00'
或人民币大写'[DBNum2][$RMB]G/通用格式;[红色][DBNum2][$RMB]G/通用格式'
"""
self.worksheet[strCellRange].number_format = strNumberFormat
def setRowHeight(self, nRowIndex: int, valRowHeight):
"""
:function: 设置行高
:param nRowIndex: 行号取值1,2...整数
:param valRowHeight: 行高度值0~409之间的整数或浮点数
:return: 设置成功返回True否则反
"""
# 类型检测
if type(nRowIndex) is not int:
print("nRowNumber 数据类型错误!请确认为整数类型")
return False
if type(valRowHeight) is not int and type(valRowHeight) is not float:
print("cur_num 数据类型错误!请确认为整数类型,或者为浮点数类型!")
return False
# 数字是否出范围
if 0 <= valRowHeight <= 409:
self.worksheet.range('A' + str(nRowIndex)).row_height = valRowHeight
return True
else:
print("行高度值,超出了目前最大行高度!")
return False
def setColumnWidth(self, strColumnIndex: str, valColumnWidth):
"""
:function: 设置列宽
:param strColumnIndex: 列索引取值整数1,2...或者'A','B'...
:param valColumnWidth: 列宽度值0~255之间的整数或浮点数
:return: 设置成功返回True否则反
"""
# 数字检测
if type(strColumnIndex) is int:
try:
strColumnIndex = get_column_letter(strColumnIndex) # 列号转列字母
except ValueError:
print("ColumnIndex参数非法请确认是输入数据为列索引字符串")
return False
if type(valColumnWidth) is not int and type(valColumnWidth) is not float:
print("valColumnWidth 数据类型错误!请确认为整数类型,或者为浮点数类型!")
return False
# 数字是否出范围
if 0 <= valColumnWidth <= 255:
self.worksheet.range(strColumnIndex + '1').column_width = valColumnWidth
return True
else:
print("列宽度值,超出了目前最大列宽度!")
return False
def setRowsHeight(self, strCellsRange: str, valRowHeight):
"""
:function: 设置多行行高
:param strCellsRange: 单元格'A2:D5''A2'
:param valRowHeight: 行高度值0~409之间的整数或浮点数
:return: 设置成功返回True否则反
"""
if type(valRowHeight) is not int and type(valRowHeight) is not float:
print("cur_num 数据类型错误!请确认为整数类型,或者为浮点数类型!")
return False
# 数字是否出范围
if 0 <= valRowHeight <= 409:
self.worksheet.range(strCellsRange).row_height = valRowHeight
return True
else:
print("行高度值,超出了目前最大行高度!")
return False
def setColumnsWidth(self, strCellsRange: str, valColumnWidth):
"""
:function: 设置多列列宽
:param strCellsRange: 单元格'A2:D5''A2'
:param valColumnWidth: 列宽度值0~255之间的整数或浮点数
:return: 设置成功返回True否则反
"""
if type(valColumnWidth) is not int and type(valColumnWidth) is not float:
print("valColumnWidth 数据类型错误!请确认为整数类型,或者为浮点数类型!")
return False
# 数字是否出范围
if 0 <= valColumnWidth <= 255:
self.worksheet.range(strCellsRange).column_width = valColumnWidth
return True
else:
print("列宽度值,超出了目前最大列宽度!")
return False
def getCellRowIndex(self, strCellRange: str):
"""
:function: 获取单元格的行标
:param strCellRange: 单元格'A2'
:return: 返回单元格的行标
"""
return self.worksheet.range(strCellRange).row
def getCellColIndex(self, strCellRange: str):
"""
:function: 获取单元格的列标
:param strCellRange: 单元格'A2'
:return: 返回单元格的列标
"""
return self.worksheet.range(strCellRange).column
def putDataByCell(self, strCellRange: str, Value):
"""
:function: 写入一个单元格数据功能
:param strCellRange: 单元格'A2'
:param Value: 写入指定单元格的数值
"""
self.worksheet.range(strCellRange).value = Value
def getDataByCell(self, strCellRange: str):
"""
:function: 读取一个单元格数据功能
:param strCellRange: 单元格'A2'
:备注返回的数值默认是浮点数
"""
return self.worksheet.range(strCellRange).value
def putDataByRowOrCol(self, strCellsRange: str, listData: list):
"""
:function:写入一行或一列数据
:param strCellsRange: 单元格范围一行'A2:D2'或一列'A2:A4'或单元格'A2'
:param listData: 一维数据列表[]
"""
index = 0
for row in self.worksheet[strCellsRange]:
for cell in row:
if index >= len(listData):
print("一维列表下表超出范围!")
else:
cell.value = listData[index]
index += 1
def getDataByRowOrCol(self, strCellsRange: str) -> list:
"""
:function:读取一行或一列数据
:param strCellsRange: 单元格范围一行'A2:D2'或一列'A2:A4'或单元格'A2'
:return:一维列表[]返回的数值默认是浮点数
"""
return self.worksheet.range(strCellsRange).value
def putDataByRow(self, strCellRange: str, listData: list):
"""
:function:以第一个单元格为起点写入一行数据
:param strCellRange: 单元格'A2'
:param listData: 一维数据列表[]
:备注
# 将列表[1,2,3]储存在A1C1中
self.worksheet.range('A1').value=[1,2,3]
# 等同于
self.worksheet.range('A1:C1').value = [1,2,3]
"""
self.worksheet.range(strCellRange).value = listData
def putDataByCol(self, strCellRange: str, listData: list):
"""
:function:以第一个单元格为起点写入一列数据
:param strCellRange: 单元格'A2'
:param listData: 一维数据列表[]
:备注
# 将列表[1,2,3]储存在A1:A3中
self.worksheet.range('A1').options(transpose=True).value=[1,2,3]
"""
self.worksheet.range(strCellRange).options(transpose=True).value = listData
def putDataByRows(self, strCellsRange: str, listData: list):
"""
:function:以第一个单元格为起点多行输入就要用二维列表
:param strCellsRange: 单元格'A2'
:param listData: 二维数据列表[[1,2],[3,4]]
:备注
# 将2x2表格即二维数组储存在A1:B2中如第一行12第二行34
self.worksheet.range('A1').options(expand='table').value=[[1,2],[3,4]]
"""
self.worksheet.range(strCellsRange).options(expand='table').value = listData
def getDataByRows(self, strCellsRange: str) -> list:
"""
:function:读取多行数据就要用二维列表
:param strCellsRange: 单元格范围'A2:C6'
:return listData: 二维数据列表[[1,2],[3,4]]
:备注返回的数值默认是浮点数
"""
return self.worksheet.range(strCellsRange).value
def getCellRowHeight(self, nRowIndex: int):
"""
:function:获取单元格行高度
:param nRowIndex: 1, 2, 3,...
:return: 返回单元格行高度
"""
return self.worksheet.range('A' + str(nRowIndex)).row_height
def getCellColWidth(self, strColumnIndex: str):
"""
:function:获取单元格列宽度
:param strColumnIndex: 'A','B',...
:return: 返回单元格列宽度
"""
fColWidth = self.worksheet.range(strColumnIndex + '1').column_width
# 浮点数保留2位小数
fNewColWidth = round(fColWidth, 2)
return fNewColWidth
def setRowsAutofit(self, strCellsRange: str):
"""
:function:单元格范围的所有行宽度自适应
:param strCellsRange: 单元格范围'A2:C6'
"""
# 所有行宽度自适应
self.worksheet.range(strCellsRange).rows.autofit()
def setColAutofit(self, strCellsRange: str):
"""
:function:单元格范围的所有列宽度自适应
:param strCellsRange: 单元格范围'A2:C6'
"""
# 所有行宽度自适应
self.worksheet.range(strCellsRange).columns.autofit()
def setAutofit(self, strCellsRange: str):
"""
:function:单元格范围的所有行和列的宽度自适应
:param strCellsRange: 单元格范围'A2:C6'
"""
# 所有行宽度自适应
self.worksheet.range(strCellsRange).autofit()
def getRangeRowsCount(self, strCellsRange: str):
"""
:function:获取单元格范围range的总行数
:param strCellsRange: 单元格范围'A2:C6'
:return : 单元格范围range的总行数
"""
return self.worksheet.range(strCellsRange).rows.count
def getRangeColsCount(self, strCellsRange: str):
"""
:function:获取单元格范围range的总列数
:param strCellsRange: 单元格范围'A2:C6'
:return : 单元格范围range的总列数
"""
return self.worksheet.range(strCellsRange).columns.count
def getRangeRows(self, strCellsRange: str) -> list:
"""
:function:获取单元格范围range的行对象列表
:param strCellsRange: 单元格范围'A2:C6'
:return : 单元格范围range的行对象列表
"""
# 返回第一行数据列表
# return self.worksheet.range(strCellsRange).rows[0].value
# 返回单元格范围range的行对象列表
return self.worksheet.range(strCellsRange).rows
def copyRange(self, strSourceCellsRange: str):
"""
:function:同一个工作表或不同工作表把一个区域拷贝到剪贴板
:param strSourceCellsRange: 源单元格范围'A1:B3'
"""
# 参数destination 设置目标区域如果省略rng区域会被拷贝到剪贴板上
self.worksheet.range(strSourceCellsRange).copy(destination=None)
def pasteRange(self, strDestCellsRange: str, paste=None, operation=None, skip_blanks=False, transpose=False):
"""
:function:同一个工作表或不同工作表把剪贴板拷贝到目的区域
:param strDestCellsRange: 目的单元格范围'D5''D5:E7'
:param paste:
参数
paste
all_merging_conditional_formats将粘贴所有内容并且将合并条件格式
all粘贴全部内容
all_except_borders粘贴除边框外的全部内容
all_using_source_theme使用源主题粘贴全部内容
column_widths粘贴复制的列宽
comments粘贴批注
formats粘贴复制的源格式
formulas粘贴公式
formulas_and_number_formats粘贴公式和数字格式
validation粘贴有效性
values粘贴值
values_and_number_formats粘贴值和数字格式
:param operation:
参数
operation
add
divide
multiply
subtract
:param skip_blanks:
参数
skip_blanks
(bool, default False)设为 True 时忽略空白单元格
:param transpose:
参数
transpose
(bool, default False)设为 True 时对行列转置
"""
# 将剪贴板里内容粘贴到指定区域
self.worksheet.range(strDestCellsRange).paste(paste=paste, operation=operation,
skip_blanks=skip_blanks, transpose=transpose)
def copyPasteRange(self, strSourceCellsRange: str, strDestCellsRange: str):
"""
:function:同一个工作表内把一个区域复制粘贴到目的区域
:param strSourceCellsRange: 源单元格范围'A1:B3'
:param strDestCellsRange: 目的单元格范围'D5''D5:E7'
"""
'''同个表格复制、粘贴'''
# 复制 A1 到 B3 之间单元格的值,粘贴到'D5'中
self.worksheet.range(strSourceCellsRange).api.Copy(self.worksheet.range(strDestCellsRange).api)
def setCellMerge(self, strCellsRange: str):
"""
:function: 合并单元格
:param strCellsRange: 单元格范围'A1:D1'
"""
self.worksheet.range(strCellsRange).merge(across=False)
def setCellUnMerge(self, strCellsRange: str):
"""
:function: 拆分单元格
:param strCellsRange: 单元格范围'A1:D1'
"""
self.worksheet.range(strCellsRange).unmerge()
def setFontStyleByCells(self, strCellsRange: str, name="宋体", size=11,
bold=False, italic=False, color=1):
"""
:function:设置一个或多个单元格的字体样式风格
配置字体格式为样式宋体尺寸11粗体flase斜体flase颜色黑色
这里可以根据自己需求修改
:param strCellsRange: 单元格范围'A29:F39'或单元格'A2'
:param name: 字体名称
:param size: 字体大小点数
:param bold: True表示粗体
:param italic: True表示斜体
:param color: 字体颜色
===字体颜色索引===
无色 = -4142,自动 = -4105,黑色 = 1,
白色 = 2 红色 = 3,鲜绿 = 4,
蓝色 = 5 ,黄色 = 6,粉红 = 7,
青绿 = 8 ,深红 = 9,绿色 = 10,
深蓝 = 11,深黄 = 12 ,紫罗兰 = 13,
青色 = 14,灰色25 = 15,褐色 = 53,
橄榄 = 52,深绿 = 51,深青 = 49,
靛蓝 = 55,灰色80 = 56,橙色 = 46,
蓝灰 = 47,灰色50 = 16,浅橙色 = 45,
酸橙色 = 43,海绿 = 50, 水绿色 = 42,
浅蓝 = 41, 灰色40 = 48,金色 = 44,
天蓝 = 33,梅红 = 54,玫瑰红 = 38,
茶色 = 40,浅黄 = 36,浅绿 = 35,
浅青绿 = 34,淡蓝 = 37,淡紫 = 39,
"""
cellRange = self.worksheet.range(strCellsRange)
cellRange.api.Font.Name = name # 设置字体名称
cellRange.api.Font.Size = size # 设置字体大小
cellRange.api.Font.Bold = bold # 设置字体是否加粗
cellRange.api.Font.Italic = italic # 设置字体是否斜体
cellRange.api.Font.ColorIndex = color # 设置字体颜色
@staticmethod
def strHorizontalAlignment_to_int(strHorizontalAlignment: str):
"""
:function:水平对齐方式字符串转int
:param strHorizontalAlignment: 水平对齐方式字符串'left''center''right'
"""
numbers = {
'left': -4131,
'center': -4108,
'right': -4152
}
return numbers.get(strHorizontalAlignment, None)
@staticmethod
def strVerticalAlignment_to_int(strVerticalAlignment: str):
"""
:function:垂直对齐方式字符串转int
:param strVerticalAlignment: 垂直对齐方式字符串'top''center''bottom''wordwrap'
"""
numbers = {
'top': -4160,
'center': -4108,
'bottom': -4107,
'wordwrap': -4130
}
return numbers.get(strVerticalAlignment, None)
def setAlignmentStyleByCells(self, strCellsRange: str, horizontal='center', vertical='center'):
"""
:function:设置一个或多个单元格的对齐方式
:param strCellsRange: 单元格范围'A29:F39'或单元格'A2'
:param horizontal: 水平对齐方式'left''center''right'
:param vertical: 垂直对齐方式'top''center''bottom''wordwrap'
"""
cellRange = self.worksheet.range(strCellsRange)
# -4108 水平居中。 -4131 靠左,-4152 靠右。
cellRange.api.HorizontalAlignment = self.strHorizontalAlignment_to_int(horizontal)
# -4108 垂直居中(默认)。 -4160 靠上,-4107 靠下, -4130 自动换行对齐。
cellRange.api.VerticalAlignment = self.strVerticalAlignment_to_int(vertical)
def setBorderStyleByCell(self, strCellsRange: str, nBorderLineStyle: int = 1, nBorderWeight: int = 2):
"""
:function:设置一个或多个单元格的边框样式
:param strCellsRange: 单元格范围'A29:F39'或单元格'A2'
:param nBorderLineStyle: 边框线型直线1虚线2点划线4双点划线5
:param nBorderWeight: 边框粗细默认值2
"""
cellRange = self.worksheet.range(strCellsRange)
# Borders(7) 左边框
cellRange.api.Borders(7).LineStyle = nBorderLineStyle # 设置边框线型
cellRange.api.Borders(7).Weight = nBorderWeight # 设置边框粗细。
# Borders(8) 顶部框
cellRange.api.Borders(8).LineStyle = nBorderLineStyle
cellRange.api.Borders(8).Weight = nBorderWeight
# Borders(9) 底部边框
cellRange.api.Borders(9).LineStyle = nBorderLineStyle
cellRange.api.Borders(9).Weight = nBorderWeight
# Borders(10) 右边框
cellRange.api.Borders(10).LineStyle = nBorderLineStyle
cellRange.api.Borders(10).Weight = nBorderWeight
"""如果是一个区域的单元格,内部边框设置如下"""
# Borders(11) 内部垂直边线
cellRange.api.Borders(11).LineStyle = nBorderLineStyle
cellRange.api.Borders(11).Weight = nBorderWeight
# Borders(12) 内部水平边线
cellRange.api.Borders(12).LineStyle = nBorderLineStyle
cellRange.api.Borders(12).Weight = nBorderWeight
"""
===============================================================
主函数
===============================================================
"""
if __name__ == '__main__':
# excel文件绝对路径
xlsxFilePath = os.path.join(os.getcwd() + "\\" + "someip.xlsx")
# 创建工作簿对象
myXwBook = myPyXwBook(xlsxFilePath)
# 创建工作表对象
myXwSheet1 = myPyXwSheet(myXwBook.openWorkSheet("ServiceInterfaces"))
# 写入数据
# myXwSheet1.putDataByRowOrCol('A1:A4', [1, 2, 3, 4])
# 读数据
readData = myXwSheet1.getDataByCell('A2:C2')
print(readData)
# 保存工作簿数据
myXwBook.saveWorkBookData()
# 关闭工作簿
myXwBook.closeWorkBook()