【Django】テンプレートを元に作成したエクセルをダウンロードさせる方法
2022.03.26 /
本記事ではDjangoでテンプレートを元に作成したエクセルをユーザーにダウンロードさせる方法について解説していきます。
Webアプリケーションでは、ユーザーに特定のファイルを保存(ダウンロード)させたい場面が多々あります。またその際に、あるテンプレートをユーザー毎に編集して、それをダウンロードさせたいこともあります。
Djangoでは非常に簡単に特定のファイルをダウンロードさせる機能を実装できます。
本記事を通して、編集したエクセルをユーザーにダウンロードさせる方法の理解を深めてください。
テンプレートを利用せずに一からエクセルやテキストファイル、CSVを作成する方法については以下記事をご参照ください。
【Django】ファイル(エクセル・CSS・テキスト)をダウンロードさせる(出力する)方法
事前準備
mediaフォルダの作成
テンプレートとなるエクセルファイルを保存するフォルダを作成します。ここでは名前をmediaとします。
mediaフォルダはベースフォルダ(manage.pyが置いてあるフォルダ)に作成してください。
テンプレートのエクセルファイルは今作成したmediaフォルダに保存しておきます。
settings.py:メディア設定の追加
前項で作成したmediaフォルダを通してテンプレートを取得するために以下の設定をsettings.pyに追記します。
import os
MEDIA_URL = '/media/'
if DEBUG:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
else:
MEDIA_ROOT = f'/var/www/{BASE_DIR.name}/media'
上記設定を詳しく知りたい方はこちらをご覧ください。
urls.py
プロジェクト内のurls.pyに以下を追記します。
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
…
]
# 以下を追加する
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
テンプレートを元に作成したエクセルをダウンロードさせる:views.py
テンプレートを元に作成したエクセルをユーザーにダウンロードさせる方法を解説していきます。
本記事では本番環境ではなく、テスト環境で実行しています。つまりDebug=Trueということです。Debugの設定について詳しくは以下記事をご参照ください。
【Django】settings.py:Debug=Trueは本番環境公開前にFalseにすべき理由
ここで解説する内容は、以下構成のWebサイトでユーザーがリンクをクリックしたら、テンプレートを編集したエクセルがダウンロードされる仕組みです。
# HTML
<a href='{% url "office:download_excel " %}'>エクセルダウンロード</a>
# urls.py
from django.urls import path
from . import views
app_name = 'office'
urlpatterns = [
path('download-excel', views.download_excel, name='download_excel'),
]
# views.py
from django.conf import settings
from django.http import HttpResponse
import openpyxl
def download_excel(request):
# ここに処理を記述
本記事ではエクセルの操作にopenpyxlを使用します。事前にpipでopenpyxlをインストールしておいてください。
pip install openpyxl
openpyxlの詳しい使用方法については以下記事をご参照ください。
【Python】openpyxl:基本的なエクセル操作方法を徹底解説
以下の流れでviews.pyに処理を記述していきます。
- テンプレートのエクセルを開く
- 開いたエクセルを編集する
- ユーザーにエクセルをダウンロードさせる
各処理について詳しく見ていきましょう。
テンプレートのエクセルを読み込む
まずテンプレートのエクセルファイルを読み込みます。テンプレートはmediaフォルダに保存しておきます。ここではtemplate.xlsxという名前のテンプレートエクセルを読み込みます。
wb = openpyxl.load_workbook(settings.BASE_DIR + '/media/template.xlsx')
ws = wb.active
openpyxl.load_workbook()関数でテンプレートを読み込み(Workbookオブジェクトが生成)、アクティブになっているシートのWorksheetオブジェクトを取得しています。
これらWorkbookオブジェクトやWorksheetオブジェクトを編集およびユーザーにダウンロードさせます。
開いたエクセルを編集する
テンプレートから取得したWorksheetオブジェクトをユーザーにダウンロードさせたい形に編集していきます。
ここではセル(1,1)にtestという文字を挿入してみます。
ws.cell(1,1).value = "test"
ユーザーにエクセルをダウンロードさせる
最後にユーザーに編集したエクセルをダウンロードさせる処理を記述します。
つまりユーザーに返すHTTPレスポンスにエクセルファイルを含ませるということです。
HTTPレスポンス
ユーザーはWebサイト(ブラウザ)を通してサーバーにHTTPリクエストを送ります。このHTTPリクエストとは、新しいページの閲覧や情報の登録などをするための要求です。
本記事ではユーザーからファイルをダウンロードしたいという要求がサーバーへ送られています。
この要求(HTTPリクエスト)に対する応答がHTTPレスポンスです。
つまりブラウザはHTTPリクエストをサーバーに送り、サーバーはHTTPレスポンスをブラウザに送るということです。
views.pyの関数ではreturnで指定した内容をHTTPレスポンスで返しています。ここではHttpResonseを使用して生成したオブジェクトをreturnでユーザーに返すことでダウンロードさせます。
つまりHttpResponseオブジェクトにエクセルファイルを含めて、returnでHttpResponseオブジェクトをユーザーに返すということです。
HttpResponse()は以下構文となっております。
HttpResponse(ファイルデータ, content_type=ファイル形式)
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_typeはapplication/vnd.ms-excelです。
HttpResponseにテンプレートを編集したエクセルを含ませるには次のように記述します。
response = HttpResponse(content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=%s' % 'template.xlsx'
wb.save(response)
あとはHttpResponseをreturnすることでユーザーはブラウザを通してエクセルファイルをダウンロードします。
return response
まとめ
本記事「【Django】テンプレートを元に作成したエクセルをダウンロードさせる方法」はいかがでしたか。
ユーザーに特定のファイルをダウンロードさせたい場面は多々あります。
本記事で紹介した方法はエクセルだけでなく、ワードやPDF、画像などすべてのファイル形式で利用できます。
ぜひ本記事を参考にして、ファイルをダウンロードさせる機能をご自身のWebアプリケーションに追加してみてください。