Openpyxl created excel file with table causes file that requires recovery error - python-3.x

I have been testing adding a table to a worksheet using openpyxl, but I get the error below when I try to open it. The file opens, but the formatting isn't correct. After hitting recover, excel reports that there was an issue with the table xml. Is there a workaround/fix for this?
The code I'm using:
import openpyxl
from openpyxl import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
xl_file_name = "new_test.xlsx"
wb = Workbook()
ws = wb.worksheets[0]
ws.title = "Table_Sheet"
headers = ["header1","header2","header3"]
for col in range(1,len(headers)+1):
for row in range(1,5):
if row == 1:
ws.cell(row,col).value = headers[col-1]
else:
ws.cell(row,col).value = str(row)
tbl = Table(displayName="Tbl1",ref="A1:C4")
style = TableStyleInfo(name="TableStyleMedium9", showFirstColumn=False, showLastColumn=False, showRowStripes=True, showColumnStripes=True)
tbl.tableStyleInfo = style
ws.add_table(tbl)
wb.save("new_test.xlsx")

Your name for the table is causing the problem. Run the same code with displayName="Tbl" or displayName="Tbl_1" instead, and you'll see it works fine. I'm not 100% sure, but I think the cause of the issue is that the name you give conflicts with the formatting for a possible cell reference of TBL1.

For me the following worked:
Change the Workbook as you wish (only Data no formatting)
Save the Workbook (If you would try to open it here it will display the error message)
Close the Workbook
Open the Workbook again (I think here Excel fixes the issue automatically)
Insert necessary formatting commands
Save the workbook
Close the Workbook
Or, as code:
import openpyxl
workbook = openpyxl.load_workbook(Source_Path)
##your code appending and deleting values - which I think sometimes causes the errors
workbook.save(Destination_Path)
workbook.close
#Now open it again
workbook = openpyxl.load_workbook(Destination_Path)
#Your Code to format
workbook.save(Destination_Path)
workbook.close
Now you should be able to open the Excel file without an error.

I've had the same error message.
I was creating tables with numbers at the start of the name, so I changed that code to add t_ at the beginning, so
table_name = "112MHZ_data"
became
table_name = "t_112MHZ_data"
And that solved it for me.

Related

Cannot find a way to replace last row inside excel files

I am fighting with an excel file in which I would simple delete the last row.
I am using XLSXWRITER, and I tried several ways, but nothing is working. I am doing something wrong (maybe I have to take a break).
I tried
worksheet.write_blank(row, col, None)
but I found out that xlsxwriter cannot replace an old row with a new one. So if I use write_blank() to write on on an existing row, it won't work.
Could you please help me? I am looping through several XLSX file, open them and replace the last row with a blank.
Many thanks!
So, I found a way to achieve this step on my own.
Basically I wasn't able to do this with XLSXWRITER library, so I loop through my excel files opening them with OPENPYXL.
import openpyxl
from openpyxl import Workbook
## look for all excel files needed
filepath = r"C:\Users\name\Desktop\folder\folder\folder"
xlsxfiles = glob.glob(filepath + r"\**\*.xlsx")
## for each excel file open the workbook and spreadsheet
for file in xlsxfiles:
wb = openpyxl.load_workbook(file)
ws = wb.active
## for each excel file, count the maximum number of rows and store the value in last_row variable
last_row = ws.max_row
print("MAX NUMER OF ROW: ", last_row)
## replace the last row with None value
ws.cell(last_row, 1).value = None
## save each excel file
wb.save(file)
My need was quite specific but I think it can be easily modify to different purposes.

Using win32.com to copy excel worksheet throws Microsoft Excel copy paste error

