OpenPyXL always return None for a cell with hyperlink - xlrd

(My ultimate purpose is to append clickable cells to existing XLSX.)
I use the code below to extract the cell's display value and the hyperlink.
from openpyxl import load_workbook
xlsFile='hello.xlsx'
wbook = load_workbook(xlsFile)
wsheet1= wbook.get_sheet_by_name('mysheet')
cell1 = wsheet1.cell('A1')
print cell1.value
print cell1.hyperlink
print wsheet1['A1'].value
print wsheet1['A1'].hyperlink
But it returns the following things:
URL1
None
URL1
None
Why the hyperlink always None? I did add hyperlink manually for cell A1 and the hyperlink works in Excel 2013.

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.

Related

Openpyxl throws no errors but no changes to workbook are being made?

I've been trying to make a job finder using beautiful soup, and now want to move what I find into an excel file. But even when I try running the simplest changes to a worksheet, like in the code below, nothing actually changes and there are no errors.
I've tried copying tutorial code from online, as I assumed it's my simple mistake (which it probably is), but there is still no change.
import openpyxl
from openpyxl import Workbook
from openpyxl import load_workbook
wb = load_workbook("PracticeWorkbook.xlsx")
ws = wb.active
ws.cell(row=1, column=1,value='please work')
wb.save("PracticeWorkbook.xlsx")
Your code works for me, bearing in mind that because you're using load_workbook you need to already have 'PracticeWorkbook.xlsx' as an existing file.

Openpyxl not removing sheets completely from Excel Sheet

I was wondering if someone can explain why openpyxl is not removing sheet completely. I am using default openpyxl function. Thought this is deleting the sheet but the traces are still there in the developer tab. If you can help to fix this, I would be very grateful.
`remove_sheet(worksheet)`
While I am now using this alternative approach, but I beleive this is not efficient, since I first delete the sheet, then again use openpyxl to write it
xl = win32com.client.Dispatch('Excel.Application')
book = xl.Workbooks.Open(Filename = file, ReadOnly=False)
xl.Application.Run("delSheets.delSheets")
book.Save()
book.Close()
xl.Application.Quit()
del xl

Python Openpyxl return a sheet name which doesn't exist

In my excel file, I have only three worksheet: "Slot 14", "Data Display", and "Ctrl Value".
When I use openpyxl to load excel file, it returns other worksheet which doesn't exist: ['Slot 14', 'DETAILNO-14', 'DETAIL-14', 'PNO-14', 'DATA-14', 'Data Display', 'Ctrl Value']
Following is my code
filepath=r'D:\Users\chshiu\Desktop\filename.xlsx'
wb = openpyxl.load_workbook(filepath)
wb.get_sheet_names()
I don't think there is something wrong in my code. I am wondering maybe the problem is from excel file itself? I have VBA code inside the excel file.
More information:
I use Python3 in windows.
Because openpyxl cannot load xls file now so I save my original xls file into xlsx file.
It's possible that your file contains hidden sheets. Older versions of Excel use things called Macrosheets for some of the GUI controls. openpyxl just reports what it finds.

Is it possible to insert a worksheet into an existing workbook using Python?

