Repository: psychopy/psychopy

Issue:
openpyxl errors when using saveAsExcel methods
As discussed in a previous issue (#1207), there are errors when using saveAsExcel when using openpyxl 2.4.0:

> With PsychoPy 1.84.2 (and openpyxl 2.4.0), I am now getting an ImportError when trying to call saveAsExcel:
> ImportError: openpyxl is required for saving files in Excel (xlsx) format, but was not found.
> 
> I did a little digging, and found that this seems to stem from line 29 in data.py:
> from openpyxl.cell import get_column_letter
> 
> as far as I can tell, get_column_letter sits in openpyxl.utils.cell:
> http://openpyxl.readthedocs.io/en/default/api/openpyxl.utils.cell.html#openpyxl.utils.cell.get_column_letter
> 
> Now, if I change line 29 to import from openpyxl.utils.cell instead, I don't get the ImportError anymore. However, I get a different error instead:
> 
> File "[local python path]/data.py", line 3326, in saveAsExcel:
> ew = ExcelWriter(workbook=wb)
> TypeError: **init**() takes exactly 3 arguments (2 given)



Discussion:
and the solution from @peircej:

> Yes, it looks like a change in the openpyxl APA. It seems we don't need to use the ExcelWriter explicitly at all though. From the docs here:
> http://openpyxl.readthedocs.io/en/default/tutorial.html#saving-to-a-file
> it looks like we can forget of any mention of it and just do workbook.save(filename) rather than
> 
> ew = ExcelWriter(workbook); 
> ew.save(filename)

@janfreyberg Feel like submitting a PR for this one? The code should check whether the `openpyxl` version is >= 2.4.0, and if yes, use the new approach; and run the existing code otherwise.

Probably the "version test" should be catching the `import` exception. ;)

Yep, I'll do that in a bit!

On Fri, 14 Oct 2016, 22:09 Richard Höchenberger, notifications@github.com
wrote:

> Probably the "version test" should be catching the import exception. ;)
> 
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> https://github.com/psychopy/psychopy/issues/1274#issuecomment-253919929,
> or mute the thread
> https://github.com/notifications/unsubscribe-auth/AD5yCbL2huvjZZiNLgp3N9DaqcIYjjfbks5qz-91gaJpZM4KXQjd
> .

Great, I'll gladly review it and give you feedback in anything needs to be adjusted. You may also contact me/post here if you have questions.


Resolving patch:
diff --git a/psychopy/data.py b/psychopy/data.py
--- a/psychopy/data.py
+++ b/psychopy/data.py
@@ -22,11 +22,16 @@
 import re
 import warnings
 import collections
+from distutils.version import StrictVersion
 
 try:
     # import openpyxl
     import openpyxl
-    from openpyxl.cell import get_column_letter
+    if StrictVersion(openpyxl.__version__) >= StrictVersion('2.4.0'):
+        # openpyxl moved get_column_letter to utils.cell
+        from openpyxl.utils.cell import get_column_letter
+    else:
+        from openpyxl.cell import get_column_letter
     from openpyxl.reader.excel import load_workbook
     haveOpenpyxl = True
 except ImportError:
@@ -645,7 +650,6 @@ def saveAsExcel(self, fileName, sheetName='rawData',
         # import necessary subpackages - they are small so won't matter to do
         # it here
         from openpyxl.workbook import Workbook
-        from openpyxl.writer.excel import ExcelWriter
         from openpyxl.reader.excel import load_workbook
 
         if not fileName.endswith('.xlsx'):
@@ -663,8 +667,6 @@ def saveAsExcel(self, fileName, sheetName='rawData',
             wb.properties.creator = 'PsychoPy' + psychopy.__version__
             newWorkbook = True
 
-        ew = ExcelWriter(workbook=wb)
-
         if newWorkbook:
             ws = wb.worksheets[0]
             ws.title = sheetName
@@ -687,7 +689,7 @@ def saveAsExcel(self, fileName, sheetName='rawData',
                 _cell = _getExcelCellName(col=colN, row=lineN)
                 ws.cell(_cell).value = val
 
-        ew.save(filename=fileName)
+        wb.save(filename=fileName)
 
     def getOriginPathAndFile(self, originPath=None):
         """Attempts to determine the path of the script that created this
@@ -3305,7 +3307,6 @@ def saveAsExcel(self, fileName, sheetName='data',
         # import necessary subpackages - they are small so won't matter to do
         # it here
         from openpyxl.workbook import Workbook
-        from openpyxl.writer.excel import ExcelWriter
         from openpyxl.reader.excel import load_workbook
 
         if not fileName.endswith('.xlsx'):
@@ -3323,8 +3324,6 @@ def saveAsExcel(self, fileName, sheetName='data',
             wb.properties.creator = 'PsychoPy' + psychopy.__version__
             newWorkbook = True
 
-        ew = ExcelWriter(workbook=wb)
-
         if newWorkbook:
             ws = wb.worksheets[0]
             ws.title = sheetName
@@ -3363,7 +3362,7 @@ def saveAsExcel(self, fileName, sheetName='data',
                 ws.cell(_cell).value = unicode(val)
                 rowN += 1
 
-        ew.save(filename=fileName)
+        wb.save(filename=fileName)
         if self.autoLog:
             logging.info('saved data to %s' % fileName)
 


Test patch: