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 を行う。

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 なので、いけるだろう。

実行してみる。

gae_excel04 

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

gae_excel05

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

あとは、力業かな。

Follow me!

コメントを残す

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