How to open Excel instance in python on MAC?

11,340

Solution 1

From the comments it is not completely clear if you need to 'update' an Excel file with data, and just assume that you need Excel to do so, or that you need to change some excel files to include new data.

It is usually much easier, and certainly faster (wrt excution speed) to go with 'updating' an Excel file without starting Excel. However updating is not the right word: you have to read in the file and write it out new. You can of course overwrite the orginal file, so it looks like an update.

For 'updating' you can use the trio xlrd, xlwt, xlutils if the files you work with are .xls files (Excel 2003). IIRC xlwt does not support .xlsx for writing (but xlrd can read those files).

For .xlsx files I use openpyxl,

Both are good enough for writing things like data, formula and basic formatting.

If you have existing Excel files which you use as 'templates' with information that would get lost if you read/write using one of the above packages, then you have to go with updating the file in Excel. I had to do so because I had no easy way to include Visual Basic macros and very specific formatting specified by a client. And sometimes it is just easier to visually setup a spreadsheet and then just fill the cells programmatically. But this was all done on Windows.

If you really have to drive Excel on Mac, because you need to use existing files as templates, I suggest you look at Applescript. Or, if it is an option, look at OpenOffice/LibreOffice PyUno interface.

Solution 2

If all you need to do is launch Excel, the best way to do it is to use LaunchServices to do it.

If you have PyObjC (which you do if you're using the Python that Apple pre-installs on 10.6 and later; otherwise, you may have to install it):

import Foundation
ws = Foundation.NSWorkspace.sharedWorkspace()
ws.launchApplication_('Microsoft Excel')

If not, you can always use the open tool:

import subprocess
subprocess.check_call(['open', '-a', 'Microsoft Excel'])

Either way, you're effectively launching Excel the same way as if the user double-clicked the app icon in Finder.

If you want to make Excel do something simple like open a specific document, that's not much harder. Look at the NSWorkspace or open documentation to see how to do whatever you want.

If you actually want to control Excel—e.g., open a document, make some changes, and save it—you'll want to use its AppleScript interface.

Apple's recommended way of doing that is via ScriptingBridge, or using a dual-language approach (write AppleScripts and execute them via NSAppleScript—which, in Python, you do through PyObjC). However, I'd probably use appscript (get the code from here). Despite the fact that it's been abandoned by its original creator, and is only being sparsely maintained, and will probably eventually stop working with some future OS X version, it's still much better than the official solutions.

Here's a sample (untested, because I don't have Excel here):

import appscript
excel = appscript.app('Microsoft Excel')
excel.workbooks[1].column[2].row[2].formula.set('=A2+1')
Share:
11,340
Fawad
Author by

Fawad

I like to code in C# and I'm developing C# applications for my office. I have good knowledge of C# but on and off I get lost so I come to stackoverflow for your support. C# Developer. Learned: Python Java PHP Basic SQL Basic CSS HTML

Updated on June 06, 2022

Comments

  • Fawad
    Fawad about 2 years

    I think this question has been asked before but it's not clear, in the original question the user has provided excel.exe which is a windows executable extension and not for mac.

    • I need to open new Excel instance in Python on MAC.

    which module should I import?

    I'm a newbie I have completed learning python language, but have trouble understanding documentation.

  • Fawad
    Fawad over 11 years
    Thanks. I actually wanted these tasks 1. Open Excel (with blank new document). Afterwards (means yes I will want to read data from excel files) 2. Read, Update, Delete, Save.
  • Fawad
    Fawad over 11 years
    from the look of code Import subprocess was able to do the task. I need to know something here. as I said earlier I'm newbie. in the doc the subprocess is given as this subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) you passed "open, -a, microsoft excel" how does python recognizes that which arguments belong to which? because there are more than 3 , how does python recognizes the order? Apple script looks readable english to me. I think i might go for that.
  • abarnert
    abarnert over 11 years
    I passed a single argument, the list ['open', '-a', 'Microsoft Excel'], which goes to the first parameter, args. The other parameters all get their default values. (Note that in 3.x, the other parameters are all keyword-only, meaning you can't pass more than 1 argument unless you pass them by name.)
  • abarnert
    abarnert over 11 years
    As for AppleScript: it's pretty easy to read, but actually pretty hard to write. You often have to find sample code that does something close to what you want and then modify it, because you can't figure out how to write it from scratch. The good news is that for popular apps like Excel, there's tons of sample code out there. Google "Applescript Excel"—or just look at the applescript-excel tag here at SO—and you should be set. Personally, I prefer to use appscript from within Python, because it means I get to use all that nice Python stuff like list comprehensions and the stldib.
  • abarnert
    abarnert over 11 years
    One more thing: If you use AppleScript/ScriptingBridge/appscript, you don't have to do anything extra to launch the app. When you send a command to an app, if it's not running, the OS starts it automatically. So, if you're going that route, you can ignore the first half of my answer.
  • Anthon
    Anthon over 11 years
    Sounds like you don't need Excel. Just go with the library that supports the format you need to produce (.xls -> xlwt, .xlsx -> openpyxl)
  • Felix Zumstein
    Felix Zumstein about 10 years
    The last line in the untested sample should read excel.workbooks[1].cells.columns[2].rows[2].formula.set('=A2‌​+1'), mind the cellsand the plurals in columsn/rows. Alternatively: cells['B2']