如何在不破坏openpyxl公式的情况下写入现有的excel文件?

时间:2013-11-28 09:38:54

标签: python excel pandas openpyxl

以下列方式从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()

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

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

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

我在这里解决"保留公式"只是问题的一部分。

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

无论如何,我推荐的(直到openpxyl进一步发展)是将公式映射到新的xlsxwriter.Workbook对象。我已成功使用该模块创建新的xlsx工作簿(带格式和公式),并且不知道格式从openpyxl对象转换到xlsxwriter的程度有多好,我相信它将是一个可行的保存解决方案至少是公式。

现在,由于shared formulas,这样做(我想做并自己完成)并不是非常简单。我不得不写一个“分享'这些共享公式,转置它们,并将它们应用于引用它的每个单元格。

有人可能会首先认为这种方法通过添加一系列公式来产生效率低下,而这些公式之前只有对现有公式的引用。但是,我尝试写这些“多余的”#39;使用xlsxwriter的公式,然后再次使用openpyxl读取该表。我发现公式再次作为共享读入,因此xlsxwriter或Excel应用程序本身正在进行此优化。 (当然,我可以很容易地弄清楚哪一个;我还没有。)

如果有需求,我很乐意发布我的解散和转置解决方案;目前它已集成到一个更大的模块中,我必须创建一个独立版本。一般来说,我在ecatmur对this question的回答中讨论的令牌化器中使用了分流码工具来解析公式,这是转置它们最难的部分(当然,如果你这么做你必须做的事情)想要推断共享公式在另一个“宿主细胞”中的含义。

答案 2 :(得分:3)

在excel中:

  Home --> Find & Select --> Replace

  Replace All: "=" with "spam"

在python中:

  Run python script to update excel sheets

在excel中:

  Replace All: "spam" with "="

答案 3 :(得分: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()