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

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.

Related

VBA - Copying cells across Workbooks

I'm writing a VBA program that changes the visuals of an excel database. At the end, I need to add a "header" (5 rows of text) at the top. The problem is, I cannot insert the text with VBA, since it contains letters (for ex. á, é...) that aren't compatible with VBA, I need to insert that text from another excel file.
The macro I have is stored in a standalone excel workbook, that also contains the cells of the header I need to copy into my database. The problem is, the name of the excel files I am working with varies. Is there a way I could switch between those 2 files and copy cells across them. Can I store the name of the excel file I am working with and later use it in the VBA code to switch between the workbooks?
Not sure if this 100% answers your question but hope it helps, you can open and store both workbooks as objects using:
Dim wb as Workbook, wb2 as Workbook
Set wb = Workbooks.Open("C:\User\Sample_Workbook_File_Path_1.xlsx")
Set wb2 = Workbooks.Open("C:\User\Sample_Workbook_File_Path_2.xlsx")
From there you can call values from either workbook using things like:
'to get the second workbooks excel file name into a worksheet: "Sample_Workbook_2"
wb.Worksheets("Sample_Worksheet").Range("A1").Value = wb2.Name
'to copy files
wb2.Worksheets("Second_Workbooks_Worksheet").Range("A2:A100").Copy _
wb.Worksheets("Sample_Worksheet").Range("A2")
'Alternatively you can store the entire workbooks path name instead of the file name using:
wb.Worksheets("Sample_Worksheet").Range("A1").Value = wb2.Path

OpenPyXL always return None for a cell with hyperlink

(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.

openpyxl data_only gives only a none answer when storing a variable

So basically what I am trying to do is read in some input variables from an excel workbook and write them into some Output Model cells. Then I save the workbook to try to update the data in the Output Model. Since my Output Model cells are formulas I try to reload the workbook as a read data_only and then grab those cells and store them on a separate sheet. Then I save the workbook one more time.
The problem is the values I try to grab (LS, Sales, TPLH) in the data_only loaded workbook reads out as none instead of the values that I need. I eventually want to make this into a loop to iterate over a bunch of input variables, but I wanted to try it with just one set to begin with.
If anyone knows of a better way to do this or what I am doing wrong please let me know! I appreciate any and all feedback.
Here is my code:
from openpyxl import load_workbook
wb2 = load_workbook("Z:\\PythonFiles\\testexcel.xlsx")
sh2 = wb2.get_sheet_by_name("Output Model")
sh= wb2.get_sheet_by_name('OptimizationData')
ForeCast = sh.cell(row=3, column=2).value
sh2.cell(row=3, column=6).value=ForeCast
wb2.save("Z:\\PythonFiles\\testexcel.xlsx")
wb = load_workbook("Z:\\PythonFiles\\testexcel.xlsx", data_only =True)
sh3 = wb.get_sheet_by_name("Output Model")
sh4 = wb.get_sheet_by_name("OptimizationData")
LS=sh3.cell(row=11, column=3).value
Sales = sh3.cell(row=12, column=3).value
TPLH = sh3.cell(row=13, column=3).value
sh4.cell(row=3, column=7).value=LS
sh4.cell(row=3, column=8).value=Sales
sh4.cell(row=3, column=9).value=TPLH
wb.save("Z:\\PythonFiles\\testexcel.xlsx")
Openpyxl will never calculate the result of a formula. It is entirely dependent upon another application having done that. It also means that such values are stripped from a workbook when it is passed through openpyxl. This happens as soon as you save wb2. If you want to access those values then you need to open wb in data-only mode first.

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".

How to open a file in an active workbook? VB.NET 2008

I have a program that filters data and then outputs it to a tabg delimited file. I then use Excel Interop to open this file in Excel because directly outputting to a worksheet takes too long. So currently I am using this code:
AD.DF.WriteToFile(vbTab)
Dim WB As Workbook = ExcelApp.Workbooks.Open(AD.DF.DatafileInfo.WriteToFileLocation)
ExcelApp.Visible = True
The first line takes the filtered data and outputs to a tab delimited file. The second opens that same file in a new workbook in Excel. And obviously the third makes Excel visible. Here is my problem though: right now when this code is run there are two open workbooks. I already have an active workbook and I would just like to open this file to that workbook.
If this is possible, how do I do it?
Thank you.
Look at the GetObject function.
Dim MyXL As Object
MyXL = GetObject(, "Excel.Application")
should get you a reference to the currently running instance of Excel.
In the code I created an object that is an Excel Workbook. I then set the created workbook as the ExcelApp.ActiveWorkbook. Then I was able to open the file without another workbook being created.