SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

PythonとDjangoでExcelファイルを作成

WebアプリケーションでExcelファイルを提供する

DjangoからのExcelファイルのダウンロード

 Excel互換ファイルをPythonで作成する方法を覚えたところで、次はそのファイルをDjangoでダウンロード可能にする方法を見ていきましょう。手順は簡単です。また、同じ手順でほとんどすべての種類のバイナリファイルを生成し、提供することができます。ファイルを作成できれば、それをユーザーにダウンロードさせるのは簡単です。

 鍵を握るのは「content-type」というHTTPヘッダーです。ブラウザからサーバー上のファイルを要求する場合、トランザクションは次のようになります。

GET /wp-content/uploads/2007/10/cropped-dsc_0020.jpg HTTP/1.1
Host: weblog.lonelylion.com
User-Agent:Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11)
   Gecko/20071204 Ubuntu/7.10 (gutsy) Firefox/2.0.0.11
Accept: image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://lonelylion.com/

HTTP/1.x 200 OK
Date: Sat, 02 Feb 2008 17:53:58 GMT
Server: Apache/1.3.37 (Unix) mod_throttle/3.1.2 DAV/1.0.3
   mod_fastcgi/2.4.2 mod_gzip/1.3.26.1a PHP/4.4.8 mod_ssl/2.8.22
   OpenSSL/0.9.7e
Last-Modified: Thu, 01 Nov 2007 03:22:12 GMT
Etag: "798f213-5c88-47294664"
Accept-Ranges: bytes
Content-Length: 23688
Keep-Alive: timeout=2, max=97
Connection: Keep-Alive
Content-Type: image/jpeg

 最後の行のContent-Type: image/jpegに注目してください。この行は、後続のデータが何であるかをブラウザに伝えています。ブラウザはこの行に基づいて、データの表示方法や、どの外部アプリケーションを開いてデータを表示するかを判断します。

 上記の例ではJpegの画像を要求しているため、Content-Typeに「image/jpeg」が設定されています。このヘッダーを「application/ms-excel」に変更すると、ファイルがExcelで開かれます。Djangoでヘッダーの記述を変更するのは非常に簡単です。以下に、csvファイルをブラウザに送信し、それをExcelで開くようブラウザに指示するDjangoビューの例を示します。

import csv
from StringIO import StringIO
from django.http import HttpResponse

def show_excel(request):
   # use a StringIO buffer rather than opening a file
   output = StringIO()
   w = csv.writer(output)
   for i in range(10):
      w.writerow(range(10))
   # rewind the virtual file
   output.seek(0)
   return HttpResponse(output.read(),
      mimetype='application/ms-excel')

 最初のcsv作成の例にいくつか修正を加えました。まず、実際にファイルを開くのではなく、ファイルに似たStringIOオブジェクトを使用しています。また、応答をDjangoのHttpResponseオブジェクトでラッピングしています(HttpResponseオブジェクトはDjangoビュー標準の戻り値のオブジェクトタイプです)。さらに、HttpResponseにcontent_typeを渡すことによって、Content-Typeヘッダーを「application/ms-excel」に設定しています。

 このパターンを使用して、ほとんどすべての種類のバイナリデータをWebブラウザから取得することができます。PDF、画像、音声、動画など、あらゆるデータに対して生成用のライブラリが用意されているので、Content-Typeヘッダーの値さえわかれば、バイナリデータを生成することが可能です。

 それでは、同じテクニックを使ってpyExceleratorで生成したExcelファイルを出力してみましょう。

from pyExcelerator import *
from django.http import HttpResponse

def show_excel(request):
   wb = Workbook()
   ws0 = wb.add_sheet('0')

   for x in range(10):
      for y in range(10):
         # writing to a specific x,y
         ws0.write(x,y,"this is cell %s, %s" % (x,y))

      wb.save('output.xls')
   return HttpResponse(open('output.xls','rb').read(),
      mimetype='application/ms-excel')

 これもやはり、先ほどのpyExceleratorを使用してExcelファイルを作成した例に似ています。ただこのコードには1つ難があります。一時ファイルを作成してデータを書き込み、その後あらためてファイルを開き、そこからデータを読み込んでいるのです。この方法だと、トラフィックが多い場合に問題が起こる可能性があります。また、あるユーザーがファイルを読み込んでいる間に別のユーザーがそこにアクセスすると、ファイルが破損してしまうかもしれません。ファイル名にタイムスタンプを付加するという解決方法もありますが、最も理想的なのは、Workbookのsaveメソッドにファイルに似たオブジェクトを渡してそこにデータを保存するという方法です。現在のpyExceleratorではこの方法は使用できませんが、必ずパッチが提供されると予想しています。

 筆者はたいていの場合、csvファイルを「Content-Type: application/ms-excel」としてブラウザに送信します。StringIOを使用すれば実装がシンプルになりますし、ダウンロード可能なスプレッドシートの作成にかかる時間は通常5分以内なので、ほとんどのエンドユーザーはおかしいとも感じません。これでユーザーの希望はかなえられますし、すぐにデータをいじってもらうことができます。ユーザーはデータをあれこれ操作することで、彼らが実際に使用するHTML表示についてより明確なビジョンを持つようになり、的確な要求をしてくるようになるでしょう。良いことだらけです。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Chris McAvoy(Chris McAvoy)

PSC Group LLC(イリノイ州シカゴ)の開発者。PythonおよびRubyのWebアプリケーションが専門。ブログはhttp://weblog.lonelylion.com

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/2423 2008/04/30 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー