例:
def import_data_from_excel(conf, filename, fk_name=None, fk_value=None, is_exchange=False): def valid_date(d): try: xlrd.xldate.xldate_as_datetime(d, 0) return True except: return False def check_field_with_input(field, i): t = type(field) choices = field.__dict__["choices"] if choices: for key, value in choices: if value == i.strip(): return True if field.__dict__["null"] is True and type(i) == unicode and not i.strip(): return True return False if t in [IntegerField, FloatField, ForeignKey]: return type(i) in [float, int] if t in [CharField, TextField]: return type(i) == unicode if field.__dict__["null"] is True and type(i) == unicode and not i.strip(): return True if t == DateField: return valid_date(i) return False # 检查attributes, primary_keys, defaults 定义的数据列在表里面 def check_conf(c): obj = create_instance(c) attrs = c["attributes"].keys() + c.get("primary_keys", []) if c.get("defaults", None): attrs = attrs + c["defaults"].keys() for k in attrs: if not hasattr(obj, k): print "{} has no attr '{}', please check.".format(c["class_name"], k) return False if fk_name: if not hasattr(obj, fk_name): print "{} has no foreign key '{}', please check.".format(c["class_name"], fk_name) return False return True def check_excel_input(c, sheet): rows_len, cols_len = sheet.nrows, sheet.ncols class_name = get_class(c) for r in range(1, rows_len): r_data = sheet.row_values(r) for k, v in c["attributes"].items(): if v > cols_len: return STRING_EXCEL_CONFIGURATION_EXCEEDS.format(cols_len, k, v) if not check_field_with_input(class_name._meta.get_field(k), r_data[v]): return STRING_EXCEL_LINE_INPUT_ERROR.format(r + 1, v, r_data[v]) return "success" def do_excel_input(c, sheet): item = get_class(c) rows_len, cols_len = sheet.nrows, sheet.ncols default_values = c.get("defaults", None) for r in range(1, rows_len): r_data = sheet.row_values(r) pks = conf.get("primary_keys", None) if pks: filter_dict = {} for pk in pks: field = item._meta.get_field(pk) choices = field.__dict__["choices"] if choices: for key, value in choices: if value == r_data[conf["attributes"][pk]]: filter_dict[pk] = key else: filter_dict[pk] = r_data[conf["attributes"][pk]] if fk_name and fk_value: filter_dict[fk_name] = fk_value rs = get_class(c).objects.filter(**filter_dict) d = rs[0] if len(rs) > 0 else create_instance(c) else: d = create_instance(c) for k, v in conf["attributes"].items(): if type(r_data[v]) == unicode and not str(r_data[v].strip()): continue field = d._meta.get_field(k) if type(field) == DateField: d.__setattr__(k, xlrd.xldate.xldate_as_datetime(r_data[v], 0)) elif field.__dict__["choices"]: for key, value in field.__dict__["choices"]: if value == r_data[v].strip(): d.__setattr__(k, key) else: d.__setattr__(k, r_data[v]) if fk_name and fk_value: d.__setattr__(fk_name, fk_value) # 此操作只用来对采购和发行的节目进行换片操作 if is_exchange and hasattr(d, "status"): d.__setattr__("status", 3) if default_values: for k, v in default_values.items(): # 对默认值的处理,对应若干历史财务数据 d.__setattr__(k, v) d.save() if not check_conf(conf): return STRING_IMPORT_CONFIGURATION_ERROR sheet_index = conf.get("excel_sheet", 0) # print "System will import {} sheet".format(sheet_index) try: import_sheet = xlrd.open_workbook(filename).sheet_by_index(int(sheet_index)) except: return STRING_EXCEL_OPEN_ERROR try: check_input = check_excel_input(conf, import_sheet) if not check_input == "success": return check_input do_excel_input(conf, import_sheet) return STRING_EXCEL_IMPORT_SUCCESS except Exception as e: print e return STRING_EXCEL_GET_RECORDS_ERROR
ProductItemExcelImportConfig = { "module_name": "Product.models", "class_name": "ProductItem", "attributes": { "sn": 0, # 序号 "name": 1, # 节目名称 "type": 2, # 类别 "theme": 3, # 类型 "episodes": 4, # 集数 "episodes_time": 5, # 单集时长 "total_time": 6, # 总时长 "clarity": 7, # 分辨率 "play_time": 8, # 播出时间 "play_app": 9, # 播出平台 "production_time": 10, # 出品年代 "area": 11, # 制片地区 "actor": 12, # 主演 "writers": 13, # 编剧 "director": 14, # 导演 "plots": 15, # 剧情介绍 "authorized_time": 16, # 授权开始日期 "authorized_end_time": 17, # 授权结束日期 "authorized_way": 18, # 授权方式 "authorized_area": 19, # 授权权利 "publish_licence": 20, # 发行许可证 "make_company": 21, # 制作机构 "up_copyright": 22, # 上游版权方 "copy_chain": 23, # 版权链 "site_limit": 24, # 站点限制 "item_status": 25, # 节目状态 "remark": 27, # 备注 }, "primary_keys": ["name", "authorized_area", "up_copyright"], "defaults": { "item_source": '2', # 标示从Excel数据导入 }, }
# 导入可销售节目 def import_product_items(request): try: path = get_upload_file_path() if request.method == 'POST': file_obj = request.FILES.get('file') # 判断选择文件 if file_obj: filename = os.path.join(path, file_obj.name) file_type = str(os.path.splitext(filename)[1]) # 判断文件类型 if file_type in [".xls", ".xlsx"]: # 判断文件是否重名或者是否已经存在 if os.path.exists(filename): filename = filename + time.strftime(".%Y%m%d%H%M%S", time.localtime()) # 把上传过来的文件保存 excel_file = open(filename, 'wb+') for file_data in file_obj.chunks(): excel_file.write(file_data) excel_file.close() r_url = "" res = import_data_from_excel(ProductItemExcelImportConfig, filename) result = {"statue": "success", "data": res} return JsonResponse(result) else: result = {"statue": "error", "data": "文件格式不对,必须是 xls或xlsx"} return JsonResponse(result) else: result = {"statue": "error", "data": "你没有选择文件呢!!!"} return JsonResponse(result) result = {"statue": "error", "data": "你没有选择文件呢!!!"} return JsonResponse(result) except Exception as e: return render(request, 'error.html', locals())