近期有一个客户现场,需要他们自己的OA
、ERP
、PLM
三个系统的自动化流程设计,在这些系统的交互过程中会产生EXCEL
文件的编辑和处理,所以就涉及到了EXCEL
文件的自动化处理。
说是自动化处理,第一个想到的方法肯定是使用Pandas
库对数据进行一系列的编辑,但是不出意外就要出意外了,整个客户现场的环境都是加密的,系统下载的文件也全都是加密的,找客户的IT
咨询了一下,回复是无法进行解密,需要自己想办法…
那没得办法,只能尝试去使用EXCEL
软件去操作,但是,意外又发生了,当我使用EXCEL
打开加密的文件时,还真打开了,因为登入使用的测试账户具有访问文件的权限,但是意外在哪?意外在在我使用EXCEL
打开文件后的1min
内,电脑直接强制关机了,后续咨询了客户的IT
,说他们会有版权问题,只能使用WPS
打开文件…
那能怎么办,继续捣鼓…
查找了一些资料,发现WPS
是有COM
接口的。所谓COM
接口,COM(Component Object Model)
是Windows
系统的一种技术,用于不同程序之间的交互。WPS Office
提供了COM
接口,允许外部程序如Python
通过win32com.client
模块控制WPS
的功能。
这下算是看到了曙光,继续查找资料,找到了各个文件类型对应的COM
接口标识符。
EXCEL文件
对应ET.Application
WORD文件
对应Ket.Application
PPT文件
对应WPP.Application
于是乎开始尝试,首先下载Python
依赖
pip install pywin32
这里我以EXCEL
为例,我们先创建一个WPS
实例
import win32com.client
wps = win32com.client.Dispatch("ET.Application")
wps.Visible = True # 让wps实例在桌面可见
这样就创建好了一个实例,然后我们打开一个EXCEL
文件,接着上文的代码添加
# 将excel_path修改成目标文件路径
workbook = wps.Workbooks.Open(excel_path)
# 读取excel中的sheet,指定sheet工作簿
sheet = workbook.Sheets(sheet_name)
这样我们的工作表对象和工作簿对象就都创建好了,后续就可以开始增删改查了,这里我写了几个方法,用来快速的读、写EXCEL
文件
def read_wps_by_x_y(sheet, row_index, col_index):
"""
功能: 根据横、纵坐标读取EXCEL文件的值
sheet: 传入的工作簿对象
row_index: 要读取数据的横坐标
col_index: 要读取数据的纵坐标
返回值: 目标单元格的值
"""
return sheet.Cells(row_index,col_index).Value
def read_wps_by_line(workbook, sheet,start_row,end_row):
"""
功能: 读取EXCEL行
workbook: 工作表对象
sheet: 工作簿对象
start_row: 读取的第一行的索引
end_row: 读取的最后一行的索引
返回值: 读取的所有数据,二维数组
"""
data = []
# 按行读取数据
for row_index in range(start_row, end_row + 1):
row_data = []
col_index = 1
while sheet.Cells(row_index, col_index).Value is not None: # 读取每一列直到空单元格
row_data.append(sheet.Cells(row_index, col_index).Value)
col_index += 1
data.append(row_data)
return data
def write_wps_by_x_y(workbook,sheet, row_index, col_index, data):
"""
功能: 根据单元格坐标写入wps
workbook: 工作表对象
sheet: 工作簿对象
row_index: 要写入数据的横坐标
col_index: 要写入数据的纵坐标
data:写入值,置空表示清除单元格内容
"""
sheet.Cells(row_index, col_index).Value = data
workbook.Save()
def write_wps_by_line(workbook,sheet,data,start_row,start_col):
"""
功能: 写入一整行数据
workbook: 工作表对象
sheet: 工作簿对象
start_row: 开始写入行编号
start_col: 开始写入列标号
data: 要写入的数据,二维数组,表示多行,例如[[1,2,3],[4,5,6]]
"""
# 写入数据到表格
num_rows = len(data) # 数据的行数
print(f"读取到数据{num_rows}行")
num_cols = len(data[0]) # 数据的列数
sheet.Range(sheet.Cells(start_row, start_col), sheet.Cells(num_rows+start_row-1, num_cols)).Value = data
# 保存表格
workbook.Save()
def copy_sheet_to_excel_by_value(wps,workbook,sheet,save_path):
"""
功能: 将单独的sheet中的单元格都以值的格式保存到另一个excel文件
wps: wps实例
workbook: 工作表对象
sheet: 工作簿对象
save_path: 保存路径
"""
# 创建一个新的工作簿
new_workbook = wps.Workbooks.Add() # 新建工作簿
new_sheet = new_workbook.Sheets(1) # 获取新工作簿的第一个工作表
new_sheet.Name = sheet.Name
# 遍历原工作表的所有单元格,将公式转换为值
used_range = sheet.UsedRange # 获取工作表的已使用范围
for row in range(1, used_range.Rows.Count + 1): # 遍历行
for col in range(1, used_range.Columns.Count + 1):
cell = sheet.Cells(row, col)
# 复制值
new_sheet.Cells(row, col).Value = cell.Value
new_workbook.SaveAs(save_path)
new_workbook.Close()
def close_wps(wps, workbook):
"""
功能: 关闭WPS和工作表
wps: wps实例
workbook: 工作表对象
"""
# 关闭表格
workbook.Close()
wps.Quit()
这样就可以操作WPS
来读取EXCEL
表格了。
比如我要写入表格中的第1
行第1
列,写入123
,可以直接调用方法
write_wps_by_x_y(workbook,sheet,1,1,"123")
比如我要读取表格中的第1
行第1
列的值,也可以直接调用方法
read_wps_by_x_y(sheet,1,1)
比如我要写入一整行数据,写到第1
行,第1
列开始,数据为[1,2,3,4,5,6]
,可以直接调用方法
write_wps_by_line(workbook,sheet,[[1,2,3,4,5,6]],1,1)
但是还是建议使用Pandas
来操作EXCEL
文件,但是如果遇到上面的这种情况,这种方法也可以当作备选方法,也可以很好的去解决实际的需求问题。