python3往excel表中寫數(shù)據(jù)(可以設(shè)置文件目錄,文件名稱隙袁,sheet表頭痰娱,寫入的內(nèi)容)

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 如下


202009251709435280.png

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 如下


商品及訂單信息表.png

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 文件如下


202009251730313144.png

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 文件如下


202009251742189129.png

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 文件如下


202009251749380755.png

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 文件如下


商品及訂單信息表-空表.png

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

目錄及打開文件的截圖如下


目錄不存在.png

商品及訂單信息表-空表.png

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 文件如下


202009251802139493.png
圖2.png

附:E:\aa\bb 和 E:\test\mytest 目錄下的文件截圖


image.png

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腰根,一起剝皮案震驚了整個(gè)濱河市激才,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌额嘿,老刑警劉巖贸营,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異岩睁,居然都是意外死亡钞脂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門捕儒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冰啃,“玉大人,你說我怎么就攤上這事刘莹⊙忠悖” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵点弯,是天一觀的道長扇调。 經(jīng)常有香客問我,道長抢肛,這世上最難降的妖魔是什么狼钮? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮捡絮,結(jié)果婚禮上熬芜,老公的妹妹穿的比我還像新娘。我一直安慰自己福稳,他們只是感情好涎拉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般鼓拧。 火紅的嫁衣襯著肌膚如雪半火。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天季俩,我揣著相機(jī)與錄音慈缔,去河邊找鬼。 笑死种玛,一個(gè)胖子當(dāng)著我的面吹牛藐鹤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赂韵,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼娱节,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祭示?” 一聲冷哼從身側(cè)響起肄满,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎质涛,沒想到半個(gè)月后稠歉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汇陆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年怒炸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毡代。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阅羹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出教寂,到底是詐尸還是另有隱情捏鱼,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布酪耕,位于F島的核電站导梆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏迂烁。R本人自食惡果不足惜看尼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婚被。 院中可真熱鬧狡忙,春花似錦、人聲如沸址芯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谷炸。三九已至北专,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旬陡,已是汗流浹背拓颓。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留描孟,地道東北人驶睦。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像匿醒,于是被迫代替她去往敵國和親场航。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355