修改了excel解析上传

This commit is contained in:
王思川 2024-06-17 20:40:32 +08:00
parent c7b6c57f26
commit 365ad8d2b6
3 changed files with 187 additions and 4 deletions

View File

@ -2,5 +2,7 @@ from django.urls import path
from excel_parser.views import * from excel_parser.views import *
urlpatterns = [ urlpatterns = [
path('common_parse/', common_parse, name="common_parse") path('excel_preview/', excel_preview, name='excel_preview'),
path('dl_excel_tpl/<str:template_name>/', dl_excel_tpl, name='dl_excel_tpl'),
path('common_parse/', common_parse, name="ep_common_parse")
] ]

View File

@ -1,5 +1,95 @@
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.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): def common_parse(request):
return render(request, 'excel_preview_table.html') 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})

View File

@ -71,7 +71,8 @@
{% render_button 'modify_records_button' %} {% render_button 'modify_records_button' %}
{% render_button 'add_button' %} {% render_button 'add_button' %}
{% render_button 'report_excel_button' %} {% render_button 'report_excel_button' %}
{% render_button 'import_excel_button' %} {# {% render_button 'import_excel_button' %}#}
<button id="importExcelBtnTest" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#uploadModal">上传Excel(测试)</button>
</div> </div>
</div> </div>
</div> </div>
@ -173,16 +174,56 @@
</div> </div>
</div> </div>
<div id="uploadModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="uploadModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form id="upload-form" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title" id="uploadModalLabel">上传Excel文件</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input id="inputFile" type="file" name="excel_file" class="form-control" hidden accept=".xlsx">
<label class="btn btn-outline-primary" for="inputFile">选择文件</label>
<span id="file-chosen" style="font-size: 12px; margin-left: 10px;">未选择文件</span>
</div>
<div class="modal-footer">
<button id="downloadExcelBtn" type="button" class="btn btn-secondary" onclick="#!">下载填报模板</button>
<button id="uploadBtn" type="button" class="btn btn-primary">上传Excel</button>
</div>
</form>
</div>
</div>
</div>
{% include 'modify_record_modal.html' with modify_records_url=modify_records_url %} {% include 'modify_record_modal.html' with modify_records_url=modify_records_url %}
{% include 'upload_excel_modal.html' with excel_upload_config=excel_upload_config %}
<script> <script>
const add_url = "{{ add_url }}"; const add_url = "{{ add_url }}";
const modify_url = "{{ modify_url }}"; const modify_url = "{{ modify_url }}";
const deleteUrl = "{{ delete_url }}"; const deleteUrl = "{{ delete_url }}";
let targetIdToDelete = null; let targetIdToDelete = null;
var templateName = "{{ excel_upload_config.template_name }}";
$(document).ready(function () { $(document).ready(function () {
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
// 处理添加按钮点击事件 // 处理添加按钮点击事件
$('#addItemBtn').click(function () { $('#addItemBtn').click(function () {
$.ajax({ $.ajax({
@ -285,6 +326,56 @@
$('#deleteModal').modal('hide'); $('#deleteModal').modal('hide');
} }
}); });
// 点击下载Excel模板按钮
$('#downloadExcelBtn').on('click', function () {
window.location.href = excel_upload_config.template_url;
});
// 当上传模态框显示时,清空文件输入框和文件名显示
$('#uploadModal').on('show.bs.modal', function () {
$('#inputFile').val('');
$('#file-chosen').text('未选择文件');
});
// 当选择文件变化时,更新文件名显示
$('#inputFile').on('change', function () {
var fileName = $(this).val().split('\\').pop();
$('#file-chosen').text(fileName || '未选择文件');
});
// 处理上传按钮的点击事件
$('#uploadBtn').on('click', function () {
var inputFile = $('#inputFile').get(0).files[0];
if (!inputFile) {
showAlert('danger', '未选择文件');
$('#uploadModal').modal('show');
return;
}
var formData = new FormData();
formData.append('file', inputFile); // 将文件添加到 FormData 中
formData.append('template_name', templateName);
$.ajax({
url: '{{ excel_upload_config.parse_url }}',
type: 'POST',
data: formData,
headers: {'X-CSRFToken': csrftoken},
contentType: false,
processData: false,
success: function (response) {
window.location.href = response.redirect_url;
},
error: function (xhr, status, error) {
var errorMsg = "解析Excel文件失败。";
if (xhr.responseJSON && xhr.responseJSON.error) {
errorMsg = xhr.responseJSON.error;
}
showAlert('danger', errorMsg);
}
});
});
}); });
</script> </script>