1.下载临时excel
from io import BytesIO
from django.http import FileResponse
import pandas as pd
try:
bio = BytesIO()
writer = pd.ExcelWriter(bio, engine='xlsxwriter')
df.to_excel(writer, sheet_name='sheet1', index=False, encoding='unicode_escape')
writer.save()
bio.seek(0)
response = FileResponse(bio)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = f'attachment;filename="knowledge.xlsx"'
return response
except Exception as e:
logger.error(repr(e))
return Response({}, status=status.HTTP_409_CONFLICT)
关于engine:
-`xlrd``支持旧式Excel文件(.xls)。
-`openpyxl`支持更新的Excel文件格式。
-`odf``支持OpenDocument文件格式(.odf、.ods、.odt)。
-`pyxlsb`支持二进制Excel文件。
2.下载临时zip压缩包(包含临时文件和实体文件)
from io import BytesIO
from django.http import FileResponse, HttpResponse
from tempfile import TemporaryFile, TemporaryDirectory
import pandas as pd
import os
import zipfile
def list(self, request, *args, **kwargs):
...
# excel文件
bio = BytesIO()
writer = pd.ExcelWriter(bio)
# writer = pd.ExcelWriter(bio, engine='xlsxwriter')
df.to_excel(writer, sheet_name='sheet1', index=False, encoding='unicode_escape')
writer.save()
bio.seek(0)
# 带有图片和excel的临时压缩文件
with TemporaryFile(suffix='zip') as tmp_file:
with zipfile.ZipFile(tmp_file, 'w', zipfile.ZIP_DEFLATED) as f:
# 文件流形式1
f.writestr('knowledge.xlsx', bio.read())
# 文件流形式2
tmp2 = tempfile.TemporaryFile()
tmp2.writer('C:xx.png')
tmp2.close()
# 实体文件形式,my:压缩包中的文件夹,可省略
f.write('C:xx.png', 'my/1676424153241488.png')
tmp_file.seek(0)
response = HttpResponse(tmp_file.read())
response['Content-Type'] = 'application/x-zip-compressed'
# response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = f'attachment;filename="knowledge.zip"'
return response
3.下载media文件
def list(self, request, *args, **kwargs):
file = open(os.path.join(IMAGES_DIR, 'knowledge_template.xlsx'), 'rb')
response = FileResponse(file)
# response['Content-Type'] = 'application/x-zip-compressed'
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = f'attachment;filename="template.xlsx"'
return response
4.上传zip文件
def batch_upload(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
file = request.FILES.get('file', None)
if not file:
return Response('文件为空.', status=status.HTTP_200_OK)
if not zipfile.is_zipfile(file):
return Response('文件不是zip格式.', status=status.HTTP_200_OK)
with zipfile.ZipFile(file, 'r') as f:
for i in f.namelist(): # 如果文件名i中存在中文 i.encode('cp437').decode('gbk')
if i == 'knowledge.xlsx': # 读到内存
df = pd.read_excel(f.extract(i))
else: # 输出到实体文件
f.extract(i, r'C:xxxx/') # 路径
return Response(queryset, status=status.HTTP_200_OK)
5.上传media文件
import urllib.request
# 生成文件名和url路径名
def gen_image_filename(filename):
suffix = os.path.splitext(filename)[-1] # 后缀带.
base_path = os.path.join(IMAGES_DIR, f"{int(time.time() * 1000000)}{suffix}")
full_path = os.path.join(settings.BASE_DIR, base_path)
base_url_path = urllib.request.pathname2url(base_path)
return base_url_path, full_path
# 获取ip和端口
def get_host_port(request):
# host = request.META.get('HTTP_X_FORWARDED_FOR', )
host_port = request.META.get('HTTP_HOST', '127.0.0.1:8000')
url_scheme = request.META.get('HTTP_X_FORWARDED_PROTO', 'http')
return url_scheme, host_port
def image(self, request, *args, **kwargs):
file = request.FILES.get('file', None)
if not file:
return Response('', status=status.HTTP_200_OK)
base_path, full_path = gen_image_filename(file.name) #
with open(full_path, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
url_scheme, host_port = get_host_port(request)
url_path = f'{url_scheme}://{host_port}/{base_path}'
return Response({'base_path': base_path, 'url_path': url_path}, status=status.HTTP_200_OK)
6.上传csv文件时编码问题
import io
import pandas as pd
from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile
isinstance(file, [TemporaryUploadedFile, InMemoryUploadedFile]) == True
file_encoding = 'utf-8'
df = pd.read_csv(io.StringIO(file.read().decode(file_encoding)))