python3.doc_66
最終投稿日:2022年6月18日
from django.views.generic import View from django.http.response import HttpResponse from io import StringIO class IndexView(View): def get(self, request): output = StringIO() output.write('First line.\n') response = HttpResponse(output.getvalue(), content_type='text/plain') response["Content-Disposition"] = 'attachment; filename=text.txt' return response
from django.views.generic import View from django.http import JsonResponse class JsonView(View): def get(self, request): j = {'hoge':'ほげ','foo':['ふ~','ばぁ']} #辞書型を引数とする return JsonResponse(j) 表示例) ブラウザには以下の様に出力される {"hoge": "\u307b\u3052", "foo": ["\u3075\uff5e", "\u3070\u3041"]} 【メモ】 JSON の内容を解析するには json ライブラリを使います。 例) import json #文字列として受け取った場合 j = '{"hoge": "\u307b\u3052", "foo": ["\u3075\uff5e", "\u3070\u3041"]}' #辞書型に変換できる data = json.loads(j) #表示結果 ⇒ {'hoge': 'ほげ', 'foo': ['ふ~', 'ばぁ']} print(data) #表示結果 ⇒ <class 'dict'> print(type(data)) #辞書型を文字列の JSON 形式に変換できる s = json.dumps(data) #表示結果 ⇒ {"hoge": "\u307b\u3052", "foo": ["\u3075\uff5e", "\u3070\u3041"]} print(s) #表示結果 ⇒ <class 'str'> print(type(s))
例1)
from django.views.generic import View
from django.shortcuts import render_to_response
class XmlView(View):
def get(self, request):
p = {}
p['status'] = 200
p['msg'] = 'Success'
#テンプレートの内容をレスポンスとして返却する
return render_to_response(
#第1:テンプレート指定、第2:通信情報(任意)
'mysite/hoge.xml', {'data':p},
#ヘッダー
content_type='application/xhtml+xml'
)
[mysite/hoge.xml]
<?xml version="1.0" encoding="utf-8" ?>
<info>
<member>
<array>
<member_id>1</member_id>
<member_name1>name1</member_name1>
</array>
</member>
</info>
例2)
from django.views.generic import View
from django.http.response import HttpResponse
class XmlView(View):
def get(self, request):
# 本来は動的に XML を作成する
xml = '<?xml version="1.0" encoding="utf-8" ?>'
xml += '<info><member><array><member_id>1</member_id>';
xml += '<member_name1>name1</member_name1></array></member></info>';
#テンプレートを使わずに送信
return HttpResponse(
xml,
#ヘッダー
content_type='application/xhtml+xml'
)
ライブラリ openpyxl を使います。 ※Anaconda3 があれば既に入っています 【注意】拡張子[xlsx/xlsm/xltx/xltm]のみ対応です 例) from django.shortcuts import render from django.http.response import HttpResponse from django.views.generic import View import os import openpyxl class XlsView(View): def get(self, request): #アップロード用の html を指定 return render(request, 'mysite/xls.html', {}) def post(self, request): #ファイルが指定されてない場合は何もしない if 'updata' not in request.FILES: return render(request, 'mysite/xls.html', {}) else: obj = request.FILES['updata'] #ファイルの拡張子を取得 ext = obj.name[obj.name.find('.') + 1:] #使用可能な拡張子かチェック if ext not in ['xlsx','xlsm']: return render(request, 'mysite/xls.html', {}) else: dir = os.path.dirname(__file__) #保存したい場合はここでフルパスを設定 file_path = os.path.join( dir, 'foo.' + ext ) #エクセル VBA の有無を設定 vba_flg = {'xlsx':False, 'xlsm':True} #エクセルを開く book = openpyxl.load_workbook(obj, keep_vba=vba_flg[ext]) #シートの 0番目を取得 sheet = book.worksheets[0] #A5 セルに文字列代入 sheet['A5'] = 'ふが~' # -------------------------- サーバへ保存する場合 ------------------------------ book.save(file_path) print('おわり~') return render(request, 'mysite/xls.html', {}) # -------------------------- ブラウザからダウンロードする場合 ------------------- new_file_name = 'foo' + '.' + ext response = HttpResponse(content_type= 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response['Content-Disposition'] = "attachment; filename='" + new_file_name + "'" book.save(response) return response [mysite/xls.html] <html> <head> <title>アップロード</title> </head> <body> <form method='post' action='' enctype='multipart/form-data'> <input type='file' name='updata'> {% csrf_token %} <input type='submit' value='送信'> </form> </body> </html> 【メモ】 サンプルのライブラリは旧エクセルフォーマットには対応していません。 一応旧フォーマットを操作するライブラリは以下があります。 xlrd エクセルを読み込むライブラリ xlwt エクセルを書き込むライブラリ 使い方例1) import xlrd book = xlrd.open_workbook('test_book.xlsx') sheet_1 = book.sheet_by_index(0) sheet_2 = book.sheet_by_name('hoge') col = sheet_1.ncols ※列数取得 row = sheet_1.nrows ※行数取得 使い方例2) import xlwt book = xlwt.Workbook() ※ブックを新規作成 s = book.add_sheet('hoge') ※シートを新規作成 s.write(0, 5, 'ほげ') ※E1に「ほげ」と入力 book.save('foo.xls') ※保存お分かりの通りこの2つのライブラリは別々なので双方のインスタンスに互換性はありません。
例)
import os
import xlrd
import xlwt
from xlutils.copy import copy
import openpyxl
class XlsView(View):
def get(self, request):
return render(request, 'mysite/xls.html', {})
def post(self, request):
if 'updata' not in request.FILES:
return render(request, 'mysite/xls.html', {})
else:
obj = request.FILES['updata']
ext = obj.name[obj.name.find('.') + 1:]
if ext not in ['xls']:
return render(request, 'mysite/xls.html', {})
else:
dir = os.path.dirname(__file__)
file_path = os.path.join( dir, 'foo.' + ext )
save_path = os.path.join( dir, 'hoge.' + ext )
#新しく空のファイルを開き
destination = open(file_path, 'wb+')
for chunk in obj.chunks():
#アップロードしたエクセルを待避する
destination.write(chunk)
#で、改めてそのファイルをオープンする
rb = xlrd.open_workbook(file_path, formatting_info=True, on_demand=True)
#この処理で wb は、xlwt のインスタンスになっています。
wb = copy(rb)
s = wb.add_sheet('hoge')
s.write(5, 0, 'ほげ~')
wb.save(save_path)
print('おわり~')
return render(request, 'mysite/xls.html', {})
※なぜ一旦空のファイルを作りエクセルを待避してるかと言うと、request.FILES['updata'] の状態では、xlrd.open_workbook() でエクセルを読み取る事ができないからです。