How to change sheet names without losing graph reference with openpyxl - python

I'm trying to write some code that will change sheet names in an excel file based on the data in another excel file.
At first this worked fine;
Sheet_names = "A","B","C","D"
wb = openpyxl.load_workbook(file_name.xlsx)
for i in range (1, len(Sheet_names)):
Name_change = wb["Sheet{}".format(str(i))]
wb.active = Name_change
Name_change.title = "{}".format(Sheet_names[i])
wb.save((file_name.xlsx))
wb.close()
But for some reason (I'm unsure what I've changed) a graph within the excel file isn't updating. So the data reference is still to Sheet1, Sheet2 etc.
Im also getting a warning message that there are external links - I guess it's assuming the sheet references are external? The excel file comes from a template that's copied across.
Changing it manually isn't an option, Is having Openpyxl recreate the graph for every sheet the only option?
Out of ideas, help!

Related

How to modify xml tables inside excel with openpyxl?

I'm trying fo fill a table (inside an xlsx template for Dynamics NAV) with openpyxl, but when I open the file with Excel it promts an alert: “We found a problem with some content in <Excel_filename>. Do you want us to try recovering the file as much as we can? If you trust the source of this workbook, then click Yes”
Then Excel 'repairs' the file and I can still see the data but the table /xl/tables/table1.xml is gone, and Navision can't accept the file.
This is my code in python:
import openpyxl
wb = openpyxl.load_workbook("data_source.xlsx", data_only=True)
sheet1 = wb.active
wb2 = openpyxl.load_workbook('template.xlsx')
sheet2 = wb2.active
filas = sheet1.max_row
for fila in range(3,filas):
sheet2["A"+ str(fila)] = sheet1["A"+ str(fila)].value
sheet2["B"+ str(fila)] = sheet1["B"+ str(fila)].value
sheet2["C"+ str(fila)] = "FRA"
sheet2["D"+ str(fila)] = "NAC"
wb2.save('tax1.xlsx')
wb2.close()
When I create a table from zero with the code they show in the openpyxl official site:
https://openpyxl.readthedocs.io/en/latest/worksheet_tables.html#creating-a-table
it works fine only if the table starts from row one (ref="A1:E5").
...but this template has a table that starts from row 3!
So when I try to make the table I need (ref="A3:D6") I get this: 'UserWarning: File may not be readable: column headings must be strings.' and as expected, I get the same alert and the same result when I open it with Excel.
Is there a way to modify/fill a table without corrupting the xlsx file?
or, like a workaround
Is there a way to create a table from A3 with no errors?
Thanks in advance

how to add the worksheet object in openpyxl to the new sheet of the existing xlsx document

I have done a lot of research and failed to solve this problem, so I am coming here to ask for help. I read the worksheet object from a file below,
sheet_2_workbook = openpyxl. load_workbook(sheet_2_path)
sheet_2 = sheet_2_workbook.worksheets\[0\]
As described in the title, I want to add it to the new sheet of the existing .xlsx document, how should I do it?
I tried to realize this as below, but the new document obtained by this method will lose some of the original formatting, including the cell background color and merged cells
old_wb = openpyxl. load_workbook(file_list[i])
old_sheet_name = old_wb. get_sheet_names()[0]
old_ws = old_wb[old_sheet_name]
ws2 = combined_wb.create_sheet(sheet_name)
for row in old_ws.values:
ws2.append(row)
I am sure that the worksheet object read in the file contains these formats, because the .xlsx document I dumped with the following code has the format mentioned above
sheet_2_workbook. save(filename = temp_save_path)
How I would go about your task of adding a worksheet object to a new sheet in an existing Excel document using openpyxl:
Import the openpyxl module
Load the existing Excel document using the load_workbook() function
Create a new sheet using the create_sheet() method of the Workbook object
Alternatively, you can specify the name of the new sheet as a string when calling the create_sheet() method
Save changes using the save() method
(To preserve the formatting you can use the copy_worksheet() to create a copy of the original worksheet and add it to the workbook)
import openpyxl
workbook = openpyxl.load_workbook('existing_document.xlsx')
sheet_2_workbook = openpyxl.load_workbook(sheet_2_path)
sheet_2 = sheet_2_workbook.worksheets[0]
new_sheet = workbook.copy_worksheet(sheet_2)
// Alternatively, you can specify the name of the new sheet as a string
// new_sheet = workbook.copy_worksheet(sheet_2, 'Sheet2')
workbook.save('existing_document.xlsx')

Openpyxl don't preserve formatting

