Python and Microsoft Excel
If you’ve looked for examples of using Python and Office, you’ll usually find that the most often hacked component is Excel. In fact, there are several non-PyWin32 modules specifically created to read and write Excel files. They are called xlrd and xlwt, respectively. But that’s a topic for another article. Here we’ll see how to mess with Excel using the PyWin32 interface. Note that the following scripts only work on Windows. One advantage of xlrd and xlwt is that you can use them on any platform.
Let’s take a look at a simple example, shall we?
import time import win32com.client as win32 #---------------------------------------------------------------------- def excel(): """""" xl = win32.gencache.EnsureDispatch('Excel.Application') ss = xl.Workbooks.Add() sh = ss.ActiveSheet xl.Visible = True time.sleep(1) sh.Cells(1,1).Value = 'Hacking Excel with Python Demo' time.sleep(1) for i in range(2,8): sh.Cells(i,1).Value = 'Line %i' % i time.sleep(1) ss.Close(False) xl.Application.Quit() if __name__ == "__main__": excel()
The example above is similar to what you will normally find on the web. It is actually based on an example I saw in Wesley Chun’s excellent book, Core Python Programming. Let’s take some time and unpack the code. To gain access to Excel, we importwin32com.client and then call its gencache.EnsureDispatch, passing in the application name that we want to open. In this case, the string to pass is “Excel.Application”. All that does is open Excel in the background. At this point, the user won’t even know Excel is open unless they have Task Manager running. The next line is adds a new workbook to Excel by calling that Excel instance’s “Workbooks.Add()” method. This returns a sheets object (I think). To get the ActiveSheet, we call ss.ActiveSheet. Finally, we make the Excel program itself visible by setting that property to True.
To set a specific cell’s value, call something like this: sh.Cells(row,col).Value = “some value”. Note that our instance is NOT zero-based and will actually put the value in the correct row/col combo. If we want to extract a value, we just remove the equals sign. What if we want the formula? To figure this our, I recorded a macro in Excel and did a Paste Special command that only pasted the Formula. Using the code generated, I figured out that to get the formula in Python, you just do this:
formula = sh.Cells(row, col).Formula
What if you need to change which sheet you’re on? Recording a macro also showed me how to accomplish this feat. Here’s the VBA code from Excel:
Sub Macro1() ' ' Macro1 Macro ' Sheets("Sheet2").Select End Sub
From this code, I gathered that I needed to call my sheets object’s “Sheets” method and after a little fiddling, I got it to work by doing the following:
sheet2 = ss.Sheets("Sheet2")
Now we have a handle on the second sheet in the workbook. If you want to edit or retrieve values, just prepend the same methods you used above with whatever you called the sheet2 instance (i.e. sheet2.Cells(1,1).Value). The last two lines from the original program will close the sheets and then quit the entire Excel instance.
You may be thinking that so far all I’ve shown is how to create a new document. What if you want to open an existing file? Just do something like this at the beginning of the code:
xl = win32.gencache.EnsureDispatch('Excel.Application') ss = xl.Workbooks.Open(filename)
And there you have it! You now know the basics of hacking Excel with Python using Excel’s COM object model. If you need to learn more, I recommend trying to record a macro and than translating the result into Python. Note: I was unable to find an example that could save the spreadsheet…there are several examples that claim they work, but they didn’t for me.