96 lines
3.7 KiB
Python
96 lines
3.7 KiB
Python
import urllib.parse
|
||
from datetime import datetime
|
||
|
||
from django.contrib.auth.decorators import login_required
|
||
from django.contrib.staticfiles import finders
|
||
from django.http import HttpResponseBadRequest, JsonResponse, FileResponse, HttpResponseNotFound
|
||
from django.shortcuts import render
|
||
from django.urls import reverse
|
||
from openpyxl.reader.excel import load_workbook
|
||
|
||
|
||
@login_required
|
||
def dl_excel_tpl(request, template_name):
|
||
"""
|
||
该视图提供下载指定的Excel模板文件。
|
||
|
||
参数:
|
||
request: HttpRequest对象。
|
||
template_name: 请求下载的Excel模板文件的名称,期望是一个字符串。
|
||
fields: 包含字段信息的字典,用于生成Excel文件的表头和格式。
|
||
|
||
返回:
|
||
FileResponse对象,允许用户下载生成的Excel文件。
|
||
如果文件未找到,则返回一个HttpResponseNotFound响应。
|
||
"""
|
||
# 使用finders.find()根据文件名在Django的静态文件目录中查找文件的绝对路径
|
||
file_path = finders.find(f'excels/{template_name}')
|
||
|
||
# 如果文件路径不存在,返回404响应
|
||
if not file_path:
|
||
return JsonResponse("Excel模板文件不存在", status=400)
|
||
|
||
# 创建FileResponse对象,设置为以附件形式下载,设置MIME类型为Excel文件
|
||
response = FileResponse(open(file_path, 'rb'), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||
# 设置Content-Disposition头,告诉浏览器这是一个需要下载的文件
|
||
# 使用urllib.parse.quote对文件名进行URL编码,以确保文件名中包含的特殊字符不会引起问题
|
||
response['Content-Disposition'] = f'attachment; filename="{urllib.parse.quote(template_name)}"'
|
||
return response
|
||
|
||
|
||
@login_required
|
||
def common_parse(request):
|
||
if request.method == 'POST':
|
||
excel_file = request.FILES['file']
|
||
template_name = request.POST.get('template_name')
|
||
|
||
wb = load_workbook(excel_file)
|
||
sheet = wb.active
|
||
|
||
# 获取上传文件中的列名
|
||
uploaded_columns = [cell.value for cell in sheet[1]]
|
||
|
||
# 获取模板中的列名
|
||
template_path = finders.find(f'excels/{template_name}')
|
||
if not template_path:
|
||
return JsonResponse({'error': "Excel模板文件不存在"}, status=400)
|
||
|
||
template_wb = load_workbook(template_path)
|
||
template_sheet = template_wb.active
|
||
template_columns = [cell.value for cell in template_sheet[1]]
|
||
|
||
# 对比表头
|
||
if uploaded_columns != template_columns:
|
||
return JsonResponse({'error': "请使用填报模板上传"}, status=400)
|
||
|
||
# 获取数据并处理 datetime 对象
|
||
data = []
|
||
for row in sheet.iter_rows(min_row=2, values_only=True):
|
||
row_data = []
|
||
for cell in row:
|
||
if isinstance(cell, datetime):
|
||
row_data.append(cell.strftime('%Y-%m-%d'))
|
||
else:
|
||
row_data.append(cell)
|
||
|
||
# 检查行是否有非空单元格
|
||
if any(cell is not None and cell != '' for cell in row_data):
|
||
data.append(row_data)
|
||
|
||
# 存储解析数据到 session 中
|
||
request.session['columns'] = uploaded_columns
|
||
request.session['table_data'] = data
|
||
|
||
# 返回新的页面 URL
|
||
return JsonResponse({'redirect_url': reverse("excel_preview")})
|
||
else:
|
||
return JsonResponse({"error": "请求方法错误"}, status=400)
|
||
|
||
|
||
@login_required
|
||
def excel_preview(request):
|
||
columns = request.session.get('columns', [])
|
||
table_data = request.session.get('table_data', [])
|
||
|
||
return render(request, 'excel_preview_table.html', {'columns': columns, 'table_data': table_data})
|