When I use win32.com to open an excel file and paste the sheet into another excel file i get a copy paste error.
import win32com.client
import os
excel = win32com.client.Dispatch("Excel.Application")
w = excel.Workbooks.Open(os.path.join(os.getcwd(), "my_excel_file.xlsx"))
w.Sheets.Copy(wb.Sheets(1))
wb.SaveAs(os.path.join(os.getcwd(), "new_excel_file.xlsx"))
excel.Application.Quit()
This is the error I get:
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Microsoft Excel', 'Excel cannot insert the sheets into the destination workbook, because it contains fewer rows and columns than the source workbook. To move or copy the data to the destination workbook, you can select the data, and then use the Copy and Paste commands to insert it into the sheets of another workbook.', 'xlmain11.chm', 0, -2146827284), None)
I was able to reproduce your error but it was not from the code you submitted. I changed your original code to reproduce the error. Additionally, there were missing information such as the "wb" variable was undefined but your issue is an Excel issue and not related to python or the Windows COM library. The following snippet of your error describes what your excel error is and the resources below that explains how you can get it.
'Excel cannot insert the sheets into the destination workbook, because it
contains fewer rows and columns than the source workbook. To move or copy
the data to the destination workbook, you can select the data, and then use
the Copy and Paste commands to insert it into the sheets of another workbook'
https://answers.microsoft.com/en-us/msoffice/forum/all/not-able-to-movecopy-the-excel-worksheet-with/bb349e56-7ab1-47c9-9b2b-35ad7ca31cb8
https://answers.microsoft.com/en-us/msoffice/forum/all/excel-help/3d549b4c-c1d3-42ac-ab02-d0373ce78bf4
In summary, its an issue if you take Microsoft Excel 2003 version and try to save it into a 2007 version.
Simply setting "wb.Sheets.Copy(w.Sheets(1))" to "w.Sheets.Copy(wb.Sheets(1))" will solve your problem. See code below:
import win32com.client
import os
try:
excel = win32com.client.Dispatch("Excel.Application")
wb = excel.Workbooks.Add()
w = excel.Workbooks.Open(os.path.join(os.getcwd(), "my_excel_file.xlsx"))
w.Sheets.Copy(wb.Sheets(1))
wb.SaveAs(os.path.join(os.getcwd(), "new_excel_file.xlsx"))
finally:
# Release resources
wb = None
w = None
excel.Application.Quit()

how to update a portion of existing excel sheet with filtered dataframe?

I have an excel workbook with several sheets. I need to read a portion from one of the sheets, get a filtered dataframe and write a single value from that filtered dataframe to a specific cell in the same sheet. What is the best way to accomplish this, ideally without opening the excel workbook? I need to run this on linux, so can't use xlwings. I don't want to write the entire sheet, but just a selected cell/offset inside it. I tried the following to write to the existing sheet, but doesn't seem to work for me (no update occurs at the desired cell):
with pd.ExcelWriter('test.xlsx', engine='openpyxl') as writer:
writer.book = load_workbook('test.xlsx')
df_filtered.to_excel(writer, 'Sheet_Name', columns=['CS'], startrow=638, startcol=96)
Any tips would be helpful. Thanks.
If you're just writing a single cell the below should suffice.
import pandas as pd
import openpyxl
df = pd.DataFrame(data=[1,2,3], columns=['col'])
filtered_dataframe = df[df.col == 1].values[0][0]
filename = 'test.xlsx'
wb = openpyxl.load_workbook(filename)
wb['Sheet1'].cell(column=1, row=2, value=filtered_dataframe)
wb.save(filename)
I believe your issue was that you never called the save method of the writer.

openpyxl save does not work

I create an excel workbook:
wb = Workbook()
create and populate some worksheets:
active_sheet = wb.copy_worksheet(temp_sheet)
active_sheet.title = 'Availabilty'
for i in range(len(np_S_Availability)):
for j in range(len(np_S_Availability[0])):
active_sheet.cell(column=j+2, row=i+2, value=np_S_Availability[i, j])
and then save it:
wb.save(destinf)
But at this point it just hangs. No response, no error messages that I can detect. Any ideas perhaps?
Paul
I think the take home here is to use the write_only=True option. These are big arrays resulting in workbooks in excess of 10MB. I have changed the code to allow for this and now all works fine. Thanks.

How to add more than 3 sheets to an excel workbook from within MATLAB

How do I add more sheets to an excel workbook from within matlab?
I set up the workbook like so (based on code I got from someone else's post in this forum):
%# create Excel COM Server
Excel = actxserver('Excel.Application');
Excel.Visible = true;
%# create new XLS file
wb = Excel.Workbooks.Add();
wsheet=1;
wb.Sheets.Item(wsheet).Activate();
That's fine. Then later on inside the loop I open a new sheet after so many loops:
...
if loop==sheetlimit,
wsheet=wsheet+1;
wb.Sheets.Item(wsheet).Activate();
end
This works up to sheet 3. But when wsheet=4 I get this error message:
??? Invoke Error, Dispatch Exception: Invalid index.
Error in ==> filename at 97
wb.Sheets.Item(wsheet).Activate();
Appreciate any help. Thanks.
I don't know Matlab but I would be surprised if wb.Sheets.Item(wsheet).Activate(); is actually adding any new worksheets. Most likely it is selecting / activating each worksheet in your wb workbook and your default Excel template has three worksheets. Hence why it errors when it gets to more than three.
Something like this might add a new Excel worksheet:
wb.sheets.Add();
Aargh - comment formatting completely messed up - I'll re-enter it as an new answer
Yes wb.sheets.Add(); will work. You can query the available methods of an interface like this:
methods(wb.sheets)
which gives:
Methods for class Interface.000208D7_0000_0000_C000_000000000046:
Add FillAcrossSheets PrintOut addproperty events loadobj set
Copy Item PrintPreview delete get release
Delete Move Select deleteproperty invoke saveobj

Resources