I have an excel file that i want to use as template, what i need is just change the values of some cells, and save it as another excel file. The problem is that when i save it the formatting, style and some date values are changed
from openpyxl import load_workbook
wb = load_workbook("test.xlsx")
ws = wb["RDO"]
ws["B8"].value = "MAI MAN"
wb.save("new.xlsx")
The old file:
The new one:
As you can see the borders and date fields were changed.
I was thinking in just unzip the excel and modify the xml files, then zip it back, but this approach has a problem. I will need to make a copy of some worksheets, so i tought i should be ok in just copy and paste the sheet.xml file and change the workbook.xml file to add this new sheet, but when i do this all the cells are cleared which is weird because when i copy the sheet in the excel program the output sheet file it's exactly the same as the original
I would like some simple solution if possible, maybe some other library or a fix for this xml sheet problem

Openpyxl not writing to my Excel spreadsheet

I am trying to write to an Excel worksheet but the code does not do anything. I have the file name right and it correctly detects the only sheet ('Sheet1') but when I try to write to a cell nothing happens. I am running Microsoft Office 365 if that matters.
I have tried
wb = openpyxl.load_workbook('Spendings 2019.xlsx')
ws = wb.active
ws['B3'] = 4
This does not change the Excel file at all when run.
Did you read the docs? You need
print(cell.value)
As explained https://openpyxl.readthedocs.io/en/stable/usage.html
Also, if you are making changes to the spreadsheet, you need to save it

xlsxwriter: is there a way to open an existing worksheet in my workbook?

I'm able to open my pre-existing workbook, but I don't see any way to open pre-existing worksheets within that workbook. Is there any way to do this?
You cannot append to an existing xlsx file with xlsxwriter.
There is a module called openpyxl which allows you to read and write to preexisting excel file, but I am sure that the method to do so involves reading from the excel file, storing all the information somehow (database or arrays), and then rewriting when you call workbook.close() which will then write all of the information to your xlsx file.
Similarly, you can use a method of your own to "append" to xlsx documents. I recently had to append to a xlsx file because I had a lot of different tests in which I had GPS data coming in to a main worksheet, and then I had to append a new sheet each time a test started as well. The only way I could get around this without openpyxl was to read the excel file with xlrd and then run through the rows and columns...
i.e.
cells = []
for row in range(sheet.nrows):
cells.append([])
for col in range(sheet.ncols):
cells[row].append(workbook.cell(row, col).value)
You don't need arrays, though. For example, this works perfectly fine:
import xlrd
import xlsxwriter
from os.path import expanduser
home = expanduser("~")
# this writes test data to an excel file
wb = xlsxwriter.Workbook("{}/Desktop/test.xlsx".format(home))
sheet1 = wb.add_worksheet()
for row in range(10):
for col in range(20):
sheet1.write(row, col, "test ({}, {})".format(row, col))
wb.close()
# open the file for reading
wbRD = xlrd.open_workbook("{}/Desktop/test.xlsx".format(home))
sheets = wbRD.sheets()
# open the same file for writing (just don't write yet)
wb = xlsxwriter.Workbook("{}/Desktop/test.xlsx".format(home))
# run through the sheets and store sheets in workbook
# this still doesn't write to the file yet
for sheet in sheets: # write data from old file
newSheet = wb.add_worksheet(sheet.name)
for row in range(sheet.nrows):
for col in range(sheet.ncols):
newSheet.write(row, col, sheet.cell(row, col).value)
for row in range(10, 20): # write NEW data
for col in range(20):
newSheet.write(row, col, "test ({}, {})".format(row, col))
wb.close() # THIS writes
However, I found that it was easier to read the data and store into a 2-dimensional array because I was manipulating the data and was receiving input over and over again and did not want to write to the excel file until it the test was over (which you could just as easily do with xlsxwriter since that is probably what they do anyway until you call .close()).
After searching a bit about the method to open the existing sheet in xlxs, I discovered
existingWorksheet = wb.get_worksheet_by_name('Your Worksheet name goes here...')
existingWorksheet.write_row(0,0,'xyz')
You can now append/write any data to the open worksheet.
You can use the workbook.get_worksheet_by_name() feature:
https://xlsxwriter.readthedocs.io/workbook.html#get_worksheet_by_name
According to https://xlsxwriter.readthedocs.io/changes.html the feature has been added on May 13, 2016.
"Release 0.8.7 - May 13 2016
-Fix for issue when inserting read-only images on Windows. Issue #352.
-Added get_worksheet_by_name() method to allow the retrieval of a worksheet from a workbook via its name.
-Fixed issue where internal file creation and modification dates were in the local timezone instead of UTC."
Although it is mentioned in the last two answers with it's documentation link, and from the documentation it seems indeed there are new methods to work with the "worksheets", I couldn't able to find this methods in the latest package of "xlsxwriter==3.0.3"
"xlrd" has removed support for anything other than xls files now.
Hence I was able to workout with "openpyxl" this gives you the expected functionality as mentioned in the first answer above.

Categories

Resources