Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Data Science Basics Exporting Exporting to Excel

I can't export to excel, I'm getting the error - cannot import name 'get_column_letter'

When I try to export I initially get an error

cannot import name 'get_column_letter'

So I changed

from openpyxl.cell import get_column_letter

to

from openpyxl.utils import get_column_letter

Then I get

/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/openpyxl/worksheet/worksheet.py:300: UserWarning: Using a coordinate with ws.cell is deprecated. Use ws[coordinate] instead warn("Using a coordinate with ws.cell is deprecated. Use ws[coordinate] instead")

Any advice?

6 Answers

The function get_column_letter has been relocated in Openpyxl version 2.4 from openpyxl.cell to openpyxl.utils. The current import is now: from openpyxl.utils import get_column_letter

Add this to your code

try:

from openpyxl.cell import get_column_letter

except ImportError:

from openpyxl.utils import get_column_letter
Stephen Cole
PLUS
Stephen Cole
Courses Plus Student 15,809 Points

After reading the docs, it seems that the ws.cell method was replaced with the coordinate system inside square brackets. Here's my updated subroutine.

        for field in rows:
            col_letter = get_column_letter(col_index)    
            ws['{}{}'.format(col_letter, row_index)].value = field
            col_index += 1
        row_index += 1
Ryan Ruscett
Ryan Ruscett
23,309 Points

We need to see the code where you are using ws.cell.

I can see if I do the following.

>>> dir(openpyxl.cell)
['Cell', 'ReadOnlyCell', 'WriteOnlyCell', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'absolute_import', 'cell', 'read_only', 'text']

VS

dir(openpyxl.utils)
['FORMULAE', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'absolute_coordinate', 'absolute_import', 'bound_dictionary', 'cell', 'cols_from_range', 'column_index_from_string', 'coordinate_from_string', 'coordinate_to_tuple', 'datetime', 'escape', 'exceptions', 'formulas', 'get_column_interval', 'get_column_letter', 'indexed_list', 'quote_sheetname', 'range_boundaries', 'range_to_tuple', 'rows_from_range', 'units']
>>> dir(openpyxl.utils.get_column_letter)

utils actually has get_column_letter, so the .cell which does exist in openpyxl, is not what you need. You found what you needed by using the openpyxl.utils.

Although, whatever method you are trying to use is deprecated. Meaning it doesn't exist anymore. That means that ws.cell doesn't work and using just cell.

I can see the following

dir(openpyxl.cell)
['Cell', 'ReadOnlyCell', 'WriteOnlyCell', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'absolute_import', 'cell', 'read_only', 'text']

I can see it has cell in it. If I look at cell

>>> dir(openpyxl.cell.cell)
['Cell', 'DEFAULT_COLUMN_WIDTH', 'DEFAULT_ROW_HEIGHT', 'ERROR_CODES', 'Hyperlink', 'ILLEGAL_CHARACTERS_RE', 'IllegalCharacterError', 'KNOWN_TYPES', 'NUMBER_REGEX', 'NUMERIC_TYPES', 'PERCENT_REGEX', 'STRING_TYPES', 'StyleableObject', 'TIME_REGEX', 'TIME_TYPES', 'WriteOnlyCell', '__builtins__', '__doc__', '__docformat__', '__file__', '__name__', '__package__', 'absolute_import', 'basestring', 'bytes', 'column_index_from_string', 'datetime', 'deprecated', 'from_excel', 'get_column_letter', 'is_date_format', 'numbers', 'points_to_pixels', 'range', 're', 'time_to_days', 'timedelta_to_days', 'to_excel', 'unicode']

It indeed has get_column_letter. as far as using ws, that would indicate that ws existed inside openpyxl somewhere. Whether it is in utils or cell but it does not. So using ws.cell wont work, but using cell by istself has the method you are trying to get. My suggestion is to head the warning, that says what you are doing is deprecated, meaning no longer exists, and use just cell. Although, without the code I can't be sure.

So this is the code.

import openpyxl
from openpyxl import Workbook
from openpyxl.writer.excel import ExcelWriter
from openpyxl.cell import get_column_letter
from s4v2 import *

def save_spreadsheet(filename, data_sample):
  wb = Workbook()
  ws = wb.active
  row_index = 1
  for rows in data_sample:
    col_index = 1

    for field in rows:
      col_letter = get_column_letter(col_index)
      ws.cell('{}{}'.format(col_letter, row_index)).value = field
      col_index += 1
    row_index += 1

  wb.save(filename)

kiton_ties = filter_col_by_string(data_from_csv, "brandName", "Kiton")
save_spreadsheet("_data/s4-kiton.xlsx", kiton_ties)

It works in Workspaces, but when I run it locally, I get this error;

Traceback (most recent call last):
  File "s4v3.py", line 4, in <module>
    from openpyxl.cell import get_column_letter
ImportError: cannot import name 'get_column_letter'

So that is why I changed

from openpyxl.cell import get_column_letter

to

from openpyxl.utils import get_column_letter

But now I get this error

/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/openpyxl/worksheet/worksheet.py:300: UserWarning: Using a coordinate with ws.cell is deprecated. Use ws[coordinate] instead
  warn("Using a coordinate with ws.cell is deprecated. Use ws[coordinate] instead")

But there are other problems I can see down the line. I'm using PyCharm locally and can see that the following;

import openpyxl
from openpyxl.writer.excel import ExcelWriter

aren't being used. I checked the pip list and have the right things installed. I'm a little confused.

Gonzalo Fernández
Gonzalo Fernández
9,537 Points

I'm having exactly the same issue as Philip

The function get_column_letter has been relocated in Openpyxl version 2.4 from openpyxl.cell to openpyxl.utils.

The current import is now: from openpyxl.utils import get_column_letter

If you want to do not know which version the end-use has, you can use the following code:

try:

  from openpyxl.cell import get_column_letter

except ImportError:

  from openpyxl.utils import get_column_letter