官方文档:
利用本文代码可以实现读写.xlsx、.xls及.csv文件,单元格格式的简单设置,文件的另存为等。
1、pywin32库的安装
如已安装Anaconda,在 Anaconda Prompt 中键入 pip install pywin32 便可自动完成该库的导入;如未安装 Anaconda,也可 pip 手动导入,其在PyPI(Python Package Index)上的注册地址为: https://pypi.org/project/pywin32 。
2、版本说明
pywin32: 224
Excel: 2016
3、COM
COM(Component Object Model,组件对象模型)是微软公司于1993年提出的一种组件技术,它是一种平台无关、语言中立、位置透明、支持网络的中间件技术。
组件对象模型,一种面向对象的编程模式。它定义了对象在单个应用程序内部或多个应用程序之间的行为方式。它是微软对于网页服务器与客户端、增益集与Office系列软件之间交互的一项软件组件技术。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Author = Hulunbuir & DalaiNur
Email: [email protected]
Last Update: 2019.09.09 18:47
=============================
"""
import win32com.client
import os
class Excel:
def __init__(self, file_abs_path=None, create_if_not_exists=False,
visible=False, display_alerts=False):
"""初始化数据
:param file_abs_path: 文件的绝对路径
:param create_if_not_exists: 文件不存在则不新建(默认)
:param visible: Excel程序不可见(默认)
:param display_alerts: 不显示警告信息(默认)
"""
self._visible = visible
self._display_alerts = display_alerts
self._xlApp = win32com.client.Dispatch("Excel.Application")
self._xlApp.DisplayAlerts = self._display_alerts # 关闭警告(默认)
self._xlApp.Visible = self._visible # Excel对象不可见(默认)
self.file_abs_path = file_abs_path # 文件的绝对路径
self._create_if_not_exists = create_if_not_exists # 文件不存在是否新建选项
self._xlBook = None
try:
# 打开文件
self._xlBook = self._xlApp.Workbooks.Open(self.file_abs_path)
print(f"""文件【{self.file_abs_path}】已打开!""")
except:
# 文件打开失败后判断是否新建文件
if not create_if_not_exists:
# 文件打开失败后不新建文件
print(f"""文件【{self.file_abs_path}】打开失败!""")
raise Exception(f"""文件【{self.file_abs_path}】不存在,请检查输入路径!""")
else:
# 文件打开失败后新建文件
print("文件新建中...")
dirct = os.path.split(self.file_abs_path)[0] # 获取文件路径
dir_exist = os.path.isdir(dirct) # 判断路径是否存在
file_name = os.path.split(self.file_abs_path)[1] # 获取文件名
# 判断所给文件路劲及文件名的合理性
if dir_exist:
try:
# 根据文件拓展名新建各种格式的文件
ext = os.path.splitext(self.file_abs_path)[1] # 获取文件拓展名
xl_file_format = {".xlsx": 51, ".xls": 56, ".csv": 6}
# 代表相应文件格式的数值
# .xls 97-2003文件;.csv 逗号分隔值文件。
file_format_value = xl_file_format[ext] if ext in xl_file_format else 51
# 根据拓展名确定文件格式标识码,默认格式为.xlsx,其标识码为51。
wb = self._xlApp.Workbooks.Add() # 新建工作簿
wb.SaveAs(self.file_abs_path, file_format_value) # 文件另存为
print(f"""文件【{self.file_abs_path}】已创建!!""")
self._xlBook = self._xlApp.Workbooks.Open(self.file_abs_path)
print(f"""新建文件【{self.file_abs_path}】已打开!!""")
except:
# 文件名称不合法
raise Exception(f"""文件名称【{file_name}】不合法!""")
else:
# 文件路径不合法
raise Exception(f"""文件目录【{dirct}】不存在!""")
def add_sheet(self, new_sheet_name=None, new_sheet_location=None):
"""为工作簿添加工作表,默认向右添加。
:param new_sheet_name: 新添加工作表的名称
:param new_sheet_location: 新添加工作表的位置
"""
try:
if new_sheet_location is None:
# 新建工作表位于到最右侧
new_sheet_location = self._xlBook.Worksheets(self._xlBook.Worksheets.Count)
sht = self._xlBook.Worksheets.Add(Before=None, After=new_sheet_location)
if new_sheet_name is not None:
sht.Name = new_sheet_name
elif new_sheet_location == 0:
# 新建工作表位于到最左侧
new_sheet_location = self._xlBook.Worksheets(1)
sht = self._xlBook.Worksheets.Add(Before=new_sheet_location)
if new_sheet_name is not None:
sht.Name = new_sheet_name
else:
# 新建工作表位于指定工作表之后
new_sheet_location = self._xlBook.Worksheets(new_sheet_location)
sht = self._xlBook.Worksheets.Add(Before=None, After=new_sheet_location)
if new_sheet_name is not None:
sht.Name = new_sheet_name
except:
print("工作表名称已存在")
raise Exception(f"""工作表名称【{new_sheet_name}】已存在!""")
def delete_sheet(self):
# 删除工作表
pass
def get_cell_value(self, sheet, row, col):
"""读取单个单元格的值
:param sheet: 工作表名称或索引号
:param row: 单元格的行号
:param col: 单元格的列号
"""
sht = self._xlBook.Worksheets(sheet)
return sht.Cells(row, col).Value
def set_cell_value(self, sheet, row, col, value):
"""设置单个单元格的值
:param sheet: 工作表名称或索引号
:param row: 单元格行的索引号
:param col: 单元格列的索引号(column)
:param value: 设置的数值
"""
sht = self._xlBook.Worksheets(sheet)
sht.Cells(row, col).Value = value
def set_cell_format(self, sheet, row, col, bold=False, font_clr=None,
background=None, center=False):
"""设置单个单元格格式
:param sheet: 设置格式的工作表名称或索引号
:param row: 设置格式的单元格行索引号
:param col: 设置格式的单元格列索引号(column)
:param bold: 文字加粗(默认不加粗)
:param font_clr: 字体颜色
:param background: 单元格背景色
:param center: 设置水平居中(默认不水平居中)
注:颜色代号——https://blog.csdn.net/weixin_34202952/article/details/85416015
"""
sht = self._xlBook.Worksheets(sheet)
if bold:
sht.Cells(row, col).Font.Bold = bold # 设置文字加粗
if font_clr is not None:
sht.Cells(row, col).Font.ColorIndex = font_clr # 设置文字颜色
if background is not None:
sht.Cells(row, col).Interior.ColorIndex = background # 单元格背景色
if center:
sht.Cells(row, col).HorizontalAlignment = -4108 # 设置平居中xlCenter
def get_range(self):
# 获取指定区域内的全部单元格数值
pass
def save(self):
# 保存工作簿
print(f"""文件【{self.file_abs_path}】已保存!""")
return self._xlBook.Save()
def close(self):
# 关闭工作簿
print(f"""文件【{self.file_abs_path}】已关闭!""")
return self._xlBook.Close()
def save_as(self, new_file_abs_path=None):
"""文件另存为
:param new_file_abs_path: 另存为文件的绝对路径
"""
new_dirct = os.path.split(new_file_abs_path)[0] # 另存为文件的文件夹路径与原文件保持一致
new_dirct_exist = os.path.isdir(new_dirct) # 判断另存为文件的路径是否存在
new_file_name = os.path.split(new_file_abs_path)[1] # 另存为文件的名称
ori_file_name = os.path.split(self.file_abs_path)[1] # 原文件的名称
ori_ext = os.path.splitext(self.file_abs_path)[1] # 获取原文件的拓展名
new_ext = os.path.splitext(new_file_name)[1] # 获取另存为文件的拓展名
if new_dirct_exist:
if new_file_name == ori_file_name:
print("另存为文件名称(含拓展名)与原文件完全一致")
raise Exception(f"""另存为文件名称【{new_file_name}】与原文件名称【{ori_file_name}】完全一致!""")
else:
if ori_ext == new_ext:
print("另存为文件与原文件拓展名一致,文件格式保持不变。")
self._xlBook.SaveAs(new_file_abs_path)
else:
xl_file_format = {".xlsx": 51, ".xls": 56, ".csv": 6}
file_format_value = xl_file_format[new_ext]
self._xlBook.SaveAs(new_file_abs_path, file_format_value)
print(f"""文件【{ori_file_name}】已另存为【{new_file_name}】!""")
print(f"""文件格式由【{ori_ext}】变为【{new_ext}】!""")
print(f"""另存为文件的绝对路径为【{new_file_abs_path}】。""")
else:
raise Exception(f"""另存为文件的文件目录【{new_dirct}】不存在!""")
def quit(self):
# 退出程序
print(f"""程序已退出!""")
return self._xlApp.Quit()
名称 | 值 | 说明 |
---|---|---|
xlCenter | -4108 | 居中 |
更多详见:https://docs.microsoft.com/zh-cn/office/vba/api/excel.constants 。
名称 | 值 | 说明 | 拓展名 |
---|---|---|---|
xlCSV | 6 | CSV | *.csv |
xlExcel8 | 56 | Excel 97-2003工作簿 | *.xls |
xlWorkbookDefault | 51 | 默认工作簿 | *.xlsx |
更多格式详见:https://docs.microsoft.com/zh-cn/office/vba/api/excel.xlfileformat 。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
=============================
Author = Hulunbuir & DalaiNur
Email: [email protected]
Last Update: 2019.09.09 18:47
=============================
"""
if __name__ == "__main__":
# 测试代码
xl = Excel(r"D:\Test.xlsx", create_if_not_exists=1) # 打开文件,若文件不存在则新建并打开。
xl.set_cell_value("Sheet1", row=1, col=1, value="H100") # 设置单元格单元格数值
xl.set_cell_value(1, row=2, col="B", value="H200") # 设置单元格单元格数值
print(xl.get_cell_value("Sheet1", row=1, col=1)) # 读取单元格数值
xl.add_sheet("New_Sheet1", 0) # 目前New_Sheet1位于最左侧
xl.add_sheet("New_Sheet2") # 目前New_Sheet2位于最后
xl.add_sheet("New_Sheet3", 2) # 目前New_Sheet3位于第二个工作表之后
xl.add_sheet() # 目前位于最后,名称采用系统默认名称
xl.add_sheet(new_sheet_location=3) # 目前位于第3个工作边之后,名称采用系统默认名称
xl.set_cell_value(4, row=1, col=1, value="H300") # 设置单元格单元格数值
xl.set_cell_value(5, row=1, col=1, value="H400") # 设置单元格单元格数值
xl.set_cell_format("Sheet1", row=1, col=1,
font_clr=3, bold=True, background=15,
center=True) # 设置单元格格式(红色加粗灰色背景水平居中)
xl.set_cell_format("Sheet1", row=2, col=2, font_clr=5) # 蓝色字体
xl.save() # 保存文件
xl.save_as(r"D:\Test.xls") # 文件另存为.xls文件
xl.close() # 关闭文件
xl.quit() # 退出程序
[1] Mark Hammond, Andy Robinson. Python Programming on Win32 Chapter 9 - Integration with Excel.
[2] 热心市民小磊. win32com模块 https://blog.csdn.net/u013289615/article/details/89295957.
[3] zhu2695. C# Excel ColorIndex 对应列表 https://blog.csdn.net/zhu2695/article/details/47444745.
以上,便是利用pywin32库对Excel进行二次开发的简单介绍,因篇幅有限,某些非关键功能未做详细介绍,如有疑问,欢迎邮件来询。
仅以此文为我的Python调用Excel有关功能的实现做个一个备忘,同时也为有需要的人提供多一点参考。
胸藏文墨怀若谷,腹有诗书气自华,希望各位都能在知识的pāo子里快乐徜徉。
因个人水平有限,文中难免有所疏漏,还请各位大神不吝批评指正。
最后,祝各位攻城狮们,珍爱生命,保护发际线!
本文部分内容来自图书 Python Programming on Win32 !
欢迎大家点赞、评论及转载,转载请注明出处!
为我打call,不如为我打款!
打赏可备注邮箱,本人会将上述代码发送给各位土豪!