如何使用Python向打开的Excel文件写入内容?

13

我正在使用openpyxl写入工作簿。但是为了编辑它,需要关闭该工作簿。是否有一种方法可以写入打开的Excel文件? 我想要一个按钮来运行一个Python代码,并填充单元格。

我目前构建的流程是使用VBA关闭文件,然后Python将其编写并重新打开文件。 但是这是低效的。这就是为什么我需要一种方法来写入打开的文件的原因。


1
你是否特别想使用openpyxl?我通常更喜欢使用xlrd和xlwt,因为它们具有相同的灵活性。 - SashaZd
1
我没有特别使用openpyxl的理由。到目前为止,我已经成功地同步了VBA和Python,并且openpyxl表现不错。你为什么建议使用xlwt或xlrd呢? - Suraj Nagabhushana Ponnaganti
1
@SashaZd 这个话题有些偏离,但你提到了 xlwt 作为一个选项。Openpyxl 在格式方面一直给我带来一些问题。在这方面,xlwt 更好吗?它是否保持 Excel 的格式? - Suraj Nagabhushana Ponnaganti
2
是的,它可以。我过去使用它进行了非常复杂的Excel-Python集成,包括公式和类型转换。它应该比OpenPyxl更好的解决方案。 - SashaZd
5个回答

10
如果您是Windows用户,有一种非常简单的方法可以实现此操作。如果我们使用Win32库,就可以利用内置的Excel对象VBA模型。
现在,我不确定您的数据长什么样子,或者想要将其放在工作簿的哪个位置,但我假设您希望它出现在打开工作簿时显示的工作表上。
例如,让我们想象一下,我有一个Pandas DataFrame,我想将其写入到一个打开的Excel工作簿中。它应该像这样:
import win32com.client
import pandas as pd

# Create an instance of the Excel Application & make it visible.
ExcelApp = win32com.client.GetActiveObject("Excel.Application")
ExcelApp.Visible = True

# Open the desired workbook
workbook = ExcelApp.Workbooks.Open(r"<FILE_PATH>")

# Take the data frame object and convert it to a recordset array
rec_array = data_frame.to_records()

# Convert the Recordset Array to a list. This is because Excel doesn't recognize 
# Numpy datatypes.
rec_array = rec_array.tolist()

# It will look something like this now.
# [(1, 'Apple', Decimal('2'), 4.0), (2, 'Orange', Decimal('3'), 5.0), (3, 'Peach', 
# Decimal('5'), 5.0), (4, 'Pear', Decimal('6'), 5.0)]

# set the value property equal to the record array.
ExcelApp.Range("F2:I5").Value = rec_array

再次强调,我们需要考虑很多事情,比如我们想要把它粘贴到哪里,数据的格式以及其他一系列问题。 然而,在一天结束时,如果你是Windows用户,使用Python可以向打开的Excel文件写入数据是可行的。


1
这个解决方案对我有效,但是由于ExcelApp.Workbooks.Open(),脚本尝试重新打开Excel表格。有没有一种方法可以获取已经打开的Excel文件? - Kaustubh
2
如果你想使用活动工作簿而不是编写以下代码:workbook = ExcelApp.Workbooks.Open(r"")你可以这样写:workbook = ExcelApp.ActiveWorkbook这代表了活动工作簿,或者换句话说,就是你当前光标所在的工作簿。 - areed1192

3

通常情况下,不应让两个不同的进程向同一个文件写入内容,否则将导致同步问题。

一种更好的方法是,在父进程(即VBA代码)中关闭现有文件,并将工作簿的位置传递给Python脚本。

Python脚本将打开它并在单元格中写入内容,然后退出。


因此,VBA代码执行Python代码并关闭Excel文件。 Python代码完成其工作并将其写入已关闭的同一Excel文件,然后打开它。但是,我正在尝试构建的工具将涉及大量交互,每次发生这种情况时,我不希望关闭和编辑Excel工作簿,然后再次打开它。就像VBA代码可以写入打开的Excel文件一样,我正在尝试使用Python实现相同的功能。 - Suraj Nagabhushana Ponnaganti
我认为Excel工作簿没有任何同步原语来允许两个并发写入。Python不知道VBA代码已经打开了文件,同样适用于VBA代码。我同意你的观点,可能会有很多交互,但最终的产品可能更可靠。此外,我认为多次打开和关闭文件并不耗时。 - apatniv

3

不可能实现这一点,因为Excel文件不支持并发访问。


1
COM与openpyxl有什么关系? - Charlie Clark

2
我通过以下步骤解决了这个问题:创建一个中间的Excel文件,接收来自Python的数据,然后在主文件和该文件之间建立连接。Excel具有自动刷新从另一个工作簿导入数据的工具。请参阅链接
wb = openpyxl.load_workbook(filename='meanwhile.xlsm', read_only=False, keep_vba=True)

...

wb.save('meanwhile.xlsm')

按顺序打开您的主要Excel文件:

在“数据”选项卡上,使用“同时”工作簿创建连接,然后在“连接”组中,单击“刷新”旁边的箭头,再单击“连接属性”。

单击“使用情况”选项卡。

选择“定期刷新”复选框,然后输入每次刷新操作之间的分钟数。


1
使用以下代码,我已经实现了在 MS Excel 中打开的情况下使用 Python 写入 Excel 文件。 此解决方案适用于 Windows 操作系统,不确定其他操作系统是否适用。
from kiteconnect import KiteConnect
import xlwings as xw

wb = xw.Book('winwin_safe_trader_youtube_watchlist.xlsx')
sht = wb.sheets['Sheet1']
stocks_list = sht.range('A2').expand("down").value
watchlist = []
time.sleep(10)

for name in stocks_list:
    symbol = "NSE:" + name
    watchlist.append(symbol)

print(datetime.datetime.today().time())
data = kite.quote(watchlist)
df = pd.DataFrame(data).transpose()
df = df.drop(['depth', 'ohlc'], 1)
print(df)
sht.range('B1').value = df
time.sleep(1)
wb.save('winwin_safe_trader_youtube.xlsx')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接