Writing a CSV from Flask framework
Question:
I have no problems writing a CSV outside of the Flask framework. But when I try to write it from Flask, it writes to the CSV, but only on one line.
Here is the template I’m following
@app.route('/download')
def download():
csv = """"REVIEW_DATE","AUTHOR","ISBN","DISCOUNTED_PRICE"
"1985/01/21","Douglas Adams",0345391802,5.95
"1990/01/12","Douglas Hofstadter",0465026567,9.95
"1998/07/15","Timothy ""The Parser"" Campbell",0968411304,18.99
"1999/12/03","Richard Friedman",0060630353,5.95
"2004/10/04","Randel Helms",0879755725,4.50"""
response = make_response(csv)
response.headers["Content-Disposition"] = "attachment; filename=books.csv"
return response
This writes the CSV perfectly, but when I try with my code, I get one long row.
My code:
@app.route('/download')
def post(self):
# lots of code
csvList.append([all,my,data,goes,here])
csvList = str(re.sub('[|]','',str(csvList))) # convert to a string; remove brackets
response = make_response(csvList)
response.headers['Content-Disposition'] = "attachment; filename=myCSV.csv"
return response
My output:
Nashville Physician Service Ce,Treasury Specialist,Brentwood,TN,(615) 507-1646,La Petite Academy,Afternoon Teacher Aide,Goodlettsville,TN,(615) 859-2034,Nashville Physician Service Ce,Denial Resolution Specialist,Brentwood,TN,(615) 507-1646
Thanks.
EDIT: I tried just about all the answers and they worked for the most part, but I chose vectorfrog’s because it fit with what I was trying to accomplish.
Answers:
You need to add newlines. Anyway, your method of making csv
s (printing the list and removing brackets from it) is not the best way to do it. Try this instead:
csvList = 'n'.join(','.join(row) for row in csvList)
Or use the csv
module:
import io, csv
dest = io.StringIO()
writer = csv.writer(dest)
for row in csvList:
writer.writerow(row)
# Now dest is a file-like object containing your csv
Since csv
is just a plain text format you shoud make shure that new line separator – n
is present at the end of every line you have
I’m not quite sure I understand your objective, but you can try the str.join() method. So, if you wanted to make a quick CSV output from a list of lists:
csvList= [['1', '2', '3'], ['4', '5', '6'], ['asdf', '7', 'eight']]
csvStrings= []
for csvLine in csvList:
csvStrings += [",".join(csvLine)]
print "n".join(csvStrings)
I did something like this recently, I found that I needed to first place the csv into a StringIO and then return the StringIO. If you want the csv to be a download, here’s what I did:
import StringIO
import csv
from flask import make_response
@app.route('/download')
def post(self):
si = StringIO.StringIO()
cw = csv.writer(si)
cw.writerows(csvList)
output = make_response(si.getvalue())
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
One alternative::
from flask import Flask, make_response
import pyexcel as pe
import StringIO # py2.7, for python3, please use import io
app = Flask(__name__)
data = [
["REVIEW_DATE","AUTHOR","ISBN","DISCOUNTED_PRICE"],
["1985/01/21","Douglas Adams",'0345391802',5.95],
["1990/01/12","Douglas Hofstadter",'0465026567',9.95],
["1998/07/15","Timothy "The Parser" Campbell",'0968411304',18.99],
["1999/12/03","Richard Friedman",'0060630353',5.95],
["2004/10/04","Randel Helms",'0879755725',4.50]
]
@app.route('/download')
def download():
sheet = pe.Sheet(data)
io = StringIO.StringIO()
sheet.save_to_memory("csv", io)
output = make_response(io.getvalue())
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
if __name__ == "__main__":
app.debug=True
app.run()
Another alternative is to use Flask-Excel:
from flask import Flask, make_response
from flask.ext import excel
app = Flask(__name__)
data = [
["REVIEW_DATE","AUTHOR","ISBN","DISCOUNTED_PRICE"],
["1985/01/21","Douglas Adams",'0345391802',5.95],
["1990/01/12","Douglas Hofstadter",'0465026567',9.95],
["1998/07/15","Timothy "The Parser" Campbell",'0968411304',18.99],
["1999/12/03","Richard Friedman",'0060630353',5.95],
["2004/10/04","Randel Helms",'0879755725',4.50]
]
@app.route('/download')
def download():
output = excel.make_response_from_array(data, 'csv')
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
if __name__ == "__main__":
app.debug=True
app.run()
I have no problems writing a CSV outside of the Flask framework. But when I try to write it from Flask, it writes to the CSV, but only on one line.
Here is the template I’m following
@app.route('/download')
def download():
csv = """"REVIEW_DATE","AUTHOR","ISBN","DISCOUNTED_PRICE"
"1985/01/21","Douglas Adams",0345391802,5.95
"1990/01/12","Douglas Hofstadter",0465026567,9.95
"1998/07/15","Timothy ""The Parser"" Campbell",0968411304,18.99
"1999/12/03","Richard Friedman",0060630353,5.95
"2004/10/04","Randel Helms",0879755725,4.50"""
response = make_response(csv)
response.headers["Content-Disposition"] = "attachment; filename=books.csv"
return response
This writes the CSV perfectly, but when I try with my code, I get one long row.
My code:
@app.route('/download')
def post(self):
# lots of code
csvList.append([all,my,data,goes,here])
csvList = str(re.sub('[|]','',str(csvList))) # convert to a string; remove brackets
response = make_response(csvList)
response.headers['Content-Disposition'] = "attachment; filename=myCSV.csv"
return response
My output:
Nashville Physician Service Ce,Treasury Specialist,Brentwood,TN,(615) 507-1646,La Petite Academy,Afternoon Teacher Aide,Goodlettsville,TN,(615) 859-2034,Nashville Physician Service Ce,Denial Resolution Specialist,Brentwood,TN,(615) 507-1646
Thanks.
EDIT: I tried just about all the answers and they worked for the most part, but I chose vectorfrog’s because it fit with what I was trying to accomplish.
You need to add newlines. Anyway, your method of making csv
s (printing the list and removing brackets from it) is not the best way to do it. Try this instead:
csvList = 'n'.join(','.join(row) for row in csvList)
Or use the csv
module:
import io, csv
dest = io.StringIO()
writer = csv.writer(dest)
for row in csvList:
writer.writerow(row)
# Now dest is a file-like object containing your csv
Since csv
is just a plain text format you shoud make shure that new line separator – n
is present at the end of every line you have
I’m not quite sure I understand your objective, but you can try the str.join() method. So, if you wanted to make a quick CSV output from a list of lists:
csvList= [['1', '2', '3'], ['4', '5', '6'], ['asdf', '7', 'eight']]
csvStrings= []
for csvLine in csvList:
csvStrings += [",".join(csvLine)]
print "n".join(csvStrings)
I did something like this recently, I found that I needed to first place the csv into a StringIO and then return the StringIO. If you want the csv to be a download, here’s what I did:
import StringIO
import csv
from flask import make_response
@app.route('/download')
def post(self):
si = StringIO.StringIO()
cw = csv.writer(si)
cw.writerows(csvList)
output = make_response(si.getvalue())
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
One alternative::
from flask import Flask, make_response
import pyexcel as pe
import StringIO # py2.7, for python3, please use import io
app = Flask(__name__)
data = [
["REVIEW_DATE","AUTHOR","ISBN","DISCOUNTED_PRICE"],
["1985/01/21","Douglas Adams",'0345391802',5.95],
["1990/01/12","Douglas Hofstadter",'0465026567',9.95],
["1998/07/15","Timothy "The Parser" Campbell",'0968411304',18.99],
["1999/12/03","Richard Friedman",'0060630353',5.95],
["2004/10/04","Randel Helms",'0879755725',4.50]
]
@app.route('/download')
def download():
sheet = pe.Sheet(data)
io = StringIO.StringIO()
sheet.save_to_memory("csv", io)
output = make_response(io.getvalue())
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
if __name__ == "__main__":
app.debug=True
app.run()
Another alternative is to use Flask-Excel:
from flask import Flask, make_response
from flask.ext import excel
app = Flask(__name__)
data = [
["REVIEW_DATE","AUTHOR","ISBN","DISCOUNTED_PRICE"],
["1985/01/21","Douglas Adams",'0345391802',5.95],
["1990/01/12","Douglas Hofstadter",'0465026567',9.95],
["1998/07/15","Timothy "The Parser" Campbell",'0968411304',18.99],
["1999/12/03","Richard Friedman",'0060630353',5.95],
["2004/10/04","Randel Helms",'0879755725',4.50]
]
@app.route('/download')
def download():
output = excel.make_response_from_array(data, 'csv')
output.headers["Content-Disposition"] = "attachment; filename=export.csv"
output.headers["Content-type"] = "text/csv"
return output
if __name__ == "__main__":
app.debug=True
app.run()