Python win32com Excel二次开发

官方文档:

  • Microsoft >> office 开发人员中心 Excel
  • GitHub >> MicrosoftDocs/VBA-Docs

目 录

  • 一、前沿
  • 二、库导入及类的初始化
  • 三、工作簿及工作表(Workbook & Worksheet)
    • 1、新建工作簿
    • 2、打开工作簿
    • 3、新建工作表
    • 4、删除工作表
  • 四、单元格及区域(Cell & Range)
    • 1、读取单元格的值
    • 2、设置单元格的值
    • 3、设置单元格格式
    • 4、区域(某一范围内的全部单元格)
  • 五、文件
    • 1、保存及关闭
    • 2、另存为
    • 3、退出
  • 六、枚举(Excel)
    • 1、常量枚举
    • 2、XlFileFormat 枚举 (文件格式)
  • 七、测试代码
  • 八、参考文献
  • 九、尾声

一、前沿

利用本文代码可以实现读写.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}】不存在!""")

三、工作簿及工作表(Workbook & Worksheet)

1、新建工作簿

2、打开工作簿

3、新建工作表

    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}】已存在!""")

4、删除工作表

    def delete_sheet(self):
        # 删除工作表
        pass

四、单元格及区域(Cell & Range)

1、读取单元格的值

    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

2、设置单元格的值

    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

3、设置单元格格式

    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

4、区域(某一范围内的全部单元格)

    def get_range(self):
        # 获取指定区域内的全部单元格数值
        pass

五、文件

1、保存及关闭

    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()

2、另存为

    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}】不存在!""")

3、退出

    def quit(self):
        # 退出程序
        print(f"""程序已退出!""")
        return self._xlApp.Quit()

六、枚举(Excel)

1、常量枚举

名称 说明
xlCenter -4108 居中

更多详见:https://docs.microsoft.com/zh-cn/office/vba/api/excel.constants 。

2、XlFileFormat 枚举 (文件格式)

名称 说明 拓展名
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,不如为我打款!

打赏可备注邮箱,本人会将上述代码发送给各位土豪!

Python win32com Excel二次开发_第1张图片

你可能感兴趣的:(Python,win32com,Excel,Excel)