Back to index

plone3  3.1.7
excel.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001, 2002 Zope Corporation and Contributors.
00004 # All Rights Reserved.
00005 # 
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
00008 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00009 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00010 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00011 # FOR A PARTICULAR PURPOSE.
00012 # 
00013 ##############################################################################
00014 """External Editor MSExcel Plugin
00015 
00016 $Id: excel.py 67538 2005-06-20 23:09:42Z chrism $
00017 """
00018 
00019 import os, types
00020 from time import sleep
00021 import win32com
00022 import pythoncom
00023 from win32com import client # Initialize Client module
00024 
00025 class EditorProcess:
00026     def __init__(self, file):
00027         """Launch editor process"""
00028         excel = win32com.client.Dispatch('Excel.Application')
00029         # Try to open the file, keep retrying until we succeed or timeout
00030         i = 0
00031         timeout = 45
00032         while i < timeout:
00033             try:
00034                 excel.Workbooks.Open(file)
00035             except:
00036                 i += 1
00037                 if i >= timeout:
00038                     raise RuntimeError('Could not launch Excel.')
00039                 sleep(1)
00040             else:
00041                 break
00042         excel.Visible = 1
00043         self.excelapp = excel
00044         self.file = file
00045         
00046     def wait(self, timeout):
00047         """Wait for editor to exit or until timeout"""
00048         sleep(timeout)
00049             
00050     def isAlive(self):
00051         """Returns true if the editor process is still alive"""
00052         tries = 0
00053         head, tail = os.path.split(self.file)
00054         head, tail = head.lower(), tail.lower()
00055 
00056         try:
00057             for doc in self.excelapp.Workbooks:
00058                 if head == doc.Path.lower() and tail == doc.Name.lower():
00059                     return 1
00060             return 0
00061         except pythoncom.com_error, why:
00062             # COM will reject the call to enumerate the docs if the user is
00063             # doing anything interactive at the time the call is made.  The
00064             # symptom is a COM error numbered -2147418111 named "Call rejected
00065             # by callee".  This could happen indefinitely while a user is
00066             # camped on a cell waiting for input, so the only sane thing to do
00067             # is to return true and wait til the next call to really do the
00068             # check.
00069             if why[0] == -2147418111:
00070                 return 1
00071             else:
00072                 raise
00073         except AttributeError, why:
00074             # No one knows why this happens but sometimes while a user is
00075             # editing, win32com\client\dynamic.py will raise an error
00076             # signifying that the attributes we attempt to look up on the Excel
00077             # document can't be found.  Ignore this and return 1 if so,
00078             # waiting for the next go-around to check again (eventually we do
00079             # get access to the attributes).
00080             if (isinstance(why, types.StringType) or
00081                 isinstance(why, types.UnicodeType)):
00082                 if why.endswith('Path') or why.endswith('Name'):
00083                     return 1
00084             raise
00085         except TypeError, why:
00086             # Again, who knows why this happens but the enumeration of
00087             # workbooks can occasionally lead to a type error, e.g.:
00088             # Traceback (most recent call last):
00089             # File "zopeedit.py", line 764, in ?
00090             # File "zopeedit.py", line 372, in launch
00091             # File "Plugins\excel.pyc", line 57, in isAlive
00092             # File "win32com\client\dynamic.pyc", line 210, in __getitem__
00093             # TypeError: This object does not support enumeration
00094             # We ignore this and return true.
00095             why = str(why)
00096             if why.endswith('enumeration'):
00097                 return 1
00098             raise
00099 
00100 def test():
00101     import os
00102     from time import sleep
00103     from tempfile import mktemp
00104     fn = mktemp('.html')
00105     f = open(fn, 'w')
00106     f.write('<html>\n  <head></head>\n<body>\n'
00107             '<table><tr><th>Column 1</th><th>Column 2</th></tr>' 
00108             '<tr><td>1234</td><td>3689</td></tr>'
00109             '<tr><td>2345</td><td>3789</td></tr>'
00110             '<tr><td>3456</td><td>3889</td></tr>'
00111             '</body>\n</html>')
00112     f.close()
00113     print 'Connecting to Excel...'
00114     f = EditorProcess(fn)
00115     print 'Attached to %s %s' % (`f.excelapp`, f.excelapp.Version)
00116     print ('%s is open...' % fn),
00117     if f.isAlive():
00118         print 'yes'
00119         print 'Test Passed.'
00120     else:
00121         print 'no'
00122         print 'Test Failed.'
00123     
00124 if __name__ == '__main__':
00125     test()