Web アプリケーションを開発していると「 Excel
ファイルをダウンロードする」機能が必要となることがあると思います。
今回は Python
の Web アプリケーションフレームワークである Django
で、 Excel
ファイルのテンプレートを利用して「Excelファイルのダウンロード機能」の実装方法を説明していきたいと思います。
開発環境について
- Python : 3.5.2
- Django : 1.10.5
- xlutils : 2.0.0
- xlrd : 1.0.0
- xlwt : 1.2.0
「 Django
」「 xlutils
」「 xlrd
」「 xlwt
」については pip install
コマンドを使用してライブラリをあらかじめインストールしておいてください。
xlutils , xlrd , xlwtについて
それぞれのライブラリの主な役割は下記の通りです。 | ライブラリ | 役割 |
---|---|---|
xlutils | Excel ファイルを操作するためのメソッドがまとめられている(ファイルコピーなど) | |
xlrd | Excel ファイルの読み込み時に利用する | |
xlwt | Excel ファイルの書き込み時に利用する |
それでは早速、これらのライブラリを利用した Excel ファイルの出力機能の実装方法を説明していきたいと思います。
Excel ファイル出力機能を実装する
あらかじめ、ライブラリをインポートしておきます。
ライブラリのインポート
import xlwt
import xlrd
from xlutils.copy import copy
今回はあらかじめ準備しているExcelのテンプレートファイルをコピーして、コピーしたファイルに書き込みを行いファイルをダウンロードさせるため、「 xlutils
」の copy
メソッドを利用します。この copy
メソッドで Excel のテンプレートファイルをコピーします。
Excel のテンプレートファイルをコピーする
# Excelのテンプレートファイルの読み込み
rb = xlrd.open_workbook(os.path.join(MEDIA_ROOT, 'report.xls'), formatting_info=True, on_demand=True)
# 読み込んだExcelファイルをコピーする
wb = copy(rb)
ここでは、 MEDIA_ROOT
のパス上にある「 report.xls
」というファイルを読み込んでいます。
formatting_info=True
とすることで、 xlrd
がセルのスタイル情報も読み込んでくれて、 xlutils.copy
を実行した時に
にスタイル情報もコピーしてくれます。xlwt
コピーした Excel ファイルにデータを書き込む
コピーした Excel ファイルにデータを書き込んでいきます。ここで注意が必要なのが、「データを書き込んだセルはスタイル情報がデフォルトに戻ってしまう。」という点です。
データのみの書き込み処理を行い、書き込んだセルに対してスタイルの設定を行わなかった場合、そのセルはデフォルトのスタイルとなってしまいます。罫線とか背景色とか文字寄せなどの情報がリセットされてしまいます。
なので、データの書き込みを行なった場合は、書き込みを行なったセルに対して忘れずにスタイルを設定する必要があります。
いくつかスタイル設定のサンプルと書き込みの実装方法を書いていきます。
# フォント設定(Excelファイル内部でよく使うものはあらかじめ設定しておいた方が良いです。)
font_normal = xlwt.Font()
font_normal.name = 'MS P明朝'
# 表示位置設定(左寄せ上下中央揃え)
align_normal = xlwt.Alignment()
align_normal.horz = xlwt.Alignment.HORZ_LEFT
align_normal.vert = xlwt.Alignment.VERT_CENTER
# 表示位置設定(右寄せ上下中央揃え)
align_right = xlwt.Alignment()
align_right.horz = xlwt.Alignment.HORZ_RIGHT
align_right.vert = xlwt.Alignment.VERT_CENTER
# 罫線設定(全てに細い罫線を引く)
border_all = xlwt.Borders()
border_all.top = xlwt.Borders.THIN
border_all.bottom = xlwt.Borders.THIN
border_all.left = xlwt.Borders.THIN
border_all.right = xlwt.Borders.THIN
# 背景色設定(黄色)
pattern = xlwt.Pattern()
pattern.pattern = xlwt.Pattern.SOLID_PATTERN
# 色と紐付くコードの情報はStyle.pyに記載されています。
pattern.pattern_fore_colour = 0x0D
# ノーマルなテキストのスタイル
style_text = xlwt.XFStyle()
style_text.font = font_normal
style_text.borders = border_all
style_text.alignment = align_normal
# ノーマルな日付のスタイル
style_date = xlwt.easyxf('font: name MS P明朝', 'YYYY年M月D日')
style_date.borders = border_all
style_date.alignment = align_normal
# ノーマルな通貨のスタイル
style_currency = xlwt.easyxf('font: name MS P明朝', '¥#,##0')
style_currency.borders = border_all
style_currency.alignment = align_normal
# 右寄せの通貨のスタイル
style_currency_align_right = xlwt.easyxf('font: name MS P明朝', '¥#,##0')
style_currency_align_right.borders = border_all
style_currency_align_right.alignment = align_right
# ノーマルな数値のスタイル
style_num = xlwt.easyxf('font: name MS P明朝', '#,##0')
style_num.borders = border_all
style_num.alignment = align_right
# ノーマルなDecimalのスタイル
style_decimal = xlwt.easyxf('font: name MS P明朝', '#,##0.0')
style_decimal.borders = border_all
style_decimal.alignment = align_right
# WorkBookからWorkSheetを取得する
ws = wb.get_sheet(sheet_name)
# テキストを書き込む
ws.write(row, col, value, style_text)
# 日付を書き込む
ws.write(row, col, value, style_date)
# 通貨を書き込む
ws.write(row, col, value, style_currency)
# 数値を書き込む
ws.write(row, col, value, style_num)
# Decimalを書き込む
ws.write(row, col, value, style_decimal)
ws.write
の引数にはそれぞれ下記を設定してください。
- row : 行番号(0〜)
- col : 列番号(0〜)
- value : 書き込むデータ
- style_*** : 設定したいずれかのスタイル
あらかじめスタイル情報を定義しておくことで、データ書き込みの際にはほとんどスタイル情報を意識することなく実装していくことができます。
都度スタイルを定義するよりもコードの可読性や実行速度が向上すると思います。
Excel ファイルをダウンロードさせる
これで、 Excel のテンプレートファイルをコピーして、データの書き込みまではできました。
最後に、書き込みを行なったファイルのダウンロード処理の部分を実装していきます。
Django
の views.py
ファイルの get
や post
の中で以下のコードを実装します。
# HttpResponseを生成する
response = HttpResponse(content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=%s' % 'report.xls'
# データの書き込みを行なったExcelファイルを保存する
wb.save(response)
# 生成したHttpResponseをreturnする
return response
views.py
の post
の処理では通常、 render
もしくは redirect
を return
すると思いますが、 Excel ファイルをダウンロードさせる場合は、 HttpResponse
オブジェクトを生成し、 return
させることで、ダウンロードを可能にします。
最後に
Web アプリケーションを開発していると「 Excel 出力機能」は結構実装する機会が多い機能だと思います。
ちなみに、 Linux
環境でも問題なくExcel出力されますので、 OS
は意識せず実装できます。
もし、 Django
を使っていて、 Excel 出力機能の実装で悩んでいるのでいれば、是非参考にしてみてください。
コメント
すみません.プログラミング初心者です.Django サーバ上でこのサンプルコードを実行したとき,ブラウザに文字列が表示されるだけで,ダウンロードできないのですが,どのようにすればダウンロード
すみません.途中で送信してしまいました.
プログラミング初心者です.Django サーバ上でこのサンプルコードを実行したとき,ブラウザに文字列が表示されるだけで,ダウンロードできないのですが,どのようにすればダウンロードできるのでしょうか??
ちなみにどんな文字列が表示されてますか?
ダウンロードの仕組みとしては生成したエクセルファイルを記事にあるようなhttpヘッダをつけてレスポンスとして返してあげてるだけなので、Djangoのviews.pyの処理の中でレスポンスが返却できてればダウンロードできると思います。
ちなみに、このエクセルのダウンロードですが、拡張子が「.xls」のものしかダウンロードできないです。
「.xlsx」の拡張子のエクセルファイルはダウンロードできません。
解決しました。
ws = wb.get_sheet(sheet_name)
でできました。
API Reference には無かったのですが…
ttps://xlwt.readthedocs.io/en/latest/api.html
ダウンロードできるようになってよかったです!
ws = wb.get_sheet(sheet_name)
上記の記載をこちらの記事の方にも反映させていただきますね。
コメントありがとうございました。