python 通过win32操作Excel 简单封装

  python 通过win32操作Excel 简单封装。来自:通过win32操作Excel 简单封装,并添加了两个功能和注释。

# -*- coding: utf-8 -*-
# @Author:
# @Date :2019/7/3
# @Time :15:01
# @file :Excel.py
# @Software: PyCharm


import win32com.client
from enum import IntEnum

import pythoncom


class FileConst(IntEnum):
    XLSX = 51
    XLS = 56
    CSV = 6
    MAXROW = 1048576
    MAXCOLUMN = 16384


class Excel:

    def __init__(self):
        self.__app = win32com.client.Dispatch("Excel.Application")
        self.__app.Visible = False
        self.__app.DisplayAlerts = False

    def openExcelFile(self, filename):
        """
        打开指定的 Excel 文件并返回一个 WorkBook 对象。

        参数:
        - filename (str): 要打开的 Excel 文件的路径和文件名。

        返回:
        - WorkBook: 一个 WorkBook 对象,代表打开的 Excel 文件。

        异常:
        - 如果文件无法打开,可能会抛出异常。
        """
        #是否打开excel界面
        self.__app.Visible = False
        #是否关闭保存弹出框
        self.__app.DisplayAlerts = False
        return WorkBook(self.__app.Workbooks.Open(filename))

    def newExcelFile(self):
        """
        创建一个新的 Excel 文件并返回一个 WorkBook 对象。

        返回:
        - WorkBook: 一个 WorkBook 对象,代表新创建的 Excel 文件。

        异常:
        - 如果文件无法创建,可能会抛出异常。
        """
        return WorkBook(self.__app.Workbooks.Add())

    def closeExcelFile(self):
        """
        关闭 Excel 文件并。


        异常:
        - 如果文件无法打开,可能会抛出异常。
        """

        #退出excel,不退出则会被占用
        self.__app.Application.Quit()
        return

    def __del__(self):
        self.__app.DisplayAlerts = True
        self.__app.Quit()
        del self.__app


class WorkBook():
    def __init__(self, wb):
        # wb 指向所打开的文件
        self.__wb = wb

    def add_sheet(self, sheet_name=None, before=None):
        """
        在工作簿中添加一个新的工作表。

        参数:
        - sheet_name (str): 新工作表的名称。如果未提供,则默认使用"Sheet"作为名称。
        - before (str): 新工作表应放置的位置。如果提供,则新工作表将放置在指定名称的工作表之前。

        返回:
        - None

        异常:
        - 如果工作表名称已存在,可能会抛出异常。
        """
        if sheet_name:
            if before:
                self.__wb.Worksheets.Add(Before=self.__wb.Sheets(before)).Name = sheet_name
            else:
                self.__wb.Worksheets.Add().Name = sheet_name
        else:
            if before:
                self.__wb.Worksheets.Add(Before=self.__wb.Sheets(before))
            else:
                self.__wb.Worksheets.Add()

    def copy_sheet(self, source_index, target_index=None, name=None):
        """
        复制工作表。

        参数:
        - source_index (int): 要复制的源工作表的索引。
        - target_index (int): 复制后的工作表应放置的位置。如果未提供,则将复制的工作表放置在工作簿的最后。
        - name (str): 复制后的工作表的新名称。如果未提供,则使用源工作表的名称。

        返回:
        - None

        异常:
        - 如果源索引超出工作簿中的工作表数量,可能会抛出异常。
        - 如果目标索引超出工作簿中的工作表数量,可能会抛出异常。
        - 如果新名称已存在,可能会抛出异常。
        """

        #选择要复制得sheet
        source_sheet = self.__wb.Worksheets(source_index)
        if target_index is None:
            target_index = self.sheetCount + 1
        if name is None:
            name = source_sheet.Name

        #工作表名称已存在
        sheetsNames=self.sheetsNames
        if name in sheetsNames:
            raise ValueError("工作表名称已存在")
            return
        #复制当前sheet
        source_sheet.Copy(pythoncom.Empty, After=self.__wb.Worksheets(target_index - 1))

        # 定位新的sheet
        new_sheet = self.__wb.Worksheets(target_index)

        # 更改新sheet的名称
        new_sheet.Name = name

    def delete_sheet(self, index):
        """
        删除工作簿中指定索引位置的工作表。

        参数:
        - index (int): 要删除的工作表的索引位置。索引从 1 开始,表示第一个工作表。

        返回:
        - None

        异常:
        - 如果索引超出工作簿中的工作表数量,可能会抛出异常。
        """
        self.__wb.Worksheets(index).Delete()


    def activateSheet(self, index):
        """
        激活工作簿中指定索引位置的工作表,并返回一个 Sheet 对象。

        参数:
        - index (int): 要激活的工作表的索引位置。索引从 1 开始,表示第一个工作表。

        返回:
        - Sheet: 一个 Sheet 对象,代表激活的工作表。

        异常:
        - 如果索引超出工作簿中的工作表数量,可能会抛出异常。
        """
        return Sheet(self.__wb.Worksheets(index))


    def save(self, filename=None):
        """
        保存工作簿。

        参数:
        - filename (str): 要保存的文件的路径和文件名。如果未提供,则使用当前文件名保存。

        返回:
        - None

        异常:
        - 如果保存过程中发生错误,可能会抛出异常。
        """
        if filename:
            self.__wb.SaveAs(filename)
        else:
            self.__wb.Save()


    def saveAs(self, filename, fileformat=None):
        self.__wb.SaveAs(filename, FileFormat=fileformat)

    @property
    def sheetCount(self):
        """
        获取工作簿中的工作表数量。

        返回:
        - int: 工作簿中的工作表数量。

        异常:
        - 如果获取工作表数量时发生错误,可能会抛出异常。
        """
        return self.__wb.Worksheets.Count


    @property
    def sheetsNames(self):
        """
        获取工作簿中的所有工作表名称。

        返回:
        - list: 一个包含所有工作表名称的列表。

        异常:
        - 如果获取工作表名称时发生错误,可能会抛出异常。
        """
        lst = []
        for i in range(1, self.sheetCount + 1):
            lst.append(self.__wb.Sheets(i).Name)

        return lst
    def get_sheet_index(self, sheet_name):
        """
        根据给定的工作表名称获取其索引。

        参数:
        - sheet_name (str): 要查找的工作表名称。

        返回:
        - int: 工作表的索引,如果未找到则返回 -1。

        异常:
        - 如果发生错误,可能会抛出异常。
        """
        for i in range(1, self.sheetCount + 1):
            if self.__wb.Sheets(i).Name == sheet_name:
                return i
        return -1
    def get_sheet_name_by_index(self, index):
        """
        根据给定的索引获取工作表的名称。

        参数:
        - index (int): 要查找的工作表的索引。

        返回:
        - str: 工作表的名称,如果未找到则返回 None。

        异常:
        - 如果发生错误,可能会抛出异常。
        """
        if 1 <= index <= self.sheetCount:
            return self.__wb.Sheets(index).Name
        return None
    def close(self,save=False):
        """
        关闭工作簿而不保存更改。

        返回:
        - None

        异常:
        - 如果关闭过程中发生错误,可能会抛出异常。
        """
        self.__wb.Close(SaveChanges=save)
