Google App Engine で Excel を作成しダウンロードさせる
先日、COCOMOによる工数計算 および、ファンクションポイント を使った見積ツールを作成したが、それに Excel で結果をダウンロードする機能を組み込みたいと思う。
pyExcelerator ではなくて xlwt を使う
Google Data サービスを利用すると、Google Document 等も作成できるようだが、まずは、Excel でダウンロードできるように。
Excel に結果をダウンロードできれば、使い勝手も上がるかな~と。
まず、Pythonから、Excelを使うには、pyExcelerator だと思い、したしらべしていたら、どうも、直接レスポンスのストリームに Excel ワークブックを書き込みできないようだ。
自宅サーバーなら、一時ファイルを作成する手もあるだろうが、相手はGAEだし、一時ファイルを作らなきゃいけないのはいただけない。
もう少し調べると、どうもすでに pyExcelerator はメンテナンスされておらず、そこからフォークした、xlwt の方が現在開発継続中で機能も豊富なようだ。そちらを使ってみることとする。
Zip インポート
GAE には、ファイルのアップロードに上限があり、ファイル数が多いときなどは、Zipインポートを使用すると、ファイル数を稼げる。
初回のインポート時に、展開されるが以降はメモリにキャッシュされ、同じインスタンスに対しては、その後オーバーヘッドは発生しないとのこと。
xlwt をダウンロード、解凍し、built/lib 以下のフォルダを zip 圧縮する。
アプリケーションのルートフォルダに配置(Exclepse + PyDev)
実装
試しに、xlwt のサンプル、xlwt-0.7.2\xlwt-0.7.2\xlwt\examples\mini.py の内容を出力してみる。
sys.path.insert で、zip import を行う。
import sys #sys.path.insert(0, 'gdata.zip') sys.path.insert(0, 'xlwt.zip') import xlwt import os from google.appengine.ext import webapp class DownloadResponse(webapp.RequestHandler): def get(self): self.post() def post(self): self.response.headers.add_header("Content-Disposition", 'attachment; filename="foo.xls"' ) wb = xlwt.Workbook() ws = wb.add_sheet('xlwt was here') wb.save(self.response.out) return None
Workbook.save メソッドに、Response.out オブジェクトを渡しているが、引数として、ファイル様オブジェクトをとるようだ。
CompoundDoc.py を参照。以下のようなシグネチャで、file_name_or_filelike_obj に対して呼ばれているのは、open と write
def save(self, file_name_or_filelike_obj, stream):
Response クラス の out は、StringIO なので、いけるだろう。
実行してみる。
ダウンロードのダイアログが開いた。
とりあえず、ローカル環境で Excel を開くことができた。
あとは、力業かな。