import_export.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # -*- coding: utf-8 -*-
  2. import os
  3. import re
  4. from datetime import datetime
  5. import openpyxl
  6. from django.conf import settings
  7. from dvadmin.utils.validator import CustomValidationError
  8. def import_to_data(file_url, field_data, m2m_fields=None):
  9. """
  10. 读取导入的excel文件
  11. :param file_url:
  12. :param field_data: 首行数据源
  13. :param m2m_fields: 多对多字段
  14. :return:
  15. """
  16. # 读取excel 文件
  17. file_path_dir = os.path.join(settings.BASE_DIR, file_url)
  18. workbook = openpyxl.load_workbook(file_path_dir)
  19. table = workbook[workbook.sheetnames[0]]
  20. theader = tuple(table.values)[0] # Excel的表头
  21. is_update = '更新主键(勿改)' in theader # 是否导入更新
  22. if is_update is False: # 不是更新时,删除id列
  23. field_data.pop('id')
  24. # 获取参数映射
  25. validation_data_dict = {}
  26. for key, value in field_data.items():
  27. if isinstance(value, dict):
  28. choices = value.get("choices", {})
  29. data_dict = {}
  30. if choices.get("data"):
  31. for k, v in choices.get("data").items():
  32. data_dict[k] = v
  33. elif choices.get("queryset") and choices.get("values_name"):
  34. data_list = choices.get("queryset").values(choices.get("values_name"),
  35. choices.get("values_value", "id"))
  36. for ele in data_list:
  37. data_dict[ele.get(choices.get("values_name"))] = ele.get(choices.get("values_value", "id"))
  38. else:
  39. continue
  40. validation_data_dict[key] = data_dict
  41. # 创建一个空列表,存储Excel的数据
  42. tables = []
  43. for i, row in enumerate(range(table.max_row)):
  44. if i == 0:
  45. continue
  46. array = {}
  47. for index, item in enumerate(field_data.items()):
  48. items = list(item)
  49. key = items[0]
  50. values = items[1]
  51. value_type = 'str'
  52. if isinstance(values, dict):
  53. value_type = values.get('type', 'str')
  54. cell_value = table.cell(row=row + 1, column=index + 2).value
  55. if cell_value is None or cell_value == '':
  56. continue
  57. elif value_type == 'date':
  58. try:
  59. cell_value = datetime.strptime(str(cell_value), '%Y-%m-%d %H:%M:%S').date()
  60. except:
  61. raise CustomValidationError('日期格式不正确')
  62. elif value_type == 'datetime':
  63. cell_value = datetime.strptime(str(cell_value), '%Y-%m-%d %H:%M:%S')
  64. else:
  65. # 由于excel导入数字类型后,会出现数字加 .0 的,进行处理
  66. if type(cell_value) is float and str(cell_value).split(".")[1] == "0":
  67. cell_value = int(str(cell_value).split(".")[0])
  68. elif type(cell_value) is str:
  69. cell_value = cell_value.strip(" \t\n\r")
  70. if key in validation_data_dict:
  71. array[key] = validation_data_dict.get(key, {}).get(cell_value, None)
  72. if key in m2m_fields:
  73. array[key] = list(
  74. filter(
  75. lambda x: x,
  76. [
  77. validation_data_dict.get(key, {}).get(value, None)
  78. for value in re.split(r"[,;:|.,;:\s]\s*", cell_value)
  79. ],
  80. )
  81. )
  82. else:
  83. array[key] = cell_value
  84. tables.append(array)
  85. return tables