Unfortunately, it's a bug.
It's a bug in 2012...
Some related thread:
Extracting Hyperlinks From Excel (.xlsx) with Python
Some details of my experiment with hyperlink. I am using OpenPyXL 2.3.3
.
- I can add hyperlink to cells.
from openpyxl import load_workbook
xlsFile='hello.xlsx'
wbook = load_workbook(xlsFile)
wsheet1= wbook.get_sheet_by_name('mysheet')
cell1 = wsheet1.cell('A1')
cell1.hyperlink = r'http://www.example.com'
cell1.value=r'XXX'
wbook.save(xlsFile)
But I cannot load the XLSX file and read the hyperlink just as my question said.
And If I just load and re-save the XLSX file, ALL existing hyperlinks will be lost. Yeah!
from openpyxl import load_workbook
xlsFile='hello.xlsx'
wbook = load_workbook(xlsFile)
wbook.save(xlsFile)
A workaround!
Use the formula with OpenPyXL.
My purpose is to append clickable cells to existing XLSX file
. Since hyperlink
doesn't work. I use the formula =HYPERLINK(url, displayText)
instead. And luckily, the formula is not lost like previous experiment 3.
from openpyxl import load_workbook
xlsFile='hello.xlsx'
wbook = load_workbook(xlsFile)
wsheet1= wbook.get_sheet_by_name('mysheet')
cell1 = wsheet1.cell('A2')
cell1.value=r'=HYPERLINK("http://www.example.com","XXX")'
wbook.save(xlsFile)
Other (failed) options I tried:
I looked into the XlsxWriter. But it explicitly says it cannot modify existing XLSX file. So it cannot be used for appending.
I also looked into the xlrd/xlwt/xlutils
, unfortunately, if you want to edit an existing excel, you have to use xlrd to load it as a read-only workbook, and then use xlutils to convert(copy) it into a writable workbook. And BANG! during the copy, something will be lost which includes the HYPERLINK
formula. According to its doc string, this is a known limitation:
# Copyright (c) 2009-2012 Simplistix Ltd
#
# This Software is released under the MIT License:
# http://www.opensource.org/licenses/mit-license.html
# See license.txt for more details.
from xlutils.filter import process,XLRDReader,XLWTWriter
def copy(wb):
"""
Copy an :class:`xlrd.Book` into an :class:`xlwt.Workbook` preserving as much
information from the source object as possible.
See the :doc:`copy` documentation for an example.
"""
w = XLWTWriter()
process(
XLRDReader(wb,'unknown.xls'),
w
)
return w.output[0][1]
And also, xlwt doesn't support XLSX, only supports XLS. That's another reason I decided not to use it.