修改了excel解析上传
This commit is contained in:
parent
c7b6c57f26
commit
365ad8d2b6
|
@ -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")
|
||||||
]
|
]
|
|
@ -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})
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue