openpyxl python – writing csv to excel gives 'number formatted as text'
Question:
I have written a code to import a .csv file (containing numbers) into an excel file through openpyxl. It works, however, all the cells have written the numbers to the excel file as text. I then have to manually correct the error in excel: “Numbers formatted as text (displaying little green triangles in the corner of the cell).
Is there a way to prevent this from happening? It occurs with any csv file, even if I make it with just numbers. Thanks
#!python2
# Add csv file to an xlsx
import os, csv, sys, openpyxl
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.cell import get_column_letter
#Open an xlsx for reading
wb = load_workbook('Test.xlsx')
ws = wb.get_sheet_by_name("RUN")
dest_filename = "Test_NEW.xlsx"
csv_filename = "csvfile.csv"
#Copy in csv
f = open(csv_filename)
reader = csv.reader(f)
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)
print "new Cashflow created"
*****UPDATE***
Thanks, that helps. My problem was that my csv file had a mixture of text and numbers without any defining quotes. So I implemented the below to change it from a string to float as long as there isn’t an error.
#Copy in csv
f = open(csv_filename,'rb')
reader = csv.reader(f)
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = get_column_letter((column_index + 1))
s = cell
try:
s=float(s)
except ValueError:
pass
ws.cell('%s%s'%(column_letter, (row_index + 1))).value = s
Answers:
You need to convert the value from the CSV file to what you need. All values in CSV files are strings.
ws.cell('%s%s'%(column_letter, (row_index + 1))).value = int(cell)
ought to do it.
BTW. you might want to look at the ws.append()
method.
This is the first google result, and I spent more time than I would like to admit working on this. I hope it helps someone in the future.
def csvtoxlsx(csv_name, xlsx_name, directory, floats):
"""
A function to convert a CSV file to XLSX so it can be used by openpyxl.
csvname = file name of csv you want to convert (include .csv)
xlsx_name = name you want to name the xlsx file (include .xlsx)
cwd = directory to find csv file (can pass os.getcwd())
floats = A list of column indexes in which floats appear
"""
os.chdir(directory)
f = open(csv_name, 'rt')
csv.register_dialect('commas', delimiter=',')
reader = csv.reader(f, dialect='commas')
wb = Workbook()
dest_filename = xlsx_name
ws = wb.worksheets[0]
ws.title = xlsx_name[:-5]
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = get_column_letter((column_index + 1))
if column_index in floats:
s = cell
#Handles heading row or non floats
try:
s = float(s)
ws[('%s%s'%(column_letter, (row_index + 1)))].value = s
except ValueError:
ws[('%s%s'%(column_letter, (row_index + 1)))].value = s
elif column_index not in floats:
#Handles openpyxl 'illigal chars'
try:
ws[('%s%s'%(column_letter, (row_index + 1)))].value = cell
except:
ws[('%s%s'%(column_letter, (row_index + 1)))].value = 'illigal char'
wb.save(filename = dest_filename)
The function get_column_letter has been relocated in Openpyxl from openpyxl.cell to openpyxl.utils
from openpyxl.utils import get_column_letter
I have written a code to import a .csv file (containing numbers) into an excel file through openpyxl. It works, however, all the cells have written the numbers to the excel file as text. I then have to manually correct the error in excel: “Numbers formatted as text (displaying little green triangles in the corner of the cell).
Is there a way to prevent this from happening? It occurs with any csv file, even if I make it with just numbers. Thanks
#!python2
# Add csv file to an xlsx
import os, csv, sys, openpyxl
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.cell import get_column_letter
#Open an xlsx for reading
wb = load_workbook('Test.xlsx')
ws = wb.get_sheet_by_name("RUN")
dest_filename = "Test_NEW.xlsx"
csv_filename = "csvfile.csv"
#Copy in csv
f = open(csv_filename)
reader = csv.reader(f)
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)
print "new Cashflow created"
*****UPDATE***
Thanks, that helps. My problem was that my csv file had a mixture of text and numbers without any defining quotes. So I implemented the below to change it from a string to float as long as there isn’t an error.
#Copy in csv
f = open(csv_filename,'rb')
reader = csv.reader(f)
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = get_column_letter((column_index + 1))
s = cell
try:
s=float(s)
except ValueError:
pass
ws.cell('%s%s'%(column_letter, (row_index + 1))).value = s
You need to convert the value from the CSV file to what you need. All values in CSV files are strings.
ws.cell('%s%s'%(column_letter, (row_index + 1))).value = int(cell)
ought to do it.
BTW. you might want to look at the ws.append()
method.
This is the first google result, and I spent more time than I would like to admit working on this. I hope it helps someone in the future.
def csvtoxlsx(csv_name, xlsx_name, directory, floats):
"""
A function to convert a CSV file to XLSX so it can be used by openpyxl.
csvname = file name of csv you want to convert (include .csv)
xlsx_name = name you want to name the xlsx file (include .xlsx)
cwd = directory to find csv file (can pass os.getcwd())
floats = A list of column indexes in which floats appear
"""
os.chdir(directory)
f = open(csv_name, 'rt')
csv.register_dialect('commas', delimiter=',')
reader = csv.reader(f, dialect='commas')
wb = Workbook()
dest_filename = xlsx_name
ws = wb.worksheets[0]
ws.title = xlsx_name[:-5]
for row_index, row in enumerate(reader):
for column_index, cell in enumerate(row):
column_letter = get_column_letter((column_index + 1))
if column_index in floats:
s = cell
#Handles heading row or non floats
try:
s = float(s)
ws[('%s%s'%(column_letter, (row_index + 1)))].value = s
except ValueError:
ws[('%s%s'%(column_letter, (row_index + 1)))].value = s
elif column_index not in floats:
#Handles openpyxl 'illigal chars'
try:
ws[('%s%s'%(column_letter, (row_index + 1)))].value = cell
except:
ws[('%s%s'%(column_letter, (row_index + 1)))].value = 'illigal char'
wb.save(filename = dest_filename)
The function get_column_letter has been relocated in Openpyxl from openpyxl.cell to openpyxl.utils
from openpyxl.utils import get_column_letter