Merged Cell Handling: side.style is None
All the time we run into customers with spreadsheets that trigger this stack trace on load_workbook
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/reader/excel.py", line 317, in load_workbook
reader.read()
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/reader/excel.py", line 282, in read
self.read_worksheets()
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/reader/excel.py", line 228, in read_worksheets
ws_parser.bind_all()
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/worksheet/_reader.py", line 443, in bind_all
self.bind_merged_cells()
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/worksheet/_reader.py", line 380, in bind_merged_cells
self.ws._clean_merge_range(mcr)
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/worksheet/worksheet.py", line 607, in _clean_merge_range
mcr.format()
File "/home/ubuntu/ph/venv/lib/python3.6/site-packages/openpyxl/worksheet/merge.py", line 109, in format
if side.style is None:
AttributeError 'NoneType' object has no attribute 'style'
This makes sense given that the following code in MergedCellRange isn't handling the None case.
def format(self):
names = ['top', 'left', 'right', 'bottom']
...
for name in names:
side = getattr(self.start_cell.border, name)
if side.style is None: # <--- Need None check here
continue # don't need to do anything if there is no border style
...
This implementation seems to imply that the border name
is not always going to be present, but the code that follows doesn't handle that case, hence the AttributeError.
We use openpyxl extensively in our application and after upgrading to 3.0.6 (from 2.6.1) this issue has started happening on a daily basis, so I think it is fair to assume that popular spreadsheet libraries are not always specifying this attribute; so I think it is worth guarding against this. Because this error happens during the load, it is very hard to work-around this in our application code.
I will try to get an example broken file, but it will take me some time to get one from a customer.