【Django】ファイル(エクセル・CSS・テキスト)をダウンロードさせる(出力する)方法

時計 2021.12.02 / 時計

【Django】ファイル(エクセル・CSS・テキスト)をダウンロードさせる(出力する)方法

本記事ではWebアプリケーションのDjangoにおける、ファイルエクセル・CSV・テキストファイル)をブラウザ経由でダウンロードさせる方法について解説していきます。

ユーザーの入力や選択に従って、Webアプリケーション側で生成したファイルをダウンロードさせたい場面は多々あります。

しかしDjangoでエクセルやCSSといったファイル群をユーザーにダウンロードさせる方法を詳しく解説した記事はあまり存在しません。

そのため本記事でその方法を詳しく解説していきたいと思います。

テンプレートを元に作成したエクセル(ワード、CSV、テキストファイルも可能)をユーザーにダウンロードさせる方法については以下記事をご参照ください。

ユーザーにファイルをダウンロードさせる

ユーザーにファイルをダウンロードさせるためには、HTTPレスポンスを生成するviews.pyでファイルをreturnする必要があります。

views.pyの関数ベースビューで最も利用されるのはrenderメソッドです。renderメソッドについては以下記事をご参照ください。

しかしここではHttpResonseを使用して生成したオブジェクトをreturnでユーザーに返すことでダウンロードさせます。

構文

HttpResponse(ファイルデータ, content_type=ファイル形式)

HttpResponseを利用するためにはdjango.httpからインポートする必要があります。

from django.http import HttpResponse

HttpResponseの引数にはエクセルやCSV、テキストファイルなどのファイルデータを指定し、content_typeには以下のファイル形式を指定します。

Content-Type ファイルの種類
text/plain テキストファイル
application/vnd.ms-excel Excelファイル
application/msword WORDファイル
text/csv CSVファイル
text/html htmlファイル
application/octet-stream EXEファイルなど
application/pdf PDFファイル
image/jpeg JPEGファイル
image/png PNGファイル

テキストファイル

テキストファイルをダウンロードさせるために、まずテキストの中身を作成します。

# 中身の例
content = "test" + "'\n"
content = content + "test"

中身が作成できたらHttpResponseの第一引数に指定し、responseオブジェクトを生成します。生成したresponseオブジェクトをreturnでユーザーに返すことでブラウザ経由でダウンロードさせることができます。

response = HttpResponse(content, content_type="text/plain")
response["Content-Disposition"] = "attachment; filename=test.txt"
return response

エクセルファイル

使用するライブラリ

エクセルファイルをviews.pyで作成する方法として、以下の2つの方法が考えられます。

  1. 新規にエクセルを作成する
  2. テンプレートにデータを書き込み、新たにエクセルを作成する

新規でエクセルファイルを一から作成する場合は「xlsxwriter」を用います。標準ライブラリではないのでpipコマンドでインストールします。

pip install xlsxwriter

xlsxwriterは名前の通りエクセルファイル(拡張子xlsx)の書き込みをサポートしています。

xlsxwriterでは既存ファイルの読み込みはできません。しかしエクセルファイルを新規で作成する分には豊富な機能を有しています。

既存のエクセルをテンプレートとして利用する場合は、「xlutils」「xlwt」「xlrd」といったライブラリを私は利用します。

本記事では新規でエクセルを作成する方法について解説していきます。

作成したエクセルをダウンロードさせる

views.pyで新規作成したエクセルをユーザーにダウンロードさせる方法を解説していきます。

ここで利用するライブラリはxlsxwriter、ioです。スクリプトの先頭で次のようにインポートしておきます。

import xlsxwriter
import io

次にメモリ内にエクセルファイルを作成します。ioのBytesIOメソッドとxlsxwriterのWorkbookメソッドを次のように使用します。

output = io.BytesIO()
book = xlsxwriter.Workbook(output)

io.BytesIO()はデータをメモリ上にバイナリデータとしてバッファ(一時的にメモリに保存すること)する機能です。これにより作成するエクセルをわざわざファイルとして保存することなく、メモリ上で操作できます。

エクセルの見出しやそれ以外でフォントを変更したい場合、add_format()メソッドを使ってそれぞれのフォントフォーマットを作成しておきます。

#見出し用のフォーマット
titleformat=book.add_format({'bold': True, 'font_color': 'black', 'font_size':'14', 'bg_color':'#FFB900'})
#通常の文字用フォーマット
style_text = book.add_format({'bold': False, 'font_size':'14'})

次にエクセルに新規でシートを追加します。新規でシートを追加するためには、add_worksheet()メソッドを利用し、引数にシート名を指定します。

ws = book.add_worksheet('test')

ここで作成したシートwsに対して文字の書き込みを行います。
文字の書き込みは基本的にwrite()メソッドを使えば問題ないです。

構文

write(行番号, 列番号, 入力する文字列, (フォーマット))

write()メソッドを使ってシートwsに見出しを記入してみます。

ws.write(0, 0, 'ID', titleformat)
ws.write(0, 1, 'Date', titleformat)
ws.write(0, 2, 'Status', titleformat)
ws.write(0, 3, 'Priority', titleformat)
ws.write(0, 4, 'Title', titleformat)
ws.write(0, 5, 'Details', titleformat)

エクセルへの記入が終わったら必ずclose()メソッドでエクセルを閉じるようにしてください。

book.close()

作成したエクセルはHttpResponseでresponseオブジェクトを生成し、returnでブラウザに返します。

output.seek(0)
filename = 'test.xlsx'
officedocument.spreadsheetml.sheet')
response = HttpResponse(output, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response

CSSファイル

views.pyでCSSファイルを生成し、そのファイルをブラウザ経由でユーザーにダウンロードさせます。

ここではcsvライブラリをインポートして利用します。

import csv

以下の流れでCSVファイルを生成し、ユーザーにダウンロードさせます。

response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment;  filename="office54.csv"'
writer = csv.writer(response)
writer.writerow(['1', 'office'])
writer.writerow(['2', 'five'])
writer.writerow(['3', 'four'])

return response

まとめ

本記事「【Django】ファイル(エクセル・CSS・テキスト)をダウンロードさせる(出力する)方法」はいかがでしたか。

Webアプリケーションを作成していると、ファイルをダウンロードさせる機能を実装する機会は多いです。

本記事を参考にして様々なファイルのダウンロード機能を実装してみてください。