django-vue-admin/backend/dvadmin/utils/import_export.py

90 lines
3.6 KiB
Python
Raw Normal View History

2022-04-05 05:22:26 +00:00
# -*- coding: utf-8 -*-
import os
import re
from datetime import datetime
2022-04-05 05:22:26 +00:00
import openpyxl
from django.conf import settings
from dvadmin.utils.validator import CustomValidationError
2022-04-05 05:22:26 +00:00
2022-06-14 16:45:27 +00:00
def import_to_data(file_url, field_data, m2m_fields=None):
2022-04-05 05:22:26 +00:00
"""
读取导入的excel文件
2022-06-14 16:45:27 +00:00
:param file_url:
2022-04-05 05:22:26 +00:00
:param field_data: 首行数据源
2022-06-14 16:45:27 +00:00
:param m2m_fields: 多对多字段
2022-04-05 05:22:26 +00:00
:return:
"""
# 读取excel 文件
file_path_dir = os.path.join(settings.BASE_DIR, file_url)
2022-04-05 05:22:26 +00:00
workbook = openpyxl.load_workbook(file_path_dir)
table = workbook[workbook.sheetnames[0]]
2023-05-19 08:02:34 +00:00
theader = tuple(table.values)[0] # Excel的表头
is_update = '更新主键(勿改)' in theader # 是否导入更新
if is_update is False: # 不是更新时,删除id列
field_data.pop('id')
2022-06-14 16:45:27 +00:00
# 获取参数映射
validation_data_dict = {}
for key, value in field_data.items():
if isinstance(value, dict):
choices = value.get("choices", {})
2022-06-14 16:45:27 +00:00
data_dict = {}
if choices.get("data"):
for k, v in choices.get("data").items():
2022-06-14 16:45:27 +00:00
data_dict[k] = v
elif choices.get("queryset") and choices.get("values_name"):
2023-05-19 08:02:34 +00:00
data_list = choices.get("queryset").values(choices.get("values_name"),
choices.get("values_value", "id"))
2022-06-14 16:45:27 +00:00
for ele in data_list:
2023-05-19 08:02:34 +00:00
data_dict[ele.get(choices.get("values_name"))] = ele.get(choices.get("values_value", "id"))
2022-06-14 16:45:27 +00:00
else:
continue
validation_data_dict[key] = data_dict
2022-04-05 05:22:26 +00:00
# 创建一个空列表存储Excel的数据
tables = []
for i, row in enumerate(range(table.max_row)):
if i == 0:
continue
2022-04-05 05:22:26 +00:00
array = {}
for index, item in enumerate(field_data.items()):
items = list(item)
key = items[0]
values = items[1]
value_type = 'str'
if isinstance(values, dict):
2023-05-19 08:02:34 +00:00
value_type = values.get('type', 'str')
2022-04-05 05:22:26 +00:00
cell_value = table.cell(row=row + 1, column=index + 2).value
2023-05-19 08:02:34 +00:00
if cell_value is None or cell_value == '':
2022-06-15 13:57:52 +00:00
continue
elif value_type == 'date':
try:
cell_value = datetime.strptime(str(cell_value), '%Y-%m-%d %H:%M:%S').date()
except:
raise CustomValidationError('日期格式不正确')
elif value_type == 'datetime':
cell_value = datetime.strptime(str(cell_value), '%Y-%m-%d %H:%M:%S')
else:
2023-05-19 08:02:34 +00:00
# 由于excel导入数字类型后会出现数字加 .0 的,进行处理
if type(cell_value) is float and str(cell_value).split(".")[1] == "0":
cell_value = int(str(cell_value).split(".")[0])
elif type(cell_value) is str:
cell_value = cell_value.strip(" \t\n\r")
2022-06-14 16:45:27 +00:00
if key in validation_data_dict:
array[key] = validation_data_dict.get(key, {}).get(cell_value, None)
if key in m2m_fields:
array[key] = list(
filter(
lambda x: x,
[
validation_data_dict.get(key, {}).get(value, None)
for value in re.split(r"[|.,;:\s]\s*", cell_value)
],
)
)
2022-06-14 16:45:27 +00:00
else:
array[key] = cell_value
2022-04-05 05:22:26 +00:00
tables.append(array)
return tables