Django Logo

[Django]でテンプレートを使ってExcelファイルを出力する

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について

それぞれのライブラリの主な役割は下記の通りです。ライブラリ役割
xlutilsExcel ファイルを操作するためのメソッドがまとめられている(ファイルコピーなど)
xlrdExcel ファイルの読み込み時に利用する
xlwtExcel ファイルの書き込み時に利用する

それでは早速、これらのライブラリを利用した 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 のテンプレートファイルをコピーして、データの書き込みまではできました。

最後に、書き込みを行なったファイルのダウンロード処理の部分を実装していきます。

Djangoviews.py ファイルの getpost の中で以下のコードを実装します。

# 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.pypost の処理では通常、 render もしくは redirectreturn すると思いますが、 Excel ファイルをダウンロードさせる場合は、 HttpResponse オブジェクトを生成し、 return させることで、ダウンロードを可能にします。

最後に

Web アプリケーションを開発していると「 Excel 出力機能」は結構実装する機会が多い機能だと思います。

ちなみに、 Linux 環境でも問題なくExcel出力されますので、 OS は意識せず実装できます。

もし、 Django を使っていて、 Excel 出力機能の実装で悩んでいるのでいれば、是非参考にしてみてください。

「[Django]でテンプレートを使ってExcelファイルを出力する」への5件のフィードバック

  1. すみません.プログラミング初心者です.Django サーバ上でこのサンプルコードを実行したとき,ブラウザに文字列が表示されるだけで,ダウンロードできないのですが,どのようにすればダウンロード

  2. すみません.途中で送信してしまいました.
    プログラミング初心者です.Django サーバ上でこのサンプルコードを実行したとき,ブラウザに文字列が表示されるだけで,ダウンロードできないのですが,どのようにすればダウンロードできるのでしょうか??

    1. ブラウザに文字列が表示されるだけで、

      ちなみにどんな文字列が表示されてますか?

      ダウンロードの仕組みとしては生成したエクセルファイルを記事にあるようなhttpヘッダをつけてレスポンスとして返してあげてるだけなので、Djangoのviews.pyの処理の中でレスポンスが返却できてればダウンロードできると思います。

      ちなみに、このエクセルのダウンロードですが、拡張子が「.xls」のものしかダウンロードできないです。
      「.xlsx」の拡張子のエクセルファイルはダウンロードできません。

  3. 解決しました。

    ws = wb.get_sheet(sheet_name)

    でできました。

    API Reference には無かったのですが…
    ttps://xlwt.readthedocs.io/en/latest/api.html

    1. ダウンロードできるようになってよかったです!

      ws = wb.get_sheet(sheet_name)

      上記の記載をこちらの記事の方にも反映させていただきますね。
      コメントありがとうございました。

コメントする

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