Django как создать tmp excel файл и вернуть его браузеру в ответе
У меня есть процесс для создания tmp-файла и последующего возврата его в браузер в формате csv. Теперь я хочу сделать то же самое, но вернуть файл excel.
Итак, что у меня есть для csv - это представление в django, которое делает:
def export_wallet_view(request):
tmp = tempfile.NamedTemporaryFile(delete=False)
with open(tmp.name, 'w', encoding="utf-8-sig") as fi:
csv_headers = [
'Id',
'Name'
]
fi.write(';'.join(csv_headers))
fi.write('\n')
//here also i save the rows into the file
response = FileResponse(open(tmp.name, 'rb'))
response['Content-Disposition'] = 'attachment; filename="wallet.csv"'
return response
Чтобы преобразовать его в excel, я пытаюсь сделать что-то вроде этого, используя pandas:
df = pd.read_csv(tmp.name)
df.to_excel('pandas_to_excel.xlsx', sheet_name='new_sheet_name')
Проблема в том, что это создает excel на сервере, а я хотел бы сделать что-то вроде:
df = pd.read_csv(tmp.name)
df.to_excel('pandas_to_excel.xlsx', sheet_name='new_sheet_name') //this being a tmp file
response = FileResponse(open(tmp.name, 'rb')) //this should be the new excel tmp file
response['Content-Disposition'] = 'attachment; filename="wallet.csv"'
return response
Спасибо
Я не понимаю вашей проблемы.
Вы должны использовать один и тот же 'pandas_to_excel.xlsx'
в обоих
df.to_excel('pandas_to_excel.xlsx', ...)
... open('pandas_to_excel.xlsx', 'rb')
или одинаковые tmp.name
в обоих
df.to_excel(tmp.name, ...)
... open(tmp.name, 'rb')
Вы можете даже использовать еще раз NamedTemporaryFile()
для создания нового временного имени.
tmp = tempfile.NamedTemporaryFile(delete=False)
df.to_excel(tmp.name, ...)
... open(tmp.name, 'rb')
Но популярным методом является использование io.String()
или io.Bytes()
для создания файлоподобного объекта в памяти - без создания файла на диске.
def export_wallet_view(request):
csv_headers = ['Id', 'Name']
file_like_object = io.Bytes()
file_like_object.write(';'.join(csv_headers).encode('utf-8-sig'))
file_like_object.write('\n'.encode('utf-8-sig'))
file_like_object.write('other rows'.encode('utf-8-sig'))
file_like_object.seek(0) # move to the beginning of file
response = FileResponse(file_like_object)
response['Content-Disposition'] = 'attachment; filename="wallet.csv"'
return response
Для excel это может быть что-то вроде этого. Я использую io.String()
для чтения csv
непосредственно в pandas
, а затем я использую io.Bytes()
для создания файлоподобного объекта с данными excel.
def export_wallet_view(request):
csv_headers = ['Id', 'Name']
text = ';'.join(csv_headers)
text += '\n'
text += 'other rows'
df = pd.read_csv(io.String(text))
file_like_object = io.Bytes()
df.to_excel(file_like_object)
file_like_object.seek(0) # move to the beginning of file
response = FileResponse(file_like_object)
response['Content-Disposition'] = 'attachment; filename="pandas_to_excel.xlsx"'
return response