Google App Engine で Excel を作成しダウンロードさせる

先日、COCOMOによる工数計算 および、ファンクションポイント を使った見積ツールを作成したが、それに Excel で結果をダウンロードする機能を組み込みたいと思う。

gae_excel01

pyExcelerator ではなくて xlwt を使う

Google Data サービスを利用すると、Google Document 等も作成できるようだが、まずは、Excel でダウンロードできるように。

Excel に結果をダウンロードできれば、使い勝手も上がるかな~と。

まず、Pythonから、Excelを使うには、pyExcelerator だと思い、したしらべしていたら、どうも、直接レスポンスのストリームに Excel ワークブックを書き込みできないようだ。

自宅サーバーなら、一時ファイルを作成する手もあるだろうが、相手はGAEだし、一時ファイルを作らなきゃいけないのはいただけない。

もう少し調べると、どうもすでに pyExcelerator はメンテナンスされておらず、そこからフォークした、xlwt の方が現在開発継続中で機能も豊富なようだ。そちらを使ってみることとする。

Zip インポート

GAE には、ファイルのアップロードに上限があり、ファイル数が多いときなどは、Zipインポートを使用すると、ファイル数を稼げる。

初回のインポート時に、展開されるが以降はメモリにキャッシュされ、同じインスタンスに対しては、その後オーバーヘッドは発生しないとのこと。

xlwt をダウンロード、解凍し、built/lib 以下のフォルダを zip 圧縮する。

gae_excel02

アプリケーションのルートフォルダに配置(Exclepse + PyDev)

gae_excel03

実装

試しに、xlwt のサンプル、xlwt-0.7.2\xlwt-0.7.2\xlwt\examples\mini.py  の内容を出力してみる。

sys.path.insert で、zip import を行う。

  1. import sys
  2. #sys.path.insert(0, 'gdata.zip')
  3. sys.path.insert(0, 'xlwt.zip')
  4.  
  5. import xlwt
  6.  
  7. import os
  8. from google.appengine.ext import webapp
  9.  
  10. class DownloadResponse(webapp.RequestHandler):
  11. def get(self):
  12. self.post()
  13. def post(self):
  14. self.response.headers.add_header("Content-Disposition", 'attachment; filename="foo.xls"' )
  15. wb = xlwt.Workbook()
  16. ws = wb.add_sheet('xlwt was here')
  17. wb.save(self.response.out)
  18. return None

Workbook.save メソッドに、Response.out オブジェクトを渡しているが、引数として、ファイル様オブジェクトをとるようだ。

CompoundDoc.py を参照。以下のようなシグネチャで、file_name_or_filelike_obj に対して呼ばれているのは、open と write

  1. def save(self, file_name_or_filelike_obj, stream):

Response クラス の out は、StringIO なので、いけるだろう。

実行してみる。

gae_excel04 

ダウンロードのダイアログが開いた。

gae_excel05

とりあえず、ローカル環境で Excel を開くことができた。

あとは、力業かな。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です