Update an Excel sheet in real time using Python - python

Is there a way to update a spreadsheet in real time while it is open in Excel? I have a workbook called Example.xlsx which is open in Excel and I have the following python code which tries to update cell B1 with the string 'ID':
import openpyxl
wb = openpyxl.load_workbook('Example.xlsx')
sheet = wb['Sheet']
sheet['B1'] = 'ID'
wb.save('Example.xlsx')
On running the script I get this error:
PermissionError: [Errno 13] Permission denied: 'Example.xlsx'
I know its because the file is currently open in Excel, but was wondering if there is another way or module I can use to update a sheet while its open.

I have actually figured this out and its quite simple using xlwings. The following code opens an existing Excel file called Example.xlsx and updates it in real time, in this case puts in the value 45 in cell B2 instantly soon as you run the script.
import xlwings as xw
wb = xw.Book('Example.xlsx')
sht1 = wb.sheets['Sheet']
sht1.range('B2').value = 45

You've already worked out why you can't use openpyxl to write to the .xlsx file: it's locked while Excel has it open. You can't write to it directly, but you can use win32com to communicate with the copy of Excel that is running via its COM interface.
You can download win32com from https://github.com/mhammond/pywin32 .
Use it like this:
from win32com.client import Dispatch
xlApp = Dispatch("Excel.Application")
wb=xlApp.Workbooks.Item("MyExcelFile.xlsx")
ws=wb.Sheets("MyWorksheetName")
At this point, ws is a reference to a worksheet object that you can change. The objects you get back aren't Python objects but a thin Python wrapper around VBA objects that obey their own conventions, not Python's.
There is some useful if rather old Python-oriented documentation here: http://timgolden.me.uk/pywin32-docs/contents.html
There is full documentation for the object model here: https://msdn.microsoft.com/en-us/library/wss56bz7.aspx but bear in mind that it is addressed to VBA programmers.

If you want to stream real time data into Excel from Python, you can use an RTD function. If you've ever used the Bloomberg add-in use for accessing real time market data in Excel then you'll be familiar with RTD functions.
The easiest way to write an RTD function for Excel in Python is to use PyXLL. You can read how to do it in the docs here: https://www.pyxll.com/docs/userguide/rtd.html
There's also a blog post showing how to stream live tweets into Excel using Python here: https://www.pyxll.com/blog/a-real-time-twitter-feed-in-excel/
If you wanted to write an RTD server to run outside of Excel you have to register it as a COM server. The pywin32 package includes an example that shows how to do that, however it only works for Excel prior to 2007. For 2007 and later versions you will need this code https://github.com/pyxll/exceltypes to make that example work (see the modified example from pywin32 in exceltypes/demos in that repo).

You can't change an Excel file that's being used by another application because the file format does not support concurrent access.

Related

Python: Issue Updating Data Links In Excel After Python Dataframe Export

Situation
I'm working on a data project integrating python in Google Colab and Excel 365 on Win 8.1. My python code collects new data updates on a regimented schedule and then exports/writes (e.g. overwrites, not appends the data) like to a report on an Excel spreadsheet.
I have no issue getting this to work going to a standalone spreadsheet.
I know I could potentially do all this in Python and not use Excel at all, but I prefer not to reinvent the wheel and not spend hours hardcoding all the formulas and links already existing in Excel.
Goal
My goal is to:
1. Use new data from my python export to populate/overwrite a data table on Sheet A in an existing Excel workbook.
2. Then I have a separate Sheet B in the same Excel workbook performing calculations via pre-existing links connecting to the original data table on Sheet A. I then want the links to auto update each time my python export updates the data table on the first sheet.
Problem
The issues I am running into are that if I use the df.to_excel function to export the data and even if I use the spreadsheet name parameter, the export overrides the data table and names the tab okay, but wipes out any other pre-existing sheets within the same workbook.
So I attempted a work around by exporting to an external workbook and then trying to update the links in the second workbook automatically. Problem is the links don't appear to update without the source data file and the second workbook with the links both being manually opened and then the updated file manually saved.
I tried using openpyxl to control the excel files but it appeared to have no effect on the files and no data was updated. (See code block and result at the end of this post.)
Assistance
Does anybody know a way to use python to:
1. Overwrite a specific sheet within an Excel workbook without wiping out the other existing sheets? And then have the links on another sheet automatically update which are connected to the new data?
Or
2. Auto update external links between separate Excel workbooks while the files are unopened?
Or
3. Control an instance of excel that can open both files to allow the links to auto update and then save and close the files automatically?
I found a post from some years ago that identified a win32 package for python that appeared to be able to control instances of excel. When I try doing a pip install in Colab I got an error that the package was unrecognized or doesn't exist.
Ideally, I would prefer not to use VB if at all possible to solve this.
Any solutions are much appreciated.
Thanks in advance.
Sample Code that isn't producing any results:
import openpyxl
# Example code
from openpyxl import load_workbook
from openpyxl import Workbook
wb = load_workbook('/content/drive/MyDrive/Data/Series/AC5M.xlsx', keep_links=True)
ws = wb.active
Workbook.save
Workbook.close
print(ws)
Result:
"function openpyxl.workbook.workbook.Workbook.close"

encrypting excel workbook sheet with python

