自動(dòng)化辦公系列2---xls/xlsx表格操作:多個(gè)表(個(gè)人信息表)導(dǎo)入單一表(匯總信息表)中

項(xiàng)目下載github
前言:這個(gè)操作Excel表格相關(guān)內(nèi)容找了很久,很多代碼都達(dá)不到想要的效果,但最后還是功夫不負(fù)有心人啊。

一、開始之前的準(zhǔn)備工作

和自動(dòng)化辦公系列1這篇一樣:自動(dòng)化辦公系列1

二、開始多表(個(gè)人信息表)導(dǎo)入單表內(nèi)容(匯總信息表)中

需求:由于經(jīng)常需要對(duì)一些現(xiàn)有的表如個(gè)人信息表進(jìn)行匯總,全部匯總到一張表內(nèi),正常情況情況下就是一頓粘貼復(fù)制咯,有點(diǎn)累吧!那就讓程序來(lái)完成。

1、創(chuàng)建py文件的時(shí)候注意,2.7.15版本默認(rèn)編碼格式不是utf-8,而我們一般操作字符都是以u(píng)tf-8的方式,故需要添加一些代碼把編碼格式轉(zhuǎn)為utf-8。python3之后默認(rèn)格式都是utf-8了。

在文件開頭添加如下代碼:

#coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

2、操作xlsx文件需要導(dǎo)入的模塊

2.1、 xlrd (讀取xls的文件內(nèi)容)
2.2、 openpyxl(把內(nèi)容寫入到xlsx文件中)
2.3、 pywin32 (方便調(diào)用windowsAPI)

3、開始編寫腳本

#coding=utf-8
import sys
import xlrd
import os
import openpyxl
import time
import pythoncom
import win32com.client as win32

reload(sys)
sys.setdefaultencoding('utf-8')


# 讀取路徑下的所有文件名
def read_file_name(file_dir):
    L = []
    for root,dirs,files in os.walk(file_dir):
        for file in files:
            L.append(file)
    return L

# 進(jìn)行xls到xlsx的轉(zhuǎn)換
def xlstoxlsx(filePath):
    if filePath.find('xls'):
        pythoncom.CoInitialize()
        excel = win32.gencache.EnsureDispatch('Excel.Application')
        filePath1 = filePath.decode('utf-8').encode('gbk')
        wb = None
        try:
            wb = excel.Workbooks.Open(filePath1)
            wb.SaveAs(filePath1 + 'x', FileFormat=51)  # FileFormat = 51 is for .xlsx extension
            print "xls轉(zhuǎn)為xlsx的絕對(duì)路徑為"+filePath + 'x'
        except IOError:
            print '文件讀寫錯(cuò)誤'
        finally:
            wb.Close()
            excel.Application.Quit()
        time.sleep(2)  # 避免未及時(shí)關(guān)閉的情況,等待關(guān)閉完成
        return filePath1 + 'x'

# 進(jìn)行xlsx到xls的轉(zhuǎn)換
def xlsxtoxls(file,filePath):
    if file.find('xlsx'):
        pythoncom.CoInitialize()
        excel = win32.gencache.EnsureDispatch('Excel.Application')
        file = file.decode('utf-8').encode('gbk')
        # 去除末尾的x[-1:]
        # filepaths = filePath.split('.')
        # filePath1 = filepaths[0]
        filePath1 = "{}".format(filePath[:-4])
        filePath1 = filePath1.decode('utf-8').encode('gbk')
        # 打開文件需要進(jìn)行異常捕獲和關(guān)閉文件
        wb = None
        try:
            wb = excel.Workbooks.Open(file)
            wb.SaveAs(filePath1 + '.xls', FileFormat=56)  # FileFormat = 51 is for .xlsx extension
            print filePath1 + '.xls'
        except IOError:
            print '該文件讀寫發(fā)生錯(cuò)誤'
        finally:
            wb.Close()
            excel.Application.Quit()
        time.sleep(1)  # 避免未及時(shí)關(guān)閉的情況,等待關(guān)閉完成
        return filePath1 + '.xls'

