Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pywin32 and excel. Exception when writing large quantities of data

I am currently trying to write a large amount of data to an excel spreadsheet using the pywin32 libraries. As a simple example of the problem that I am facing take the following code to generate a 1000 cell x 1000 cell multiplication table.

import win32com.client
from win32com.client import constants as c

xl = win32com.client.gencache.EnsureDispatch("Excel.Application")                             
xl.Visible = True
Workbook = xl.Workbooks.Add()
Sheets = Workbook.Sheets

tableSize = 1000

for i in range(tableSize):
    for j in range(tableSize):
        Sheets(1).Cells(i+1, j+1).Value = i*j

For small values this works. However, for larger values the python program eventually crashes with the error:

Traceback (most recent call last):
  File ".\Example.py", line 16, in <module>
    Sheets(1).Cells(i+1, j+1).Value = i*j
  File "C:\PYTHON27\lib\site-packages\win32com\client\__init__.py", line 474, in __setattr__
    self._oleobj_.Invoke(*(args + (value,) + defArgs)) pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2146777998), None)

I've already admitted defeat due to the fact that this is significantly slower than xlwt but I am still curious as to what is happening to cause this error.

like image 758
Aaron S Avatar asked Aug 06 '12 21:08

Aaron S


1 Answers

I figured it out.

The error only occurred when the user interacted with excel window while code was running. By adding xl.Interactive = False before doing any work with excel this can be avoided. If this is added before the application is visible there is no chance of any interaction.

So the final code is:

import win32com.client
from win32com.client import constants as c

xl = win32com.client.gencache.EnsureDispatch("Excel.Application")
xl.Interactive = False
xl.Visible = True
Workbook = xl.Workbooks.Add()
Sheets = Workbook.Sheets

Sheets(1).Cells(1,2).Value = "Test"
print Sheets(1).Cells(1,2).Value

tableSize = 1000

for i in range(tableSize):
    for j in range(tableSize):
            Sheets(1).Cells(i+1, j+1).Value = i*j
like image 136
Aaron S Avatar answered Oct 26 '22 19:10

Aaron S