tags:

views:

190

answers:

2

I am trying to use the stock standard win32com approach to drive Excel 2007 from Python. However, when I try to create a new workbook, things go pear-shaped:

Python 2.6.4 (r264:75706, Nov  3 2009, 13:23:17) [MSC v.1500 32 bit (Intel)] on win32
...
>>> import win32com.client
>>> excel = win32com.client.Dispatch("Excel.Application")
>>> wb = excel.Workbooks.Add()

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    wb = excel.Workbooks.Add()
  File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 467, in __getattr__
    if self._olerepr_.mapFuncs.has_key(attr): return self._make_method_(attr)
  File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 295, in _make_method_
    methodCodeList = self._olerepr_.MakeFuncMethod(self._olerepr_.mapFuncs[name], methodName,0)
  File "C:\Python26\lib\site-packages\win32com\client\build.py", line 297, in MakeFuncMethod
    return self.MakeDispatchFuncMethod(entry, name, bMakeClass)
  File "C:\Python26\lib\site-packages\win32com\client\build.py", line 318, in MakeDispatchFuncMethod
    s = linePrefix + 'def ' + name + '(self' + BuildCallList(fdesc, names, defNamedOptArg, defNamedNotOptArg, defUnnamedArg, defOutArg) + '):'
  File "C:\Python26\lib\site-packages\win32com\client\build.py", line 604, in BuildCallList
    argName = MakePublicAttributeName(argName)
  File "C:\Python26\lib\site-packages\win32com\client\build.py", line 542, in MakePublicAttributeName
    return filter( lambda char: char in valid_identifier_chars, className)
  File "C:\Python26\lib\site-packages\win32com\client\build.py", line 542, in <lambda>
    return filter( lambda char: char in valid_identifier_chars, className)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x83 in position 52: ordinal not in range(128)
>>> 

What is going wrong here? Have I done something silly, or is Python/win32com/Excel somehow broken?

+1  A: 

I'm on 2.6.3, so I can't check this directly, but it appears that you've got a non-ASCII character in the className somehow, and valid_identifier_chars is a byte string, so this breaks it.

A couple thoughts on things to check:

  • Are you using a localized version of Excel?
  • Do you have the latest version of win32com (the error message doesn't line up exactly with my version's line numbers)?
  • Do you have an earlier version of python (e.g. 2.5) that you can test this on, to see if it's a problem introduced in 2.6.4?

If you do have the latest version of win32com, a hacky thing to try would be to edit build.py, and change valid_identifier_chars to a Unicode string.

Ryan Ginstrom
Thanks Ryan! You hit the nail on the head with that last suggestion. My locale, `('English_Australia', '1252')` has non-ascii characters in string.letters, and `className` is sometimes Unicode. The `in` operator thus forces valid_identifier_chars to Unicode, which fails with the above error. Converting `className` to str provides a work-around for now, while I raise a possible bug with the win32com maintainers.
Marcelo Cantos
Given your locale is the same as that of the author of the whole pywin32 package, I'm a little surprised that this alleged bug hasn't been noticed before :-)
John Machin
+2  A: 

Hi Marcelo,

you might want to look at the excellent xl*t packages at http://www.python-excel.org/

Creating workbooks/sheets is as easy as:

import xlwt
from datetime import datetime

wb = xlwt.Workbook()
ws = wb.add_sheet('A Test Sheet')

ws.write(0, 0, 'Test', style0)
ws.write(1, 0, datetime.now(), style1)
ws.write(2, 0, 1)
ws.write(2, 1, 1)
ws.write(2, 2, xlwt.Formula("A3+B3"))

wb.save('example.xls')

And you don't have to bother with the win32com api.....

Good luck !!

Ben

Ben Hughes