1、前述介紹
我在測試一個(gè)智能對話項(xiàng)目時(shí)需要評(píng)估對話的準(zhǔn)確率菩收,就設(shè)計(jì)了一些問題放到excel表中梨睁,讀取問題并觸發(fā)問答后把響應(yīng)信息按需要的數(shù)據(jù)寫入到另外一個(gè)excel中∧榷基于這個(gè)坡贺,我分別寫了讀excel函數(shù)和寫excel函數(shù)。
寫入文件的內(nèi)容content示例說明:
格式:{key:[[list]]},key為sheet名稱拴念,value中的最外層的列表元素為行數(shù)據(jù)钧萍,最內(nèi)層的list元素為列數(shù)據(jù)
如:
{
'第1個(gè)sheet表':[[第1行第1列內(nèi)容, 第1行第2列內(nèi)容, ..., 第1行第n列內(nèi)容], [第2行第1列內(nèi)容, 第2行第2列內(nèi)容, ..., 第2行第n列內(nèi)容], ..., [第m行第1列內(nèi)容, 第m行第2列內(nèi)容, ..., 第m行第n列內(nèi)容]],
'第2個(gè)sheet表':[[第1行第1列內(nèi)容, 第1行第2列內(nèi)容, ..., 第1行第n列內(nèi)容], [第2行第1列內(nèi)容, 第2行第2列內(nèi)容, ..., 第2行第n列內(nèi)容], ..., [第m行第1列內(nèi)容, 第m行第2列內(nèi)容, ..., 第m行第n列內(nèi)容]],
...
'第n個(gè)sheet表':[[第1行第1列內(nèi)容, 第1行第2列內(nèi)容, ..., 第1行第n列內(nèi)容], [第2行第1列內(nèi)容, 第2行第2列內(nèi)容, ..., 第2行第n列內(nèi)容], ..., [第m行第1列內(nèi)容, 第m行第2列內(nèi)容, ..., 第m行第n列內(nèi)容]]
}
使用方法、注意事項(xiàng)政鼠、參數(shù)介紹等均在源碼中有注釋风瘦,不在這里贅述,下面直接看源碼公般。
讀excel表文章地址:http://www.reibang.com/p/f380dbd9cb73
2万搔、源碼
# 寫excel文件
def writeExcel(writeExcelPath='', writeExcelName='', sheetHeaders=None, content=None):
import xlwt, datetime, random, os, time, json
# 參數(shù)說明
# writeExcelPath 寫入文件的絕對路徑,如果不指定官帘,默認(rèn)在當(dāng)前目錄下生成文件瞬雹,如r"E:\test"
# writeExcelName 生成的文件名稱(aa.xls aa.xlsx),如果不指定或者與路徑下的文件名稱重復(fù)刽虹,名稱默認(rèn)為當(dāng)前時(shí)間加隨機(jī)數(shù)字
# excelHeaders sheet表的表頭信息酗捌,必須時(shí)列表格式,否則表頭為空涌哲,順序?yàn)榱斜碇性氐捻樞蚺昼停袷剑? # [[sheet1_h1, sheet1_h2, ..., sheet1_hn], [sheet2_h1, sheet2_h2, ..., sheet2_hn], ...]
# content 要寫入的內(nèi)容,從第二行開始寫入阀圾,默認(rèn)為空哪廓,格式支持字典格式和json格式。格式:
# {sheetname1:[第一行[第一列content1, 第二列content2, ...], 第二行[第一列content3, 第二列content4, ...], ...], ...}
# 注意1:如果路徑中出現(xiàn)轉(zhuǎn)義字符初烘,如\t涡真,\n等,路徑前面加r肾筐,如 r"E:\test\aa.txt"
# 注意2:不能往已有文件中寫入數(shù)據(jù)哆料,只能新增一個(gè)文件
# 注意3:如果len(sheetHeaders)大于len(content)會(huì)生成部分只有表頭的sheet,如果兩個(gè)相等則生成的sheet都帶表頭局齿,否則會(huì)有部分不帶表頭
writeExcelPath = str(writeExcelPath)
writeExcelName = str(writeExcelName)
try:
# 獲取當(dāng)前目錄
currentPath = os.path.dirname(os.path.abspath(__file__))
# 如果sheetHeaders不是列表剧劝,轉(zhuǎn)為列表橄登,并將表頭中的數(shù)字轉(zhuǎn)為字符串
if not isinstance(sheetHeaders, list):
sheetHeaders = [[sheetHeaders]]
if sheetHeaders == []:
sheetHeaders = [sheetHeaders]
sheetHeadersTem = []
for x in range(0, len(sheetHeaders)):
tem = sheetHeaders[x]
if not isinstance(tem, list):
aa = []
aa.append(str(tem))
sheetHeadersTem.append(aa)
else:
bb = []
for temItem in tem:
bb.append(str(temItem))
sheetHeadersTem.append(bb)
sheetHeaders = sheetHeadersTem
# 如果conten是json格式抓歼,轉(zhuǎn)為字典,否則將提示信息寫入到excel的第一個(gè)sheet中
if not isinstance(content, dict):
try:
content = json.loads(content)
except:
# return 'content格式不正確拢锹,請按格式設(shè)置谣妻。'
content = {
'':[
["寫入的內(nèi)容格式不正確,寫入失敗卒稳。"],
["格式:{sheetname1:[第一行[第一列content1, 第二列content2, ...], 第二行[第一列content3, 第二列content4, ...], ...], ...}"],
[
'''示例:{
'第1個(gè)sheet表':[[第2行第1列內(nèi)容, 第2行第2列內(nèi)容, ..., 第2行第n列內(nèi)容], [第3行第1列內(nèi)容, 第3行第2列內(nèi)容, ..., 第3行第n列內(nèi)容], ..., [第m行第1列內(nèi)容, 第m行第2列內(nèi)容, ..., 第m行第n列內(nèi)容]],
'第2個(gè)sheet表':[[第2行第1列內(nèi)容, 第2行第2列內(nèi)容, ..., 第2行第n列內(nèi)容], [第3行第1列內(nèi)容, 第3行第2列內(nèi)容, ..., 第3行第n列內(nèi)容], ..., [第m行第1列內(nèi)容, 第m行第2列內(nèi)容, ..., 第m行第n列內(nèi)容]],
...
'第n個(gè)sheet表':[[第2行第1列內(nèi)容, 第2行第2列內(nèi)容, ..., 第2行第n列內(nèi)容], [第3行第1列內(nèi)容, 第3行第2列內(nèi)容, ..., 第3行第n列內(nèi)容], ..., [第m行第1列內(nèi)容, 第m行第2列內(nèi)容, ..., 第m行第n列內(nèi)容]]
}'''
]
]
}
# 處理寫入文件的目錄和文件名稱
if writeExcelPath == '' or not os.path.isdir(os.path.abspath(writeExcelPath)):
writeExcelPath = currentPath
writeExcelPath = writeExcelPath.rstrip(r'\\') + r'\\'
isFileExist = os.path.isfile(writeExcelPath + writeExcelName)
isNoName = writeExcelName.split('.')[0]
isRightExtension = writeExcelName.endswith('.xls') or writeExcelName.endswith('.xlsx')
if isFileExist or not isNoName or not isRightExtension:
writeExcelName = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + ''.join(random.sample('04512346789567012389', 4)) + ".xls"
filePath = writeExcelPath + writeExcelName
# 設(shè)置sheet表頭樣式
wb = xlwt.Workbook(encoding='utf-8')
font = xlwt.Font()
font.bold = True
style = xlwt.easyxf()
style.font = font
# 處理非字符串類型的sheetName(其他類型的sheetName會(huì)報(bào)錯(cuò))
sheetNameList = list(content.keys())
# 處理非字符串的sheetname蹋半,否則會(huì)報(bào)錯(cuò)
for k in range(0, len(sheetNameList)):
if not isinstance(sheetNameList[k], str):
content[str(sheetNameList[k])] = content.pop(sheetNameList[k])
# 按內(nèi)容中的sheetname的個(gè)數(shù)和sheet表頭的個(gè)數(shù)來確定sheet表的最大數(shù)量
contentSheets, headerSheets = len(content), len(sheetHeaders)
if contentSheets > headerSheets:
for j in range(0, contentSheets - headerSheets):
sheetHeaders.append([])
elif contentSheets < headerSheets:
for jj in range(0, headerSheets - contentSheets):
sheetNameRand = 'randomSheet' + str(jj+1)
if sheetNameRand in sheetNameList:
sheetNameRand = 'randomSheet' + ''.join(random.sample('019280190192837465', random.randint(1, 3))) + ''.join(random.sample('019280190192837465', random.randint(1, 3)))
content[sheetNameRand] = []
sheetNameList.append(sheetNameRand)
# 準(zhǔn)備寫入excel
for i in range(0, len(content)):
sheetName = str(sheetNameList[i])
contentList = content[sheetName]
# sheetName為空時(shí)自動(dòng)生成一個(gè),如果sheetName已存在充坑,則在后面添加加下劃線和隨機(jī)數(shù)
if not sheetName:
sheetName1 = 'randomSheet'+ ''.join(random.sample('045123467804512346704512346789567012389895670123899567012389', random.randint(1,6)))
ws = wb.add_sheet(sheetName1)
else:
ws = wb.add_sheet(sheetName)
# 設(shè)置sheet表頭信息
if i <= headerSheets:
for ii in range(0, len(sheetHeaders[i])):
ws.write(0, ii, sheetHeaders[i][ii], style)
# 處理寫入的行數(shù)據(jù)减江,如果行數(shù)據(jù)類型不是列表則默認(rèn)寫入第二行第一列的單元格
if not isinstance(contentList, list):
ws.write(1, 0, contentList)
continue
for row in range(0, len(contentList)):
# 處理寫入的列數(shù)據(jù)染突,如果列數(shù)據(jù)類型不是列表則默認(rèn)寫入當(dāng)前行第一列的單元格
if not isinstance(contentList[row], list):
ws.write(row+1, 0, contentList[row])
continue
# 寫入數(shù)據(jù)
for col in range(0, len(contentList[row])):
ws.write(row+1, col, contentList[row][col])
# 生成excel文件
try:
f = open(filePath, 'r')
f.close()
except IOError:
f = open(filePath, 'w')
wb.save(filePath)
return {'結(jié)果': '寫文件成功', '文件地址': filePath}
except Exception as e:
return {'結(jié)果': '寫文件失敗', '錯(cuò)誤信息': e}
3、調(diào)用及結(jié)果(8種情況)
3.1 正常寫入-內(nèi)容中的sheet比表頭中的sheet多
if __name__ == '__main__':
content = {'商品訂單':[['001','002'], ['003','004'], ['005','006', '007']],
'下單人及支付金額':[['秦始皇',32], ['乾隆',18.96], ['李世民']],
'商品列表': ['', ['西紅柿', '5元/kg'], ['火龍果', '18.9元/kg']]
}
sheetHeaders = [['主單號(hào)','子單號(hào)'],['姓名','金額']]
bb = writeExcel(writeExcelPath=r'', writeExcelName='', content=content,sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\test\\mytest\\\\202009251709435280.xls'}
打開 202009251709435280.xls 如下
3.2 正常寫入-內(nèi)容中的sheet比表頭中的sheet少
if __name__ == '__main__':
content = {'商品訂單':[['001','002'], ['003','004'], ['005','006', '007']],
'下單人及支付金額':[['秦始皇',32], ['乾隆',18.96], ['李世民']],
'商品列表': ['人參果', ['西紅柿', '5元/kg'], ['火龍果', '18.9元/kg']]
}
sheetHeaders = [['主單號(hào)','子單號(hào)'], ['姓名','金額'], ['商品名稱','單價(jià)', '規(guī)格'], ['日收入總額','周收入總額','月收入總額']]
bb = writeExcel(writeExcelPath=r'E:\aa\bb', writeExcelName='商品及訂單信息表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\aa\\bb\\\\商品及訂單信息表.xls'}
打開 商品及訂單信息表.xls 如下
3.3 正常寫入-內(nèi)容中的sheet與表頭中的sheet相等
if __name__ == '__main__':
content = {'商品訂單':[['001','002'], ['003','004'], ['005','006', '007']],
'下單人及支付金額':[['秦始皇',32], ['乾隆',18.96], ['李世民']],
'商品列表': ['人參果', ['西紅柿', '5元/kg'], ['火龍果', '18.9元/kg']]
}
sheetHeaders = [['主單號(hào)','子單號(hào)'], ['姓名','金額'], ['商品名稱','單價(jià)', '規(guī)格']]
bb = writeExcel(writeExcelPath=r'E:\aa\bb', writeExcelName='商品及訂單信息表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\aa\\bb\\\\202009251730313144.xls'}
說明:由于3.2中已經(jīng)生成了“商品及訂單信息表.xls”辈灼,重名的時(shí)候會(huì)自動(dòng)生成新文件
打開 202009251730313144.xls 文件如下
3.4 正常寫入-寫入數(shù)據(jù)為空
if __name__ == '__main__':
content = {}
sheetHeaders = [['主單號(hào)','子單號(hào)'], ['姓名','金額'], ['商品名稱','單價(jià)', '規(guī)格']]
bb = writeExcel(writeExcelPath=r'E:\aa\bb', writeExcelName='商品及訂單信息表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\aa\\bb\\\\202009251742189129.xls'}
打開 202009251742189129.xls 文件如下
3.5 正常寫入-sheet表頭為空
if __name__ == '__main__':
content = {'商品訂單':[['001','002'], ['003','004'], ['005','006', '007']],
'':[['秦始皇',32], ['乾隆',18.96], ['李世民']],
'商品列表': ['人參果', ['西紅柿', '5元/kg'], ['火龍果', '18.9元/kg']]
}
sheetHeaders = []
bb = writeExcel(writeExcelPath=r'E:\aa\bb', writeExcelName='商品及訂單信息表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\aa\\bb\\\\202009251749380755.xls'}
打開 202009251749380755.xls 文件如下
3.6 正常寫入-寫入數(shù)據(jù)和sheet表頭為空
if __name__ == '__main__':
content = {}
sheetHeaders = []
bb = writeExcel(writeExcelPath=r'E:\aa\bb', writeExcelName='商品及訂單信息表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\aa\\bb\\\\商品及訂單信息表-空表.xls'}
打開 商品及訂單信息表-空表.xls 文件如下
3.7 格式錯(cuò)誤-目錄不存在
if __name__ == '__main__':
content = {}
sheetHeaders = []
bb = writeExcel(writeExcelPath=r'E:\aa\bbc', writeExcelName='商品及訂單信息表-空表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\test\\mytest\\\\商品及訂單信息表-空表.xls'}
說明:E:\aa\bbc目錄不存在份企,默認(rèn)將文件生成到了項(xiàng)目文件所在的目錄下E:\\test\\mytest
目錄及打開文件的截圖如下
3.8 格式錯(cuò)誤-內(nèi)容格式錯(cuò)誤
if __name__ == '__main__':
content = 'test'
sheetHeaders = []
bb = writeExcel(writeExcelPath=r'E:\aa\bb', writeExcelName='商品及訂單信息表.xls', content=content, sheetHeaders=sheetHeaders)
print(bb)
結(jié)果:{'結(jié)果': '寫文件成功', '文件地址': 'E:\\aa\\bb\\\\202009251802139493.xls'}
說明:由于content給了字符串,不是字典類型巡莹,內(nèi)容寫入失敗司志,并將錯(cuò)誤信息寫入到excel中。(如果使用集成工具降宅,如pycharm骂远,傳參不符合類型時(shí)會(huì)有提示,見下圖2)
打開 202009251802139493.xls 文件如下
附:E:\aa\bb 和 E:\test\mytest 目錄下的文件截圖