Apologies for no coding provided, this is really a generic question.
I'm using Python xlwings library, and trying to copy a sheet from one workbook to another new workbook, then hard-code the sheet in the newly created workbook. Effectively same as "Copy / Paste Values and source formatting".
I wasn't able to find any documentation on this, and thank you in advance for your help!
edit: someone mentioned that I should include an example. Here it is but it's kind hard to show the format in an Excel file. the following code will copy/paste "sht" into a new workbook but the "new_sht" will contain formulas. I'm trying to hard-code all the values while preserving the number format (eg. with thousands separator, percentage sign, etc)
import xlwings as xw
wb = xw.Book('example1.xlsx')
sht = wb.sheets['sheet1']
new_wb = xw.Book()
new_sht = new_wb.sheets[0]
sht.api.Copy(Before = new_sht.api)
Answering my own question as I just figured out what I wanted to accomplish.
The following code will hardcode the values while preserve the formatting, since it's essentially pasting value-only to an already formatted area.
new_sht.range('A1:C10').value = new_sht.range('A1:C10').value
Related
Please, if you are not able to provide a constructive solution, do not mark it as duplicate, because I have not found any solution and it says very little about your interest in providing some help.
Excel rejects the formula, but the other strings in other cells are allowed. I'm using the names of the formulas in English and have tried commas and semicolons with the same result.
The formula consists of a markdown template and has several nested conditions.
Part of the code is:
wb = Workbook()
sheet= wb.active
l=str(sheet.max_row+1)
formula='=CONCATENATE("**"&{}&"**"&CHAR(10)&CHAR(10)&"- **Ponente:** "&{}&CHAR(10)&"- **Fuente:** "&{};IF(EXACT({};"");"";CHAR(10)&"- **ID:** "&{});CHAR(10)&"- **Web:** "&{}&CHAR(10)&"- **Idioma:** "&{}&CHAR(10)&"- **Etiquetas:** "&{};IF(EXACT({};"");;CHAR(10)&"- **Fecha:** "&{});IF(EXACT({};"");;CHAR(10)&"- **Notas:** "&{}))'.format("A"+l,"B"+l,"C"+l,"D"+l,"D"+l,"E"+l,"H"+l,"G"+l,"F"+l,"F"+l,"I"+l,"I"+l)
print (formula)
data={
"TÃtulo":[titulo],
"Autor":[profesor],
"Fuente":[plataforma],
"ID":[id],
"Web":[url],
"Fecha":[fecha_esp],
"Etiquetas":[etiquetas],
"Idioma":[idioma],
"Notas":[notas],
"Plantilla":[formula]
}
dataframe_pandas = pd.DataFrame(data)
for x in dataframe_to_rows(dataframe_pandas, index=False, header=False):
sheet.append(x)
wb.save(filename)
The console output shows the following formula:
=CONCATENATE("**"&A2&"**"&CHAR(10)&CHAR(10)&"- **Ponente:** "&B2&CHAR(10)&"- **Fuente:** "&C2;IF(EXACT(D2;"");"";CHAR(10)&"- **ID:** "&D2);CHAR(10)&"- **Web:** "&E2&CHAR(10)&"- **Idioma:** "&H2&CHAR(10)&"- **Etiquetas:** "&G2;IF(EXACT(F2;"");;CHAR(10)&"- **Fecha:** "&F2);IF(EXACT(I2;"");;CHAR(10)&"- **Notas:** "&I2))
This formula is rejected by Excel, but if I copy and paste it in the excel field, I have no problem.
Recover workbook: https://i.stack.imgur.com/1OL7T.png
Plantilla field rejected: https://i.stack.imgur.com/Ztcpx.png
Paste formula in field and run: https://i.stack.imgur.com/whlOA.png
So, what is the problem?
Update
Previously this issue was published, but it was marked as duplicated without even trying to help. Now, I am very grateful to the three people who responded.
The problem was the formula in python. I replaced all semicolons, but I must have had some typo that I corrected later and never tried again. But with the evidence provided I tried once more and it worked
Try to replace your semicolons with , in the formula and check.
I tried manually in libreoffice and compared it with auto generated formula. Both differs in , as it automatically changed ; to ,. Then I replaced ; with , in the python file. and the auto generated excel is fine.
You can try with ExcelWriter
from pandas import ExcelWriter
writer = pd.ExcelWriter('output.xlsx')
# write dataframe to excel
df_marks.to_excel(writer)
# save the excel
writer.save()
writer.close()
The Problem:
Open a ListObject (excel table) of an Excel file from y python environment.
The why:
There are multiple solutions to open an excel file in python. Starting with pandas:
import pandas as pd
mysheetName="sheet1"
df = pd.read_excel(io=file_name, sheet_name=mysheetName)
This will pass the sheet1 into a pandas data frame.
So far so good.
Other more detailed solution is using specific libraries. This one being a code of a stack overflow question.
from openpyxl import load_workbook
wb2 = load_workbook('test.xlsx')
print wb2.get_sheet_names()
['Sheet2', 'New Title', 'Sheet1']
worksheet1 = wb2['Sheet1'] # one way to load a worksheet
worksheet2 = wb2.get_sheet_by_name('Sheet2') # another way to load a worksheet
print(worksheet1['D18'].value)
So far so good as well.
BUT:
If you have a ListObject (excel table) in a sheet I did not find any way to access the data of the Listobject.
ListObjects are often used by a bit more advance users of Excel; above all when programming macros in VBA. There are very convenient and could be seen as the equivalent of a pandas dataframe in Excel. Having a bridge between Excel Listobject and a pandas data frame seems like super logical. Nevertheless I did not find so far any solution, library or workaround for doing that.
The question.
Does anyone know about some python lybrary/solution to directly extract Listobjects form Excel sheets?.
NOTE1: Not nice solution
Of course knowing the "placement" of the Listobject it is possible to refer to the start and last cell, but this is a really bad solution because does not allow you to modify the Listobject in the excel file (the python would have to be modified straight away). As soon as the placement of the ListObject changes, or the listobject itself gets bigger, the python code would be broken.
NOTE2: My current solution:
I export the listObject from excel (with a macro) into a JSON file and read it from python. But the extra work is obvious. VBA code, extra file etc etc.
Last comment: If someone is interested about this issue but still don't have a clue what is a ListObject in excel here click and see here:
James is right:
https://openpyxl.readthedocs.io/en/stable/worksheet_tables.html
https://openpyxl.readthedocs.io/en/stable/api/openpyxl.worksheet.table.html
There is a class in openpyxl to read tables. Also by id:
class openpyxl.worksheet.table.Table(id=1,...
id=1 would mean the first table of the worksheet.
Remember always that ListObjects in Excel are called Tables. Thats weird (as oft with VBA). If you work with VBA you might forget that the ListObject=Table.
With xlwings is also possible. The API is a bit different:
import xlwings as xw
wb = xw.Workbook.active()
xw.Range('TableName[ColumnName]').value
Or to get the column including header and Total row, you could do:
xw.Range('TableName[[#All], [ColumnName]]').value
is there a way to get the real value instead of the formula of a cell printed out with openpyxl library?
I read a lot about that, according to stackoverflow the openpyxl library doesnt offer this option which is bad.
The only solution which I found here was to manually open the excel file and save the formulas as hard coded values.
I am trying to automate my processes and dont want to do anything manually.
import openpyxl
template = openpyxl.load_workbook('import_spendesk_datev.xlsx') #Add file name
temp_sheet = template['Import']
print(temp_sheet.cell(row=2,column=13).internal_value)
I expect that I can print out the real value of the cell instead of the formula.
Thanks a lot for any help. Maybe another python library for manipulating excel which offers this?
You can try xlrd.
I have a single value in an excel workbook that uses a formula RANDBETWEEN:
Code to grab the value:
import xlrd
from xlrd import open_workbook, cellname
book = open_workbook(r'path_to_excel\test.xlsx')
sheet = book.sheet_by_name("Sheet1")
print(sheet.cell(0,0).value)
65.0
I am new to Python and working on a project that I could use some help on. So I am trying to modify an existing excel workbook in order to compare stock data. Luckily, there was a program online that retrieved all the data I need and I have successful been able to pull the data and write the data into a new excel file. However, the goal is to pull the data and put it into an existing excel file. Furthermore, I need to overwrite the cell values in the existing file. I believe xlwings is able to do this and I think my code is on the write track, but I ran into an unexpected error. The error I get is:
com_error: (-2147023174, 'The RPC server is unavailable.', None, None)
I was wondering if anyone knew why this error came up? Also, does anyone know how to fix it? Is it fixable? Is my code wrong? Any help or guidance is appreciated. Thank you.
import good_morning as gm
import pandas as pd
import xlwings as xw
#import income statement, balance sheet, and cash flow of AAPL
fd = gm.FinancialsDownloader()
fd_frames = fd.download('AAPL')
#Creates a DataFrame for only the balance sheet
df1 = pd.DataFrame(list(fd_frames.values())[0])
#connects to workbook I want to modify
wb = xw.Book(r'C:/Users/vince/OneDrive/Documents/Python/Project/spreadsheet.xlsm')
#sheet I would like to modify
sht = wb.sheets[1]
#modifies & overwrites values in my spreadsheet
sht.range('M6').value = df1
This issue is discussed in https://github.com/xlwings/xlwings/issues/633. It is apparently related to an Excel glitch. A workaround is provided on that github page. Also, the xlwings documentation mentions that you might get an error (not clear if it's this one) if the workbook is already open in Excel.
I am trying to create an Excel workbook with two worksheets - i used xlsxwriter to enter data on the first worksheet, then rank that data on the second worksheet. When i open the workbook, the ranks have an Excel name? error. If i click on the end of the formula in the edit bar, it calculates correctly, so i dont think the formula is incorrect.. i suspect it may be some sort of ordering of operations? My excel sheet is set to automatically calculate formulas... the only similar problem i could find on the web was xlsxwriter: add formula with other sheet in it, but i cannot tell what the solution was (if it actually turned out to be something other than a french to english issue)
Here is a simplified version of my code
import xlsxwriter
wb = xlsxwriter.Workbook('C:\Python33\ScoreTry.xlsx')
ws1 = wb.add_worksheet('RawScores')
ws2 = wb.add_worksheet('RankScores')
ws1.write(0,0,32)
ws1.write(1,0,39)
ws1.write(2,0,15)
for i in range (0,3):
x = 'IF(isblank(RawScores!A'+str(i+1)+'),"",RANK.AVG(RawScores!A'+str(i+1)+',RawScores!A$1:A$100,0))'
ws2.write_formula(i,0,x)
wb.close()
my RankScores worksheet opesn with three #NAME? errors instead of ranks until i click enter on each. Any ideas much appreciated!
RANK.AVG() is a function that was added as an "extension" after the original XLSX file format specification. There is a list of these functions defined in the Microsoft documentation.
So, although the formula is displayed as RANK.AVG() it is stored in the file as _xlfn.RANK.AVG() (as listed in the previous doc).
If you change your formula to use the prefixed version of the function it should work.
This is a kludgy but currently unavoidable workaround (without some equally kludgey workaround in the module). For what it is worth it is documented in the write_formula() section of the docs.