# 寫入到execel表格
# 先打開原表然后復(fù)制一份最后另存為
# values為單表內(nèi)容總和 startCol為開始的列數(shù) row為開始的行數(shù) col為爬取的內(nèi)容數(shù)
def wExecel(path,row,col,startCol,values):
    # 這里最開始先判斷一下填的路徑是否存在
    print "是否存在路徑判斷"+path
    if os.path.isfile(path.decode('utf-8').encode('gbk')):
        # 這里需要對(duì)路徑文件格式進(jìn)行判斷一個(gè)if語(yǔ)句
        if path.find('xlsx') != -1:                    # 把xlsx轉(zhuǎn)為xls,會(huì)把原路徑的xlsx文件替換
            xlsxPath = path.decode('utf-8').encode('gbk')
            print xlsxPath.decode('gbk').encode('utf-8')   #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
        else:
            print '文件格式為:xls'
            xlsxPath = xlstoxlsx(path)
            # 轉(zhuǎn)換完成之后需要把原來(lái)xls這個(gè)文件刪除
            path = path.decode('utf-8').encode('gbk')
            # os.remove(path)
            # print '原xls文件已刪除'
        # wb = None
        try:
            wb = openpyxl.load_workbook(xlsxPath) # 打開這個(gè)xlsx文件得到wb對(duì)象
            sheetnames = wb.get_sheet_names()     # 獲取文件內(nèi)的所有表格
            # sheet = wb.get_sheet_by_name(sheetnames[0])
            for sheetname in sheetnames:          # 遍歷這個(gè)文件的內(nèi)的所有表格 這里只取第一個(gè)表
                sheet = wb.get_sheet_by_name(sheetname)       # 取sheet表
                # print "遍歷的表格數(shù)" + str(j)
                # range(start,stop,step) 開始 結(jié)束(不包括) 步長(zhǎng)
                for num in range(0, len(values)-(col-1), col):   # col每次遍歷跳過(guò)的數(shù) 以col的數(shù)量為單位 len(values)一定是col的整數(shù)倍
                    for a in range(0, col):                      # 對(duì)一行數(shù)據(jù)進(jìn)行操作 一共col列循環(huán)col次
                        value = str(values[num+a])               # 獲取內(nèi)容
                        # value = value.decode('utf-8').encode('gbk')
                        print "寫入的內(nèi)容" + value
                        sheet.cell(row, startCol+a).value = value  # 把內(nèi)容寫入到匯總表對(duì)應(yīng)位置
                    row += 1
                break
                # j += 1
            # 這里保存的路徑需要修改,只需要路徑名
            print "最終保存路徑---->"+xlsxPath.decode('gbk').encode('utf-8')       #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
            wb.save(xlsxPath)
        except IOError:
            print 'IO讀寫錯(cuò)誤----->107'
    else:
        print "你填入的導(dǎo)出路徑不存在請(qǐng)重新填寫"

# 該函數(shù)抓取導(dǎo)入的多張表的某些指定內(nèi)容,內(nèi)容指定由坐標(biāo)表示
# 因?yàn)樯婕暗揭粋€(gè)文件可能存在多個(gè)表的問(wèn)題所以要以表為單位進(jìn)行內(nèi)容抓取
def rwExecel(Rpath,eList_col,eList_entry):
    # global list_col
    xlsPath = Rpath
    xls = None
    # 這里需要對(duì)路徑文件格式進(jìn)行判斷一個(gè)if語(yǔ)句
    if 'xlsx' in Rpath:                    # 把xlsx轉(zhuǎn)為xls,會(huì)把原路徑的xlsx文件替換為xls,讀的時(shí)候只能操作xls表格
        print '文件格式為:xlsx'
        xlsPath = xlsxtoxls(Rpath,Rpath)
        # 轉(zhuǎn)換完成之后需要把原來(lái)xlsx這個(gè)文件刪除
        path = Rpath.decode('utf-8').encode('gbk')
        os.remove(path)
        print '文件已刪除'
        print xlsPath.decode('gbk').encode('utf-8')       #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
        # xls = xlrd.open_workbook(xlsPath)
    else:
        # xlsPath = xlsPath.decode('utf-8').encode('gbk')
        print xlsPath.decode('gbk').encode('utf-8')       #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
    # --------對(duì)xlsx文件內(nèi)的所有表格都進(jìn)行判斷是否有內(nèi)容-----------
    xls = xlrd.open_workbook(xlsPath)
    tables = xls.sheets()         # 獲取文件所有表格這樣就不需要表的標(biāo)號(hào)和名稱了
    sheet_name = xls.sheet_names()
    print sheet_name
    for table in tables:         # 如何判斷一個(gè)表是否有內(nèi)容
        if table.nrows == 0:     # 查看表的有效函數(shù)是否為0
            continue             # 直接進(jìn)入下一個(gè)循環(huán)
        # 通過(guò)遍歷elist_entry來(lái)獲得對(duì)應(yīng)坐標(biāo),每三個(gè)為一個(gè)單位獲取
        for num in range(0,len(eList_entry)-2,3):
            # 只讀入有效坐標(biāo)只有行或列或者全沒(méi)有不讀入直接跳入下一個(gè)循環(huán)
            if (eList_entry[num+1]!='' and eList_entry[num+2]!='') and (eList_entry[num+1]!=None and eList_entry[num+2]!=None):
                r = int(eList_entry[num+1])   # 第二個(gè)是行
                c = int(eList_entry[num+2])   # 第三個(gè)是列
                eList_col.append(table.cell_value(r,c)) # 爬取表格內(nèi)容
                print '每次爬取內(nèi)容' + str(table.cell_value(r,c))
            else:
                continue
        # wExecel(Wpath,eRow,eCol,eList_col) #寫入的文件路徑
        # del eList_col[:]  #每次執(zhí)行完一行清空列表
        # eRow = eRow + 1
    return eList_col  # 返回裝載所有多表信息的列表