class Sheet():

    def __init__(self, sheet):
        self.__sheet = sheet

    def __check_index(self, row=1, column=1):
        if row < 1 or column < 1 or row > FileConst.MAXROW or column > FileConst.MAXCOLUMN:
            raise ValueError("索引出界")

    def setCellValue(self, row, col, value):
        self.__check_index(row, col)
        self.__sheet.Cells(row, col).Value = value

    def getCellValue(self, row, col):
        self.__check_index(row, col)
        return self.__sheet.Cells(row, col).Value

    def getCellObject(self, row, column):
        location = str(self.__sheet.Cells(row, column).Address)
        return Cell(self.__sheet.Range(location))

    def setCellTextFormat(self, row, col):
        """
        将指定单元格设置为文本格式。

        参数:
        - row (int): 单元格的行索引。
        - col (int): 单元格的列索引。

        返回:
        - None
        """

        self.__check_index(row, col)
        cell = self.__sheet.Cells(row, col)
        cell.NumberFormat = '@'  # 设置单元格格式为文本
    def delete_row(self, row):
        self.__check_index(row)
        self.__sheet.Rows(row).Delete()

    def delete_column(self, column):
        self.__check_index(column=column)
        self.__sheet.Columns(column).Delete()

    def insert_row(self, row):
        self.__check_index(row=row)
        self.__sheet.Rows(row).Insert()

    def insert_column(self, col):
        self.__check_index(column = col)
        self.__sheet.Columns(col).Insert()

    def rename(self, newName):
        self.__sheet.Name = newName

    @property
    def maxRow(self):
        return self.__sheet.UsedRange.Rows.Count + self.__sheet.UsedRange.Cells(1, 1).Row - 1

    @property
    def maxCloumn(self):
        return self.__sheet.UsedRange.Columns.Count + self.__sheet.UsedRange.Cells(1, 1).Column - 1

    # 支持sheet["A1"] 取值
    def __getitem__(self, item):
        return self.__sheet.Range(item)

    # 支持sheet["A1"] = value 这样赋值
    def __setitem__(self, key, value):
        self.__sheet.Range(key).Value = value


class Cell:

    def __init__(self, cell):
        self.__cell = cell

    def setFont(self, value):
        self.__cell.Font.Name = value

    def setFontSize(self, value):
        self.__cell.Font.Size = value

    def setValue(self, value):
        self.__cell.Value = value

    def getValue(self):
        return self.__cell.Value



if __name__ == '__main__':
    s1 = Excel()
    wb1 = s1.openExcelFile(r"C:\22.xlsx")
    a=wb1.sheetsNames
    sht1 = wb1.activateSheet(3)

    # print(sht.maxCloumn)
    # print(sht.maxRow)
    s2 = Excel()
    wb2 = s2.openExcelFile(r"C:\555.xlsx")

    print(wb2.sheetsNames)
    sht2 = wb2.activateSheet(1)




    for x in range(2, sht1.maxRow + 1):
        name=sht1.getCellValue(x,4)
        id=sht1.getCellValue(x,5)
        phone=sht1.getCellValue(x,7)
        num=sht1.getCellValue(x,8)
        card=sht1.getCellValue(x,9)
        print(name,id,phone,num,card)
        wb2.copy_sheet(source_index=1,name=name)
        sht2 = wb2.activateSheet(wb2.sheetCount)

        sht2.setCellTextFormat(2,2)
        sht2.setCellTextFormat(4,2)
        sht2.setCellTextFormat(3,6)
        sht2.setCellTextFormat(3,9)
        sht2.setCellTextFormat(4,7)

        sht2.setCellValue(3,2,name)
        sht2.setCellValue(4,2,id)
        sht2.setCellValue(3,6,phone)
        sht2.setCellValue(3,9,num)
        sht2.setCellValue(4,7,card)


    wb2.close(save=True)
    wb1.close()

    s1.closeExcelFile()
    s2.closeExcelFile()