I'm making a Python program that opens, edits, and saves xlsm Excel files with VBA. However, in this line wb.save(filename = 'b.xlsm'), the following error is occurring: lxml.etree.XMLSyntaxError: Opening and ending tag mismatch: br line 19 and b, line 20, column 12.
I must edit and save the xlsm file.
import openpyxl
wb = openpyxl.load_workbook(filename = 'a.xlsm', keep_vba = True)
ws = wb.active
ws.cell(1,1).value = 'test'
print(ws.cell(1,1).value)
wb.save(filename = 'b.xlsm')
Gonna guess something is broken in another part of your code, as this aren't 20 lines and the code on itself runs just fine on my machine :) Based on the error code, you are just missing a bracket somewhere
Related
I'm currently trying to do the following:
Open up an .xml file that's already in spreadsheet format with Excel
Save the .xml file as .xlsx without corrupting the file
Other options that I can take via Python are:
Convert the .xml to .xlsx
Copy specific columns (A1:AC6000) to another Excel workbook
Import an XML file directly in an Excel workbook.
I failed at all of them and can't think of a different way so here I am asking for help. My latest code is here:
# importing openpyxl module
import openpyxl as xl;
# opening the source excel file
file = 'C:\\Users\\ddejean\\Desktop\\HESKlogin\\Downloads\\data.xlsx'
wb1 = xl.load_workbook(file)
ws1 = wb1['Sheet1']
# opening the destination excel file
filename1 = 'C:\\Users\\ddejean\\Desktop\\HESKlogin\\Downloads\\updated.xlsx'
wb2 = xl.load_workbook(filename1)
ws2 = wb2['Sheet1']
# calculate total number of rows and
# columns in source excel file
mr = ws1.max_row
mc = ws1.max_column
# copying the cell values from source
# excel file to destination excel file
for i in range (1, mr + 1):
for j in range (1, mc + 1):
# reading cell value from source excel file
c = ws1.cell(row = i, column = j)
# writing the read value to destination excel file
ws2.cell(row = i, column = j).value = c.value
# saving the destination excel file
wb2.save(filename1)
I also tried changing the format of the file which ultimately corrupted the file:
A = r"C:\\Users\\ddejean\\Desktop\\HESKlogin\\Downloads\\data.xml"
pre, ext = os.path.splitext(A)
B = os.rename(A, pre + ".xlsx")
I tried importing the file into Excel which was terrible since none of the data in xml have properly name attributes to differentiate the data. I also tried calling a macro, but I get an error with each macro on my network, so I disposed of that alternative.
Any assistance you can give would be much appreciated! I also think it's important to say that I'm a noob.
This works for me :)
import os
import win32com.client as win32
import requests as r
import pandas as pd
hesk = "C:\\Users\\ddejean\\Desktop\\TEST\\hesk.xml"
folder = "C:\\Users\\ddejean\\Desktop\\TEST"
output = "C:\\Users\\ddejean\\Desktop\\TEST\\output.csv"
cd = os.path.dirname(os.path.abspath(folder))
xmlfile = os.path.join(cd, hesk)
csvfile = os.path.join(cd, output)
# EXCEL COM TO SAVE EXCEL XML AS CSV
if os.path.exists(csvfile):
os.remove(csvfile)
try:
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.OpenXML(xmlfile)
wb.SaveAs(csvfile, 6)
wb.Close(True)
except Exception as e:
print(e)
finally:
# RELEASES RESOURCES
wb = None
excel = None
I used xlwings to open excel workbook. It worked fine up to last month. But today, when I run the same code, it opened my worksheet but convert my worksheet name into lowercase.
Anybody know why is that? And how can I keep my original captalization?
I am using windows 10.
Example, when I run below code, the ABC.xlsx automatically converted abc.xlsx by xlwings.
import xlwings as xw
fullPath = ''\\\\xxx\\xxx\\ABC.xlsx'
psw = '123'
wb = xw.Book(fullPath, password = psw)
I had the same issue and I am not sure why it does that (I think it only happens to protected workbooks). An easy fix is renaming the file again as follows:
import os
old_file_name = os.path.split(fullPath)[0] +'\\' + os.path.split(fullPath)[1].lower()
new_file_name = fullPath
os.rename(old_file_name, new_file_name)
This code assumes that your path and file are saved under fullPath.
I have a pandas dataframe df. I then save it as an excel file Report.xlsm and then I add VBA code to filter this data.
The code runs well. However, when I execute the VBA code, Excel always shows the message box to ask to save the Report.xlsm. Does anyone know how to get rid of this message and automatically save it, rahter than having to click save?
If I do not click save, the excel file will be broken and the code will be crash too.
Microsoft Excel, ask to save file notification
Python Code:
desktop = os.path.normpath(os.path.expanduser("~/Desktop"))
# Generate excel file
writer = pd.ExcelWriter(desktop + '\Report.xlsx', engine = 'xlsxwriter')
df.to_excel(writer, index = False, sheet_name = 'Report')
workbook = writer.book
workbook.filename = desktop + '\Report.xlsm'
# Add VBA code to new excel report - Report.xlmx from vbaProject.bin
workbook.add_vba_project('vbaProject.bin')
writer.save()
# RUN MACRO
exel = win32com.client.Dispatch('Excel.Application')
exel.Workbooks.Open(Filename = desktop + '\Report.xlsm' , ReadOnly=1)
xl.Application.Run("Macro1")
xl.Application.Quit()
del xl
Add this at the end of your code
exel.ActiveWorkbook.Close(True)
True = Save,
False = Do Not Save
I received the following error as I tried to open the Excel file which I have saved using openpyxl:
Excel could not open excel_test.xlsx because some content is unreadable. Do you want to open and repair this workbook?
Is there a way to tackle this issue without having to click the "repair" option? I have looked into here but it does not solve the problem.
The original content of the file looks like this:
and here is my code:
import openpyxl
path_excel = ""
workbook_test = openpyxl.load_workbook(filename = path_excel)
worksheet_test = workbook_test["Sheet1"]
for row_, cellObj_ in enumerate(worksheet_test["D"], 1):
if row_ == 1:
cellObj_.value = "SUM"
else:
cellObj_.value = "= $B${0} + $C${0}".format(row_)
workbook_test.save(filename = path_excel)
i have a weekly report that i need to do, i chooseed to create it with openpyxl python module, and send it via mail, when i open the received mail (outlook), the cells with formulas appears as empty, but when downloading the file and open it, the data appears, OS fedora 20. parts of the code :
# imported modules from openpyxl ...
wb = Workbook()
ws = wb.active
counter = 3
ws.append(row)
for day in data :
row = ['']*(len(hosts)*2 +5)
row[0] = day.dayDate
row[1] ='=SUM(F'+str(counter)+':'+get_column_letter(len(hosts)+5)+str(counter)+\
')/(COUNT(F'+str(counter)+':'+get_column_letter(len(hosts)+5)+str(counter)+'))'
row[2] = '=SUM('+get_column_letter(len(hosts)+6)+str(counter)+':'+\
get_column_letter(len(hosts)*2+5)+str(counter)+')/COUNT('+\
get_column_letter(len(hosts)+6)+str(counter)+':'+\
get_column_letter(len(hosts)*2+5)+str(counter)+')'
row[3] = '=MAX('+get_column_letter(len(hosts)+6)+str(counter)+':'+\
get_column_letter(len(hosts)*2+5)+str(counter)+')'
row[4] = '=_xlfn.STDEV.P('+get_column_letter(len(hosts)+6)+str(counter)\
+':'+get_column_letter(len(hosts)*2+5)+str(counter)+')'
counter += 1
then, i create from the date some charts, etc.. and save, then send via mail :
wb.save(pathToFile+fileName+'.xlsx')
os.system('echo -e "'+msg+'" | mail -s "'+fileName+'" -a '+\
pathToFile+fileName+'.xlsx -r '+myUsr+' '+ppl2send2)
those are parts of the actual code, any one have an idea why the email don't show the results of the formulas in the cells ? Thanks in advance :)
openpyxl doesn't compute a result for formulas inserted into a spreadsheet; if you open the sheet with excel and save it, the result will have values filled in.
opepyxl has a problem with formulas, after you update your excel file you need to open it and save it to get the values generated. There are two ways to solve this problem.
(I won't advice you to use this unless you really want it.)
You can automate the process of opening the file and saving it from python before reading it. You can do this by using the win32com module
import win32com.client
wb.save('PUT YOUR FILE PATH HERE')
ab = win32com.client.Dispatch("Excel.Application")
wb2 = ab.Workbooks.Open('PUT YOUR FILE PATH HERE')
ws = ab.Sheets('PUT THE SHEET NAME HERE')
ab.DisplayAlerts = False
wb2.Save()
wb2.Close()
ab.Application.Quit()
#Now you can read from the file and you can see the values generated from the formula
Or you can use xlwings instead of openpyxl. if you use this module you don't have to worry about saving the excel file. The module will do it for you.
import xlwings
wb= xlwings.Book('PUT YOUR FILE PATH HERE')
ws = wb.sheets[0]
#Do your update here example ws.range(2, 8).value = 34
wb.save()
wb.close()