Search code examples
pythonexcelopenpyxlxlsx

updating and saving excel file using openpyxl and then reading it gives none values for formula based column


I am trying to update an excel sheet using openpyxl. When reading a updated formula based cell I am getting None output. The updates are not getting saved even though I have used openpyxl save command.

import openpyxl

# data_only=False   to upadate excel file
def write_cell(data_only):
    wb_obj = openpyxl.load_workbook("mydata.xlsx", data_only=data_only)
    sheet_obj = wb_obj["Sheet1"]
    sheet_obj = wb_obj.active
    sheet_obj.cell(row = 1, column = 1).value = 8
    wb_obj.save(filename="mydata.xlsx")

# data_only=True   to read excel file"
def read_cell(data_only):
    wb_obj = openpyxl.load_workbook("mydata.xlsx", data_only=data_only)
    sheet = wb_obj["Sheet1"]
    # Formula at column 2 : =A1*5
    val = sheet.cell(row = 1, column = 2).value
    return val


write_cell(False)
print(read_cell(True))

Actual Output -> None Expected output -> 40


Solution

  • There are two solutions to this:

    1. If you refer the documentation, it is mentioned that you can either have the formula or the value from formula. If you modify a file with formulae then you must pass it through some kind of application such as Excel and save it again which will now update the value of the formula. You won't get the none as the output now if you try to read the value of the cell containing formula.

    2. Another solution is to open the excel file and save it from the script itself after saving it using openpyxl:

    from win32com.client import Dispatch
    import openpyxl
    
    def write_cell(data_only):
        wb_obj = openpyxl.load_workbook("mydata.xlsx", data_only=data_only)
        sheet_obj = wb_obj["Sheet1"]
        sheet_obj = wb_obj.active
        sheet_obj.cell(row = 1, column = 1).value = 8
        wb_obj.save(filename="mydata.xlsx")
        open_save("mydata.xlsx")
    
    def open_save(filename):
        """Function to open and save the excel file"""
        xlApp = Dispatch("Excel.Application")
        xlApp.Visible = False
        xlBook = xlApp.Workbooks.Open(filename)
        xlBook.Save()
        xlBook.Close()