- 利用pandas模塊實現Excel與MySQL的互通
- 代碼實現
# 批量導入數據(速度快)
def importdata(localpath: str, db: str, foreignkey):
data = pandas.read_excel(localpath, dtype='str', keep_default_na=False) # 讀取本地上傳的excel表內容, dtype='str'防止讀取001為1這種情況,keep_default_na=False是防止空值為NULL。
verbosename = db._meta.fields # 獲取被導入數據庫的字段
rows = data.shape[0] # 獲取excel表的行數
columns = data.shape[1] # 獲取excel表的列數
querysetlist = [] # 用於儲存數據
eachdata = {} # 用於儲存每一行數據
# 外鍵需要添加_id,與數據庫中的字段保持一致
for i in range(len(verbosename)):
if verbosename[i].name in foreignkey: # 判斷是否為外鍵
verbosename[i].name = verbosename[i].name + '_id'
if len(verbosename) == columns: # 必須保證二者長度一致,順序一致。
for i in range(rows):
for j in range(len(verbosename)):
eachdata[verbosename[j].name] = data.iloc[i, j] # 不會包括表頭
querysetlist.append(db(**eachdata))
try:
db.objects.bulk_create(querysetlist) # 批量導入數據
msg = '數據導入成功,導入數據共計{}條'.format(rows)
except Exception as e:
print('報錯信息:{}'.format(e))
msg = '數據導入失敗'
return msg
else:
msg = '數據導入失敗!請檢查excel表。'
return msg
# 逐個導入數據(速度慢)
def importdata2(localpath: str, db: str, foreignkey):
data = pandas.read_excel(localpath, dtype='str', keep_default_na=False) # 讀取本地上傳的excel表內容, dtype='str'防止讀取001為1這種情況。
verbosename = db._meta.fields # 獲取被導入數據庫的字段
# for i in range(0, len(verbosename)):
# print(verbosename[i].name)
rows = data.shape[0] # 獲取excel表的行數
columns = data.shape[1] # 獲取excel表的列數
eachdata = {} # 用於儲存每一行數據
# 外鍵需要添加_id,與數據庫中的字段保持一致
for i in range(len(verbosename)):
if verbosename[i].name in foreignkey: # 判斷是否為外鍵
verbosename[i].name = verbosename[i].name + '_id'
if len(verbosename) == columns: # 必須保證二者長度一致,順序一致。
for i in range(rows):
for j in range(len(verbosename)):
eachdata[verbosename[j].name] = data.iloc[i, j] # 不會包括表頭
try:
db.objects.create(**eachdata)
msg = '數據導入成功,共計{}條'.format(rows)
except Exception as e:
print('報錯信息:{}'.format(e))
msg = '數據導入失敗'
# return msg
else:
msg = '數據導入失敗!請檢查excel表。'
return msg
def import_ceping(request):
"""導入測評人員"""
foreignkey = ['department', 'rank_id', 'post_id'] # 記錄外鍵
# 接收excel文件存儲到Media文件夾
rev_file = request.FILES.get('excel')
# 判斷是否有文件
if not rev_file:
return JsonResponse({'code': 0, 'msg': 'Excel文件不存在'})
# 獲得一個唯一的名字:uuid+hash
new_name = get_random_str()
# 准備寫入的URL
file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
# 開始寫入磁盤
try:
f = open(file_path, 'wb')
# 分多次寫入
for i in rev_file.chunks():
f.write(i)
f.close()
except Exception as e:
return JsonResponse({'code': 0, 'msg': '寫入失敗,請聯系管理員'})
# 讀取存儲在Media文件夾的數據
ex_data = importdata(file_path, Ceping, foreignkey)
return JsonResponse({'code': 1, 'msg': ex_data})
# 導出數據
def exportdata(localpath, db):
verbosename = db._meta.fields
columnname = [] # 存儲字段名
for i in range(len(verbosename)):
columnname.append(verbosename[i].name)
info = db.objects.values_list() # 查詢數據庫數據
data = pandas.DataFrame(info)
try:
data.to_excel(localpath, na_rep='NULL', header=columnname, index=False)
msg = '數據導出成功'
except Exception as e:
msg = '數據導出失敗'
return msg