Flask で CSV 出力(修正版)
前回はファイルを書き込んで閉じてから、また開いてと、かなり気持ち悪かったのですが、
と、修正案を頂いたので、適用してみました。
これで余分な一時ファイルも作られないのですっきり。
StringIO を使うのか!と、また1つ勉強になりました。
V 様に感謝。
# -*- coding: utf-8 -*- import codecs import csv import cStringIO from flask import Flask, Response, make_response, render_template app = Flask(__name__) @app.route("/") def root(): return Response("<a href='/dl/'>DL</a>") @app.route("/dl/") def make_csv(): """ CSV 出力 """ response = make_response() response.data = _get_csv_data() response.headers['Content-Type'] = 'application/octet-stream' response.headers['Content-Disposition'] = u'attachment; filename=データ.csv' return response def _get_csv_data(): """ CSV データ作成 """ data = _make_data() csv_file = _make_file(data) return csv_file def _make_data(): """ 書き込みデータ作成 """ result = [] result.append(("1", "p", "python", 100, "あ")) result.append(("2", "y", "python", 200, "い")) result.append(("3", "t", "python", 300, "う")) result.append(("4", "h", "python", 400, "え")) result.append(("5", "o", "python", 500, "お")) result.append(("6", "n", "python", 600, "か")) return result def _make_file(data): """ データを CSV 形式に変換 """ csv_file = cStringIO.StringIO() writer = csv.writer(csv_file, quoting=csv.QUOTE_NONNUMERIC) writer.writerows(data) return csv_file.getvalue() if __name__ == '__main__': app.run(debug=True)
コメントも追加してみたり。
これで多少は実用に耐えられるかなー。
追記:出力を Shift-JIS にする場合、
- response.data = _get_csv_data() + response.data = _get_csv_data().decode('utf8').encode('sjis')
と「.decode('utf8').encode('sjis')」つけるだけでできます。
これは CSV に限らず、HTML 出力の場合でも出来るので色々使えそう。