Google App Engine(Python)用フレームワークKayを使い、動的にExcelファイルを作成してZIP形式で圧縮しダウンロードさせる

Google App Engine(Python)用フレームワークKayを使い、動的にExcelファイルを作成してZIP形式で圧縮しダウンロードさせる方法。

Google App Engine(Python)用フレームワークKayを使い、動的にZIP形式で圧縮してダウンロードさせる」と「Google App Engine用フレームワークKayでExcelファイルをダウンロードさせる」の合わせ技になります。

Excelファイルの作成には、xlwtを使用します。
xlwtはpure pythonなので、Google App Engineで使用することが出来ます。

xlwtからソースをダウンロードして展開します。
xlwtフォルダーをKayのプロジェクトのルートフォルダーにコピーします。
xlwtフォルダー中のdocフォルダーやexamplesフォルダーは不要です

次のようなフォルダー構成になります。

myproject/
 ├ kay/
 ├ myapp/
 └ xlwt/

xlwtでExcelデータを作成します。

wb = xlwt.Workbook()
ws1 = wb.add_sheet('Sheet1')
ws1.write(0, 0, u'セル:A1')
ws1.write(1, 0, u'セル:A2')
ws1.write(0, 1, u'セル:B1')
ws1.write(1, 1, u'セル:B2')
data = StringIO.StringIO()
wb.save(data)

xlwt.save()は引数にファイルライクなオブジェクトをとります。
引数に指定したオブジェクトにExcelデータが書き込まれます。

ZipFileオブジェクトを作成します。

ZipFileオブジェクトのコンストラクタの1番目の引数にファイルライクなオブジェクトを指定します。
引数に指定したファイルライクなオブジェクトに、ZIPデータが書き込まれます。

zipdata = StringIO.StringIO()
zipobj =  zipfile.ZipFile(zipdata, 'w', zipfile.ZIP_DEFLATED)

ZipFileオブジェクトにファイルを登録します。
1番目の引数にファイル名を、2番目の引数にファイルのデータ(バイト列)を指定します。

zipobj.writestr('example.xls', data.getvalue())

ここで、1番目の引数にZipInfoオブジェクトを指定すると、ファイルの情報を細かく設定することが出来ます。

最後に閉じます。

zipobj.close()

以上で、ZIPデータを作成できました。

作成したZIPデータをダウンロードさせるために、HTTPヘッダの設定を行います。

header = Headers()
header.add('Content-Type', 'application/octet-stream');
header.add('Content-Disposition', 'attachment', filename='foo.zip')

最後に、ZIPデータをレスポンスとして返します。

return Response(zipdata.getvalue(), headers=header)

全体のソースコードは以下のようになります。

def index(request):
    import xlwt
    import StringIO
    import zipfile
    from werkzeug.datastructures import Headers
    from werkzeug import Response

    wb = xlwt.Workbook()
    ws1 = wb.add_sheet('Sheet1')
    ws1.write(0, 0, u'セル:A1')
    ws1.write(1, 0, u'セル:A2')
    ws1.write(0, 1, u'セル:B1')
    ws1.write(1, 1, u'セル:B2')
    data = StringIO.StringIO()
    wb.save(data)

    zipdata = StringIO.StringIO()
    zipobj =  zipfile.ZipFile(zipdata, 'w', zipfile.ZIP_DEFLATED)
    zipobj.writestr('example.xls', data.getvalue())
    zipobj.close()

    header = Headers()
    header.add('Content-Type', 'application/octet-stream');
    header.add('Content-Disposition', 'attachment', filename='foo.zip')
    return Response(zipdata.getvalue(), headers=header)

関連ページ

コメント

  1. これはなかなか良いTipsですね。いつも役に立つ記事をありがとうございます。

  2. コメントありがとうございます。
    間違いがあれば、どんどん指摘してください。

コメントを残す

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