Python openpyxl打开有公式的excel表取值错误的解决办法,Python openpyxl获取excel有公式的单元格的数值错误,Python操作excel(.xlsx)封装类

Python openpyxl打开有公式的表格,如果直接读取,会出现有公式的单元格为空或零的情况。
参见:
https://blog.csdn.net/weixin_45903952/article/details/105073611?utm_medium=distribute.wap_relevant.none-task-blog-title-3

wb = openpyxl.load_workbook(‘test.xlsx’, data_only=True)
当’test.xlsx’被生成并在Excel程序中打开并保存之后(这个过程Excel会把公式结果计算出来),该文件附带有两套值,一套是公式全都没有计算的(data_only=False(默认)),一套是公式计算了结果的(data_only=True)。(如果没有被Excel打开并保存,则只有一套值(data_only=False的那套,公式没有计算结果的)。
此时,以data_only=True或默认data_only=False打开会得到两种不同的结果,各自独立,即data_only=True状态下打开的,会发现公式结果为None(空值)或者一个计算好的常数,而不会看到它原本的公式是如何。而data_only=False则只会显示公式而已。因此,data_only=True状态下打开,如果最后用save()函数保存了,则原xlsx文件中,公式会被替换为常数结果或空值。而data_only=False状态下打开,最后用save()函数保存了的话,原xlsx文件也会只剩下data_only=False的那套值(即公式),另一套(data_only=True)的值会丢失,如想重新获得两套值,则仍旧需要用Excel程序打开该文件并保存。

    def justOpen(strFileName):
        """
        模拟手工打开excel表
        :param strFileName: 打开的excel文件名(后缀.xlsx格式)
        """
        try:
            xlApp = Dispatch("Excel.Application")
            xlApp.Visible = False
            xlBook = xlApp.Workbooks.Open(os.path.join(os.getcwd(), strFileName))
            xlBook.Save()
            xlBook.Close()
        except:
            print("请手工打开 %s 后,随便修改一个空值并保存" % strFileName)

**

我的完整测试代码如下:

**

"""
================================================
Python模块:Python操作excel(.xlsx)封装类MyPyExcel
================================================
"""

import openpyxl
from openpyxl.worksheet.worksheet import Worksheet
import os
from win32com.client import Dispatch


class MyPyExcel:
    """
    Python操作excel(.xlsx)封装类MyPyExcel
    """

    def __init__(self, strOpenFilePath, data_only=True):
        """
        初始化功能,加载excel文件
        : strOpenFilePath: 要打开的excel(.xlsx)文件路径
        """
        self.strOpenFilePath = strOpenFilePath  # 工作簿路径
        self.workbook = None  # 工作簿对象
        self.worksheet = None  # 工作表对象

        path = os.path.join(os.getcwd() + "\\" + strOpenFilePath)
        # 文件存在就加载,不存在就创建工作簿。
        if os.path.exists(path):
            # 文件存在就加载,加载失败就报错。
            try:
                self.workbook = openpyxl.load_workbook(strOpenFilePath, data_only=data_only)
            except:
                print("加载excel文件失败!请检查!")
                raise
        else:
            print("加载excel文件不存在!自动创建文件!")
            self.workbook = openpyxl.Workbook()  # 创建工作簿

    def openWorkSheet(self, strSheetName) -> Worksheet:  # 表示此函数的返回值,是一个这样的类型,函数注解
        """
        打开工作表功能
        :param strSheetName: 要打开的工作表名称
        :return: 返回打开的工作表Worksheet对象
        """
        if strSheetName in self.workbook.sheetnames:
            self.worksheet = self.workbook[strSheetName]
        else:
            print("表单名称在当前excel文件中不存在,请检查表单名称!")

        return self.worksheet

    def getDataByCell(self, nRow, nColumn):
        """
        读取一个单元格的数据功能
        :param nRow: 行号1,2,...
        :param nColumn: 列号1,2,...
        :return: 指定单元格数值
        """
        # 判断行号、列号有效
        if self.isCheckNumValid(nRow, self.worksheet.max_row) is True and \
                self.isCheckNumValid(nColumn, self.worksheet.max_column) is True:
            return self.worksheet.cell(nRow, nColumn).value

    def putDataByCell(self, nRow, nColumn, value):
        """
        写入一个单元格数据功能
        :param nRow: 行号1,2,...
        :param nColumn: 列号1,2,...
        :param value: 写入指定单元格的数值
        """
        self.worksheet.cell(nRow, nColumn).value = value

    def saveWorkBookData(self, strSaveFilePath):
        """
        保存工作簿数据功能
        :param strSaveFilePath: 保存或另存工作簿的路径
        """
        try:
            self.workbook.save(strSaveFilePath)
        except PermissionError:
            print("要操作的文件,没有写入权限,请检查权限!")
            raise
        except FileNotFoundError:
            print("文件路径不存在,请确保路径正确!")
            raise
        except:
            print("保存写入的数据失败!请检查异常!")
            raise

    def closeWorkBook(self):
        """
        关闭工作簿功能
        """
        self.workbook.close()

    @staticmethod
    def isCheckNumValid(cur_num, max_num):
        """
        检测数据是否有效功能
        :param cur_num: 当前指定的行号或列号1,2...
        :param max_num: 当前工作表的最大行号或最大列号1,2...
        :return: True表示数据有效,否则反
        """
        # 类型检测
        if type(cur_num) is not int and type(cur_num) is not str:
            print("cur_num 数据类型错误!请确认为整数类型,或者为字符串类型!")
            return False
        # 数字检测
        if type(cur_num) is str:
            try:
                cur_num = int(cur_num)
            except:
                print("cur_num参数非法!请确认是输入数据为整数数字!")
                return False
        # 数字是否出范围
        if cur_num in range(1, max_num + 1):
            return True
        else:
            print("行号或者列号,超出了目前最大行号,或者最大列号!!")
            return False

    @staticmethod
    def justOpen(strFileName):
        """
        模拟手工打开excel表
        :param strFileName: 打开的excel文件名(后缀.xlsx格式)
        """
        try:
            xlApp = Dispatch("Excel.Application")
            xlApp.Visible = False
            xlBook = xlApp.Workbooks.Open(os.path.join(os.getcwd(), strFileName))
            xlBook.Save()
            xlBook.Close()
        except:
            print("请手工打开 %s 后,随便修改一个空值并保存" % strFileName)


"""
========================================
主函数功能测试
========================================
"""
if __name__ == '__main__':
    # 对自己定义的功能类进行测试
    # 正常功能测试
    myExcel = MyPyExcel("test.xlsx")  # 加载文件
    myExcel.openWorkSheet("Sheet")  # 选择工作表
    myExcel.putDataByCell(1, 1, 100)  # 写入一个单元格数据
    myExcel.putDataByCell(2, 1, 400)  # 写入一个单元格数据
    myExcel.putDataByCell(3, 1, "=SUM(A1:A2)")  # 写入一个单元格公式
    myExcel.saveWorkBookData("test.xlsx")  # 保存数据
    myExcel.closeWorkBook()  # 关闭工作簿

    myExcel.justOpen("test.xlsx")  # 模拟手工打开excel表

    """读取单元格的数值。data_only=True"""
    myExcel2 = MyPyExcel("test.xlsx")  # 加载文件
    myExcel2.openWorkSheet("Sheet")  # 选择工作表
    print(myExcel2.getDataByCell(3, 1))  # 读取某一个单元格数据
    myExcel2.closeWorkBook()  # 关闭工作簿

    """读取单元格的公式。data_only=False"""
    myExcel3 = MyPyExcel("test.xlsx", False)  # 加载文件
    myExcel3.openWorkSheet("Sheet")  # 选择工作表
    print(myExcel3.getDataByCell(3, 1))  # 读取某一个单元格公式
    myExcel3.closeWorkBook()  # 关闭工作簿

输出结果如下:
在这里插入图片描述
Python openpyxl打开有公式的excel表取值错误的解决办法,Python openpyxl获取excel有公式的单元格的数值错误,Python操作excel(.xlsx)封装类_第1张图片

你可能感兴趣的:(Python+PyCharm,Python,openpyxl,excel含公式的单元格,获取单元格数值失败,openpyxl,单元格,数值,Python操作excel封装)