I have a *.xlsm file which has 20 sheets in it. I want to save few sheets as *.csv (formatting loss is fine) individually. Already tried xlrd-xlwt and win32com libraries but could not get through. Can anybody please provide a code snippet which does the above processing in Python? I have other python dependencies so no other language would work. Thanks
Asked
Active
Viewed 3.5k times
10
-
As far as I remember, all recent Microsoft Office formats were XML packed into Zip container. So probably you could take a look at the .xlsm file sources, clarify its XML structure and then extract required fields. – user3159253 May 09 '14 at 00:43
3 Answers
6
xlrd should work fine on xlsm files as well. I tested the code with a random xlsm file, and it worked perfectly.
import csv
import xlrd
workbook = xlrd.open_workbook('test.xlsx')
for sheet in workbook.sheets():
with open('{}.csv'.format(sheet.name), 'wb') as f:
writer = csv.writer(f)
writer.writerows(sheet.row_values(row) for row in range(sheet.nrows))
If you've encoding issues, try the code below:
import csv
import xlrd
workbook = xlrd.open_workbook('test.xlsm')
for sheet in workbook.sheets():
if sheet.name == "Sheet_name_from_xlsm_file":
with open('{}.csv'.format(sheet.name), 'wb') as f:
writer = csv.writer(f)
for row in range(sheet.nrows):
out = []
for cell in sheet.row_values(row):
try:
out.append(cell.encode('utf8'))
except:
out.append(cell)
writer.writerow(out)

Ali Sayani
- 33
- 7

Steinar Lima
- 7,644
- 2
- 39
- 40
-
1If this doesn't work, you should upload your data file if possible. – Steinar Lima May 09 '14 at 01:16
-
Thanks for the snippet! I am getting this error: writer.writerows(sheet.row_values(row) for row in range(sheet.nrows)) UnicodeEncodeError: 'ascii' codec can't encode character u'\xb5' in position 0: ordinal not in range(128) Is there a way to specify encoding here? Sorry, can't upload the file here. – iPirate May 09 '14 at 01:32
-
@iPirate I think you need to encode the strings with utf8 or something similar. Try cp1252 if it doesn't work. I've updated my answer. – Steinar Lima May 09 '14 at 01:42
-
1I tried to use this code to convert an .xlsm file to csv and nothing happens - no errors and it doesn't write anything out that I can see.. what could be happening. I also dont' understand where the csv is getting written out to in the above code – kflaw Jan 06 '15 at 21:18
-
@kflaw: The output is saved in _
.csv_ (without the brackets obviously). This file will be located the place you run your script from. If you have any further questions, I advise you to open a new question here at SO, with as much context provided as possible. You can link to your new question here if you want to. – Steinar Lima Jan 06 '15 at 23:07 -
1Please keep in mind, that from the current xlrd-version onwards (2.0+) explicitly only "xls" is allowed as a file format. So for opening "xlsm"-files you have to switch to the much better openpyxl module. – CheradenineZK Feb 25 '21 at 09:47
4
You can do this easily with pandas
Install pandas and xlrd dependencies by following
- pip3 install pandas
- pip3 install xlrd (required by pandas)
Now simply read xlsm file using read_excel. Here is a demo:-
import pandas as pd
# YOU MUST PUT sheet_name=None TO READ ALL CSV FILES IN YOUR XLSM FILE
df = pd.read_excel('YourFile.xlsm', sheet_name=None)
# prints all sheets
print(df)
# prints all sheets name in an ordered dictionary
print(df.keys())
# prints first sheet name or any sheet if you know it's index
first_sheet_name = list(df.keys())[0]
print(first_sheet_name)
# prints first sheet or any sheet if know it's name
print(df[first_sheet_name])
# export first sheet to file
df[first_sheet_name].to_csv('FirstSheet.csv')
# export all sheets
for sheet_name in list(df.keys()):
df[sheet_name].to_csv(sheet_name + 'Sheet.csv')
# USE IT IN MULTIPLE WAYS #

bikram
- 7,127
- 2
- 51
- 63