【问题标题】:How to write to an existing excel file without breaking formulas with openpyxl?如何在不破坏 openpyxl 公式的情况下写入现有的 excel 文件?
【发布时间】:2013-12-14 06:34:53
【问题描述】:

当您以以下方式从 Python 写入 excel 文件时:

import pandas
from openpyxl import load_workbook

book = load_workbook('Masterfile.xlsx')
writer = pandas.ExcelWriter('Masterfile.xlsx') 
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)

data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])

writer.save()

现有工作表中的公式和图表链接将保存为值。

如何覆盖此行为以保留公式和图表链接?

【问题讨论】:

    标签: python excel pandas openpyxl


    【解决方案1】:

    我知道这是一个较旧的线程,但我花了一段时间才找到解决方案 - xlwings 允许您写入一个选项卡并在另一个选项卡上保留图表。

    以下示例打开现有工作簿,更新图表所基于的数据,并保存为新版本。

    import xlwings as xw
    import pandas as pd
    
    #create DF
    months = ['2017-01','2017-02','2017-03','2017-04','2017-05','2017-06','2017-07','2017-08','2017-09','2017-10','2017-11','2017-12']
    value1 = [x * 5+5 for x in range(len(months))]
    df = pd.DataFrame(value1, index = months, columns = ['value1'])
    df['value2'] = df['value1']+5
    df['value3'] = df['value2']+5
    
    #load workbook that has a chart in it
    wb = xw.Book('C:\\data\\bookwithChart.xlsx')
    
    ws = wb.sheets['chartData']
    
    ws.range('A1').options(index=False).value = df
    
    wb = xw.Book('C:\\data\\bookwithChart_updated.xlsx')
    
    xw.apps[0].quit()
    

    【讨论】:

    • 有人知道为什么这不起作用吗?它在 2 天前对我有用,现在它除了启动 excel 并关闭它之外什么也没做。
    • @Tinkinc 你的 Excel 副本过期了吗?
    【解决方案2】:

    这里我只讨论问题的“保留公式”部分。

    我尝试使用 openpyxl 1.8,它确实成功读取了公式,但是当我尝试保存副本时它坏了。 (破损似乎与样式有关,而不是公式。)

    无论如何,我建议(直到 openpxyl 更进一步)将公式映射到新的 xlsxwriter.Workbook 对象。我已经成功使用该模块创建了新的 xlsx 工作簿(带有格式和公式),并且不知道这些格式将从 openpyxl 对象转换为 xlsxwriter 对象的效果如何,我相信这将是一个可行的解决方案,至少可以保留公式。

    现在,由于shared formulas,这样做(我想做并且自己做了)并不是超级简单。我必须编写一个工具来“取消共享”这些共享公式、转置它们并将它们应用于引用它的每个单元格。

    人们可能首先会认为,这种方法会在以前只引用现有公式的地方添加一堆公式,从而导致效率低下。但是,我尝试使用 xlsxwriter 编写这些“冗余”公式,然后再次使用 openpyxl 读回该表。我发现公式再次被读取为共享,因此 xlsxwriter 或 Excel 应用程序本身正在执行此优化。 (当然可以很容易地弄清楚是哪一个;我还没有。)

    如果有需求,我很乐意发布我的解共享和转置解决方案;目前它已集成到一个更大的模块中,我必须创建一个独立版本。不过一般来说,我在 ecatmur 对this question 的回复中讨论的分词器中使用了分流场工具来解析公式,这是转置它们最难的部分(当然,如果你想推断共享的内容,你必须这样做公式看起来像在另一个“宿主细胞”中)。

    【讨论】:

    • 正确 - 如果单元格具有属性 t='shared' 和 'ref':'A1:B3',则 excel 将在加载时复制此共享公式。 Openpyxl 1.8.3 应该保留共享公式。
    【解决方案3】:

    在excel中:

      Home --> Find & Select --> Replace
    
      Replace All: "=" with "spam"
    

    在python中:

      Run python script to update excel sheets
    

    在excel中:

      Replace All: "spam" with "="
    

    【讨论】:

      【解决方案4】:

      Openpyxl 1.7 包含一些处理公式的改进,以便在阅读时保留它们。使用guess_types=False 防止openpyxl 尝试猜测单元格的类型,如果您需要值而不是公式,1.8 包括data_only=True 选项。

      想要保留 2.x 系列中的图表。

      【讨论】:

      • 如果 data_only=False,公式应该使用 openpyxl 保存:book.save('filename.xlsx')。我不确定 pandas 是如何工作的,但公式的编写方式与单元格值不同,因此如果支持它们,您很可能需要以某种方式识别这些单元格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 2015-12-22
      • 2012-11-08
      • 2013-12-11
      相关资源
      最近更新 更多