I'm currently implementing a tool to automise parts of my daily work. Therefore I need to create a python tool which creates an excel-file (workbook) with several informations and encrypts the sheets of the file.
The first part which creates the file and fills it with the data works perfectly.
But the encryption doesn't work at all.
I'm using win32com, win32com.client and openpyxl. The workbook hast two different sheets, named "1" and "2".
My Workbook:
import win32com.client
import os, sys, win32com, os.path, time
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True
workbook = excel.Workbooks.Open(reading_path) ####this is the path where the file is stored
sheet = workbook.Worksheets(1)
So I searched through other topics and got the following:
import openpyxl
sheet.protection.set_password('test')
sheet.save(saving_path)
Unfortunately this doesn't work... My shell response an AttributeError. In Detail:
AttributeError: <unknown>.set_password
Does someone knows another way how to encrypt just the pages in excel with python?
Thanks a lot for your help!
It is not entirely clear what you mean by "encrypting the sheet" as the openpyxl code you refer to has nothing to do with encryption; see the warning in the documentation. Excel does support encryption of entire workbooks though, but that appears to be different from what you want.
In any case, your code fails because the sheet you get from win32com is a wildly different beast than what openpyxl expects. For example, sheet being based on COM requires an Excel process to run for manipulation to be possible, while openpyxl does not even require Excel to be available on the host machine.
Now in your particular case, you do not actually need openpyxl (although you might find that using it over win32com has plenty of benefits), and you could stay entirely within COM. As such, adding password protection is possible through Worksheet.Protect which in your case would boil down to simply running
sheet.Protect('test')

How to make Python change xlsx files when Excel app is opened?

Sorry if I ask a question that may have been asked before but I could not really find the answer in Google and Stack Overflow forums.
Question is connected with openpyxl usage as it is the most convenient library which works with xlsx files.
import openpyxl
wb = openpyxl.load_workbook("D:/Python.xlsx")
sheet = wb.active
i = 0
sheet["A1"] = i
wb.save("D:/Python.xlsx")
However, it does not work with an opened excel file. I get an error
[Errno 13] Permission denied: 'D:/Python.xlsx'
I also found similar questions:
PermissionError [errno 13] when running openpyxl python script in Komodo
write to an open exceldocument
What can I do to solve this error and make Python work with an opened file in Excel? My current version is Python 2.7. Also, if possible, what is the solution of making the same magic in xlsm files?
UPD:
If there is no solution for the first question (except Google Docs maybe, thanks to #Alex), is it possible to write a code which makes the following algorithm perform:
1. Close an Excel app and save
2. Do staff in python, and save the results in some destination in Excel
3. Open Excel file in Excel app?
I know how to do 2. Any thoughts on 1 and 3?
UPD2:
xlwings really does awesome job! Just what I needed! Thanks!
I want to provide a code that worked for me (just other users can find in Google and use):
import xlwings as xl
import time
wb = xl.Workbook.active()
sheet = wb.active
iter = 10
i = 0
while True:
i += 1
if i <= iter:
xl.Range("A1").value = i
time.sleep(1)
print(i)
else:
break
wb.save()
print("Done!")
OpenPyXL operates directly on files; it has nothing to do with the Excel program, and has no control over the Excel program. As such, if the file it is trying to modify is locked by Excel, there is nothing OpenPyXL can do about that.
This question is tagged with excel-vba and that is certainly one appropriate way to control the Excel program (so you can modify data while it is open in Excel, or close Excel). If you want an interface to Excel using Python, the best package these days is xlwings.

Is there anyway we can call an excel addin using python?

Is there anyway we can call an excel addin using python?
I would like to call a user-defined add-in which is present in excel using a python program. I need a freeware I think pyxll requires license.
You can try xlwings if you like to use python inside your excel.
Or try to dispatch excel with win32com
excel = win32com.client.gencache.EnsureDispatch ("Excel.Application")
I think that you'd have to save your add-in as vba project (How to Use Your Excel Add-In Functions in VBA.
Generally nearly everything that can be done via VBA could be done with python and dispatched excel, so VBA Object Model reference is a good documentation on it.

Automation Excel from Python

In my company, we use Linux in development and production environment. But we have a machine running Windows and Excel because we use a third party application excel addin to get financial market data to the machine. The add-in provides some functions (just like Excel function) for getting these datas into the local machine and then sending back to a MySql Database. We've also developed some VBA script to automation the task but still not satisfy with the result.
I'm considering using Python to do all these jobs, but before jumping in, i need to find a python package that can do
Use python to manipulate Excel (with its add-ins) and use its functions without opening Excel?
If I need to open Excel, I need to automate that task of executing the script every day, or in specific moment of the day (the market data need to be feed a specific time)
Thanks for suggestion
You'll need the Python Win32 extensions - http://sourceforge.net/projects/pywin32/
(now migrated to GitHub: https://github.com/mhammond/pywin32)
Then you can use COM.
from win32com.client import Dispatch
excel = Dispatch('Excel.Application')
wb = excel.Workbooks.Open(r'c:\path\to\file.xlsx')
ws = wb.Sheets('My Sheet')
# do other stuff, just like VBA
wb.Close()
excel.Quit()
You can put your script on Windows Task Scheduler to run for the times you need.
As an alternative, you might consider openpyxl.
import openpyxl
wb= openpyxl.Workbook()
ws = wb.get_active_sheet()
ws.title = 'My Title'
wb.save('C:\\Development\\Python\\alpha.xlsx')
Here's a chapter from the book I'm working through.
https://automatetheboringstuff.com/chapter12/
Luck

Categories

Resources