# 爬取表格內(nèi)容并復(fù)制到表格力功能A
# 多個(gè)表格內(nèi)容復(fù)制到另一個(gè)表,一個(gè)表的內(nèi)容就是一行
def deal_Excel_A(start_row_col,content_row_col,importPath,exportPath):
    print u"開始執(zhí)行任務(wù)"
    print '用戶輸入行數(shù)'+start_row_col[0]
    row = int(start_row_col[0]) + 1                       # 獲得用戶輸入的開始行數(shù)
    print '用戶輸入列數(shù)'+start_row_col[1]
    col = int(start_row_col[1]) + 1                   # 獲得用戶輸入的開始列數(shù)
    list_col = []                                     # 用來(lái)保存一個(gè)人的表格內(nèi)容
    list_entry = content_row_col                      # 獲得用戶輸入的行和列
    allFilesNames = read_file_name(importPath)        # 獲取每個(gè)xls的表名
    i = 0
    for fileName in allFilesNames:                    # 遍歷每個(gè)表名
        print fileName.decode('gbk').encode('utf-8')                               # 打印獲得的每個(gè)表名 #為了方便控制臺(tái)查看轉(zhuǎn)為utf-8
        list_col = rwExecel(importPath + '/' + fileName,
                            list_col, list_entry)     # 抓取一張表的內(nèi)容然后暫存到list_col
        i += 1
    print '遍歷的表格文件數(shù)目---->' + str(i)
    # 讀內(nèi)容到列表完畢后進(jìn)行統(tǒng)一寫入操作
    wExecel(exportPath, row, len(list_entry)/3, col, list_col) # 把list_col的內(nèi)容全部寫入新的xlsx文件內(nèi)

# -------需要提供的數(shù)據(jù)--------
start_row_col = ["1","1"]          # 最終導(dǎo)入的單表->數(shù)組第0個(gè)為開始行 數(shù)組第1個(gè)為開始列
content_row_col = ["姓名","0","1", "年齡","0","3", "出生日期","1","1"]        # 抓取的坐標(biāo)以及內(nèi)容名稱(表明這個(gè)坐標(biāo)抓取的東西方便查看)



if __name__ == '__main__':
    deal_Excel_A(start_row_col,content_row_col,"I:/pythonProject/xls_operation/importPath",
                 "I:/pythonProject/xls_operation/exportPath/某機(jī)構(gòu)匯總表.xls")

4、使用方式

1、新建兩個(gè)文件夾


文件夾

2、在對(duì)應(yīng)的文件夾放入對(duì)應(yīng)的文件


多個(gè)個(gè)人信息表

個(gè)人信息表格式

匯總表

匯總表格式

3、按照對(duì)應(yīng)規(guī)則填入?yún)?shù)
注意:excecl表格的坐標(biāo)是從0開始的,如第一個(gè)格子的位置為0,0

# -------需要提供的數(shù)據(jù)--------
start_row_col = ["1","1"]          # 最終導(dǎo)入的單表->數(shù)組第0個(gè)為開始行 數(shù)組第1個(gè)為開始列
content_row_col = ["姓名","0","1", "年齡","0","3", "出生日期","1","1"]        # 抓取的坐標(biāo)以及內(nèi)容名稱(表明這個(gè)坐標(biāo)抓取的東西方便查看)



if __name__ == '__main__':
    deal_Excel_A(start_row_col,content_row_col,"I:/pythonProject/xls_operation/importPath",
                 "I:/pythonProject/xls_operation/exportPath/某機(jī)構(gòu)匯總表.xls")

4.開始執(zhí)行程序


控制臺(tái)顯示的內(nèi)容

可以看到多出了一個(gè)xlsx的文件


導(dǎo)入成功

查看內(nèi)容后發(fā)現(xiàn)數(shù)據(jù)已經(jīng)填入了,這里從左到右填入的順序是由你填入?yún)?shù)的那個(gè)數(shù)組順序決定的,后面的數(shù)字代表就是個(gè)人信息表內(nèi)容每個(gè)格子的坐標(biāo)
content_row_col = ["姓名","0","1", "年齡","0","3", "出生日期","1","1"] 
填入成功

使用注意事項(xiàng):
1、如果只是單純的使用,復(fù)制我的代碼按照之前說(shuō)的環(huán)境即win10,python2.7.15下是可以正常使用的。
2、使用時(shí)請(qǐng)關(guān)閉Excel或者wps等軟件。
3、程序中只使用了xlsToxlsx()函數(shù),還有一個(gè)xlsxToxls()沒(méi)使用,所以該方法刪除也不影響腳本運(yùn)行。
注:轉(zhuǎn)載請(qǐng)注明出處
本文如果對(duì)你有幫助的話希望能給我點(diǎn)個(gè)贊哦~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,595評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,814評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,224評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,444評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,988評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,804評(píng)論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,998評(píng)論 1 370
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評(píng)論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,237評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評(píng)論 1 287
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,706評(píng)論 3 393
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,993評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容