I am creating a Python script to paste values pulled from another file into an Excel template.
The Excel template contains many macros that process the data it is given. This data is then sent to the clipboard, and the unsaved Excel file is then closed.
I have used a combo of xlwt and xlrd (it's a .xls file) to try and write to the Excel file, but it seems that these commands access the file without explicitly opening it (the Excel file never comes on screen).
I was curious if anyone could point me in the right direction of some tools that would allow me to explicitly open an Excel file (e.g. subprocess.call()), paste the data into some cells, then let the user do the rest.
Any help or criticism is appreciated.
EDIT:
I have been trying to use pywin32 for my purposes. It's not quite working. While it can successfully open the Excel file and run the macro, it cannot pass any values into the textbox of the macro.
Here is my current code:
import win32com.client as win32
import time
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(r'C:\Users\me\Desktop\file.xlsm')
excel.Visible = True
#if I run wb.Application.SendKeys(1) here, it places a 1 into a cell on the worksheet
wb.Application.Run('Set_Up_Sheet') #running the macro, which successfully launches
time.sleep(2)
wb.Application.SendKeys(1) #this seems to have no effect
How can I send values to this macro's textbox?
Related
I was just curious about this ability but can't find a definitive answer. For example, if you have a program that writes data to an excel file, can you also include code that will open that excel file through the excel GUI?
I use openpyxl to interact with Excel files using Python 3.7. I open and save my .xlsx spreadsheets as follows:
from openpyxl import load_workbook
wb.load_workbook('file.xlsx', read_only=False)
wb.save('file.xlsx')
If file.xlsx contains no links to external data sources (such as SQL Server or Postgre-SQL), then there is no problem with the saved file and it opens okay in Excel after being processed by my Python script.
However, if file.xlsx does contain a link to external data, then upon executing the above script, the output file is now corrupted. When opening the file in Excel, the following error is reported and I have the option of attempting to recover it. When recovering, the data remains but all links to the data source are gone.
> We found a problem with some content in file.xlsx. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.
It is easy to reproduce this error as follows:
Create a blank spreadsheet and save it as file.xlsx.
Run the above three lines of Python code to open and save the file. You will see this works fine and has no impact on the spreadsheet.
Now open file.xlsx in Excel and, from the Data tab, choose a data source. You can choose any data source (link to a csv file, a table within Excel, or an external data source - it doesn't matter).
Save the spreadsheet, then run the above Python script (which again, simply opens and saves it).
Open file.xlsx in Excel. You will see that it is now corrupted.
My conclusion is that, at the moment, openpyxl doesn't support spreadsheets that contain links to external data. It would be useful to have this confirmed, or for a workaround to the above issue to be proposed.
Thanks!!
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')
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.
I'm using labview to create and save data from an experiment. Labview itself creates a text file but saves it automatically with a .xls extension (word 1997-2003--it's an old setup that was never changed because it never broke). Whenever I go to open one of the data files, excel spits out this:
"The file you are trying to open, 'name.ext', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?"
I'm generating a lot of data, so I want to use python to sort it out and do some quick analysis over files in a directory.
The problem is that python doesn't like that it's a text file saved with a .xls extension. It can cycle through the directory just fine to get the file names, but whenver I actually try to open the file or do anything with it, I get the error in the image attached. This happens if I change the extension to .xls, .xlsx, or do nothing with it at all and let it try to open the original filename.
error message
I literally have hundreds of these .xls files. I know I can go through, open each one in excel and save as a real excel file by hand, but that will take hours. Can someone please help me figure a way around this error in python?
Dropbox Data File set
*Update. Matlab, when trying to read one of the files using xlsread, says this:
Error using xlsread (line 251)
File C:\Users\zane\Documents\Research Projects\PneuFish Project\Data\Nov 28 2016 ATI
Data\ATI_Data_2016Y_11M_28D_16h_36m_01s.xls not in Microsoft Excel Format.
Thank you!
You can use the module xlrd.
import xlrd
import csv
def csv_from_excel():
wb = xlrd.open_workbook('your_workbook.xls')
sh = wb.sheet_by_name('Sheet1')
your_csv_file = open('your_csv_file.csv', 'wb')
wr = csv.writer(your_csv_file, quoting=csv.QUOTE_ALL)
for rownum in xrange(sh.nrows):
wr.writerow(sh.row_values(rownum))
your_csv_file.close()
Taken from This Post
This will convert from .xls to .csv, which is easily manipulated with Python.
You've said that the file is a text file, so don't tell Python that it's an Excel file. Just use Python's open and read it as text, then do whatever you want with it. open doesn't care what extension a file has.
I'm going to guess that the format is actually tab-delimited. From memory, earlier versions of Excel would read in tab-delimited text files with the .xls extension without complaint, whereas csv files would always bring up the text import wizard, so this was a common dodge if saving data intended for Excel from a program that didn't support writing real Excel files.
If you want the LabVIEW code to write real Excel files in future, the Write to Measurement File express VI has an option to write in xlsx format. I'm not sure which version of LabVIEW first introduced this but it's been there for a few years now.