【Django】テンプレートを元に作成したエクセルをダウンロードさせる方法

時計 2022.03.26 / 時計

【Django】テンプレートを元に作成したエクセルをダウンロードさせる方法

本記事ではDjangoテンプレートを元に作成したエクセルをユーザーにダウンロードさせる方法について解説していきます。

Webアプリケーションでは、ユーザーに特定のファイルを保存(ダウンロード)させたい場面が多々あります。またその際に、あるテンプレートをユーザー毎に編集して、それをダウンロードさせたいこともあります。

Djangoでは非常に簡単に特定のファイルをダウンロードさせる機能を実装できます。

本記事を通して、編集したエクセルをユーザーにダウンロードさせる方法の理解を深めてください。

テンプレートを利用せずに一からエクセルやテキストファイル、CSVを作成する方法については以下記事をご参照ください。

事前準備

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の設定について詳しくは以下記事をご参照ください。

ここで解説する内容は、以下構成の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の詳しい使用方法については以下記事をご参照ください。

以下の流れで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アプリケーションに追加してみてください。