How can I convert a CSV file with :
delimiter to XLS (Excel sheet) using openpyxl
module?
-
nothing, I have a csv file and i just want to convert in excel. I am new in python so no clue. – Satish Oct 19 '12 at 14:38
-
1On stackoverflow your questions are answered but no one will do the job for you. – dav1d Oct 19 '12 at 14:45
-
1@Satish I believe what dav1d is saying is that SO has this unspoken rule about giving men fish, as opposed to teaching them to fish. Anyways http://stackoverflow.com/questions/10802417/how-to-save-an-excel-worksheet-as-csv-from-python-unix. – John Oct 19 '12 at 14:48
-
@Johnthexiii Thanks! but that example is from excel to csv.. I am looking opposite solution. – Satish Oct 19 '12 at 14:53
4 Answers
A much simpler, minimalist solution:
import csv
import openpyxl
wb = openpyxl.Workbook()
ws = wb.active
with open('file.csv') as f:
reader = csv.reader(f, delimiter=':')
for row in reader:
ws.append(row)
wb.save('file.xlsx')

- 2,001
- 1
- 16
- 16
-
This is better answer. Appending is IMO better way than ws.cell() method. – G4mo May 31 '17 at 10:01
-
import csv
from openpyxl import Workbook
from openpyxl.cell import get_column_letter
f = open(r'C:\Users\Asus\Desktop\herp.csv')
csv.register_dialect('colons', delimiter=':')
reader = csv.reader(f, dialect='colons')
wb = Workbook()
dest_filename = r"C:\Users\Asus\Desktop\herp.xlsx"
ws = wb.worksheets[0]
ws.title = "A Snazzy Title"
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = get_column_letter((column_index + 1))
ws.cell('%s%s'%(column_letter, (row_index + 1))).value = cell
wb.save(filename = dest_filename)

- 13,197
- 7
- 51
- 101
-
I got this error [spatel@mg0008 work]$ python26 c2x.py Traceback (most recent call last): File "c2x.py", line 17, in
for row_index, row in enumerate(reader): _csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode? – Satish Oct 23 '12 at 14:21 -
Nice, but resulting file opens with all number fields reporting that they are saved as text instead of as a number... – MrMobileMan Dec 22 '15 at 22:29
-
Found the fix to the numbers as text issue here: http://stackoverflow.com/questions/24971556/openpyxl-python-writing-csv-to-excel-gives-number-formatted-as-text – MrMobileMan Dec 22 '15 at 22:39
-
2Using `enumerate(start=1)` is a nice way to eliminate those `+ 1`. Also note that you can directly specify `cell(row=row_index, column=column_index)` instead of building a string. – John McGehee Mar 24 '16 at 00:13
-
3To make this work I had to change the 3rd line to `from openpyxl.utils import get_column_letter` and then change the penultimate line to `ws['%s%s'%(column_letter, (row_index + 1))].value = cell` – dingles Feb 01 '17 at 15:05
-
Here is Adam's solution expanded to strip out characters that openpyxl considers illegal and will throw an exception for:
import re
from openpyxl.cell.cell import ILLEGAL_CHARACTERS_RE
...
##ws.append(row) - Replace with the code below
for i in row:
ws.append([ILLEGAL_CHARACTERS_RE.sub('',i)])
ILLEGAL_CHARACTERS_RE is a compiled regular expression containing the characters openpyxl deems "illegal". The code is simply substituting those characters with an empty string.
Source: Bitbucket openpyxl issue #873 - Remove illegal characters instead of throwing an exception

- 181
- 1
- 5
-
1I think you may have meant:`ws.append([ILLEGAL_CHARACTERS_RE.sub('', _i) for _i in row])` – KyleKing Apr 25 '19 at 17:40
On top of the suggestion by John, I slightly modified my script using function to remove the apostrophe of string for all raw data. This way, I managed to check all raw data (string and number), which were also placed in respective cell. Lastly, I assign numeric data to float type starting from row 20 onward. This is because all numeric data existed from row 20th onward, while all data above were text only.
cell_value = cell.replace('"', '')
Below is my script:
import csv
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
with open(filepath1_csv) as f:
reader = csv.reader(f)
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = column_index + 1
cell_value = cell.replace('"', '')
ws.cell(row = row_index + 1, column = column_letter).value = cell_value
for row in ws.iter_rows(min_row=20, min_col=1, max_col=5,
max_row=ws.max_row):
for cell in row:
if cell.value is None:
break
else:
cell.value = float(cell.value)
wb.save(filename = filepath1_xlsx)

- 66
- 3
-
Can you please paste the comment in a proper formatting? Images are not the best medium to display code. – Alex Metsai Jun 15 '21 at 07:56
-
Hi Alex Metsai, I will change the format and thanks for your suggestion! – Eureka JX Jun 15 '21 at 08:14