The Problem
Creation of fancy reports using Pandas and Python.
Proposed Solution
Using a template xlsx file containing a template sheet nicely formatted with references to another pre-populated worksheet, delete the pre-populated sheet and insert the new worksheet from pandas. The template sheet will lose the links reverting to #REF so these will need to be renamed.
I tried:
import os
import xlrd, xlwt
import envconfig
swb1 = xlrd.open_workbook(os.path.join(envconfig.REPORT_WRITER_PATH,'TEMPLATE.xls'), on_demand=True, formatting_info=True)
swb2 = xlrd.open_workbook(os.path.join(envconfig.REPORT_WRITER_PATH,'REPORT.xls'), on_demand=True, formatting_info=True)
swb1s1 = swb1.sheet_by_name('Template')
swb2s1 = swb2.sheet_by_name('Report')
twb = xlwt.Workbook()
sheet1 = twb.add_sheet(swb1s1)
sheet2 = twb.add_sheet(swb2s1)
twb.save("python_spreadsheet.xls")
The above errors with:
sheet1 = twb.add_sheet(swb1s1)
File "C:\Users\pa003202\AppData\Local\Continuum\Anaconda3\lib\site-packages\xlwt\Workbook.py", line 366, in add_sheet
sheetname = sheetname.decode(self.encoding)
AttributeError: 'Sheet' object has no attribute 'decode'
sheetname = sheetname.decode(self.encoding)
AttributeError: 'Sheet' object has no attribute 'decode'
Is there a way to inject data from pandas into a workbook or to open a workbook and insert a sheet?
I solved this by creating a template as described and used the solution here:
Proposed Solution Using a template xlsx file containing a template sheet nicely formatted with references to another pre-populated worksheet, insert the new worksheet from pandas. The template sheet does not lose the links providing the inserted sheet has same name.
Solution:
Look at How to write to an existing excel file without overwriting data? and this works for the scenario.

Is there a way to programmatically insert formulas into a csv file using vb.net?

I need to add formulas to a CSV file that already exists. Is this possible to do this using VB.Net?
The idea is I already have a CSV file and I need one column to be populated in each cell with a custom formula. This has to be done programmatically because these files are being created dynamically.
Does anyone know how to do this? Thanks.
1,2,3,=SUM(A1:C1)
Surprised me when I tried it, but Excel will keep the formula.
You can even export formulas into a CSV by first displaying them on screen.
(Ctrl-`)
While I stand by that my original answer is technically correct, I have been getting a lot of downvotes on this. Apparently popular spreadsheet software such as Microsoft Excel, Open Office, Libre Office Calc will calculate formulas that are entered into a CSV file. However, I would still not recommend relying in this capability.
Original answer:
The CSV format does not support formulas. It is a plain text only format.
You can import formula's into excel via a text file using comma separated values. Just remember to make sure it is named with the suffix .txt.
Then do the import.
My example import ( Data table, From Text)
Column1,Column2,ResultColumn
1,2,=A2+B2
It imported and computed just fine
Are you generating the CSV file? If so, consider writing an actual Excel file. (I'm assuming you're importing into Excel, since you used the term "cell", which has no meaning in CSV.)
Here's a link on how to do it: Create Excel (.XLS and .XLSX) file from C#
If you aren't generating the CSV, and if all you want is to add a new, calculated value,(rather than a formula that will change dynamically as cells change values) you can do this easily enough by reading in the CSV file, parsing each line enough to get the values you need for your formula, calculating the result, and appending it (after a comma) to each line before writing the line out to a new file.
You could open the csv in Excel and then add the formulas to Excel and save back out to csv. You would do this by using the Microsoft Excel 11.0 Object Library. Then
dim wb as Excel.Workbook
dim exApp as New Excel.Application
dim exSheet as Excel.Worksheet
dim rowNum as integer = 1
wb = System.Runtime.InteropServices.Marshal.BindToMoniker(pathAndFileNameOfCSV)
exApp = wb.Parent
exApp.DisplayAlerts = False
exApp.AlertBeforeOverwriting = False
exSheet = exApp.ActiveWorkbook.Sheets.Item(1)
'do your functions in a loop here i.e.
exSheet.Range("A" & rowNum).Value = "=SUM($A$1:$D$4)"
rowNum += 1
wb.Close (True) 'closes and saves
Saving the workbook should convert the formulas back to the values when it is closed.
In Excel, to import formulas with commas the formula must be encapsulated by double quotes to prevent the formula being spread across cells. For example:
2,4,6,13,=sum(A1:C1),"=if(A1=C1,D1-A1,D1+A1)"
Another quirk of Excel is that if you have a string consisting entirely of numbers, you must present it as a formula to retain leading zeros. "00012345" imports as 12345, ignoring the quotes. To import as text, the .CSV file must present this as ="00012345".