1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        我用python,幫朋友寫了一個“制作工資條”的自動化程序!

        共 3474字,需瀏覽 7分鐘

         ·

        2020-08-08 19:14

        作者:黃偉呢

        本文轉(zhuǎn)自:數(shù)據(jù)分析與統(tǒng)計學之美


        本文說明

        周末和一個朋友吃飯,她說我經(jīng)常使用Excel制作工資條,但是每個月都要做一遍。你能不能用python寫一個代碼,能夠自動化完成這個工作,這當然可以啦,就是這么牛逼!

        我們先來看看原始數(shù)據(jù)是什么樣子的。

        那么最后做成的效果是什么樣子的呢?

        這就很方便了,不管你公司有多少人,只要你把原始數(shù)據(jù)丟給我,我都可以秒出一個工資條,省得每次都需要使用Excel操作一遍,并且數(shù)據(jù)多了Excel還會卡頓。

        代碼邏輯剖析

        那么這樣一個程序,是怎么寫的呢?

        其實只要是邏輯想清楚了,剩下的就是寫代碼的事兒了。下面我就帶著大家梳理一下,這段代碼的邏輯。

        首先,我們應該是讀取Excel表格。然后需要拷貝其中一個sheet表到另外一張sheet表,并給sheet命名。這樣做的目的:為了存放制作好工資條的那張sheet表。

        import?re
        import?openpyxl
        from?copy?import?copy

        wb?=?openpyxl.load_workbook('工資條.xlsx')
        # copy_worksheet():拷貝sheet表?
        wb.copy_worksheet(wb['工資條'])
        # worksheets:以列表的形式返回所有的Worksheet(表格)
        ws?=?wb.worksheets[-1]
        ws.title?=?'final_工資條'

        可能這樣說,大家還是不知道上述代碼到底是什么意思?我下面截一張圖給大家,其實就可以很好的說明上述函數(shù)的含義了。

        接著,就需要給每一行數(shù)據(jù)前面添加一個表頭。由于后面每一行表頭的樣式,都與第一行完全一模一樣的,因此我們需要復制第一行表頭中的樣式。

        def?cell_style(cell):
        ????alignment?=?copy(cell.alignment)????#?對齊樣式
        ????border?=?copy(cell.border)??????????#?邊框樣式
        ????fill?=?copy(cell.fill)??????????????#?填充樣式
        ????font?=?copy(cell.font)??????????????#?字體樣式
        ????return?alignment,?border,?fill,?font
        ????
        #?獲取標題行中,每個單元格中的各種樣式
        alignment,?border,?fill,?font?=?cell_style(cell=cells_rows[0][0])

        從上面的代碼中可以看到:我定義了一個函數(shù),使用copy庫中的copy()方法,直接拷貝單元格的4大樣式。因為原表第一行中每個單元格的4大樣式,都是完全一致的,因此我們直接獲取第一個單元格的樣式即可

        最后這一part是整個代碼中最精彩的部分,不太好敘述,大家仔細研究一下下方的注釋。

        for?i,?_?in?enumerate(cells_rows[1:]):
        ????if?i?>?0:
        ????????index?=?i*3
        ????????#?每循環(huán)一次,就在對應位置下方插入2行。1行是空行,1行是表頭行。
        ????????ws.insert_rows(idx=index,?amount=2)
        ????????#?因為每次插入2行,所以需要在表頭行那里,將表頭及其樣式寫入。
        ????????for?j,?v?in?enumerate(header):
        ????????????r,?c?=?index+1,?j+1
        ????????????cell?=?ws.cell(row=r,?column=c)
        ????????????cell.value?=?v
        ????????????cell.alignment?=?alignment
        ????????????cell.font?=?font
        ????????????cell.border?=?border
        ????????????cell.fill?=?fill
        ????????????#?更新后面的公式
        ????????????if?cell.coordinate[:1]?in?('H',?'J'):
        ????????????????cell?=?ws.cell(row=r+1,?column=c)
        ????????????????cell.value?=?re.sub('\d+',?str(r+1),?cell.value)

        這里需要特別說明一點的就是更新公式。就拿第一次循環(huán)來說,我們在第3行的位置,插入了2個空白行。那么原本第3行的數(shù)據(jù),此時就被擠到了第5行。

        注意:它是被迫擠到第5行的,因此這一整行是原封不動搬到第5行的,包括它原來的公式。原來在第3行的時候,如果公式是SUM(E3:G3),被擠到到了第5行后,應該是SUM(E5:G5),但是它仍然是SUM(E3:G3),因為它是被迫的,所以需要我們修改公式,上述代碼中正是使用正則將這個數(shù)字3改為了5。

        完整代碼

        import?re
        import?openpyxl
        from?copy?import?copy

        def?cell_style(cell):
        ????alignment?=?copy(cell.alignment)????#?對齊樣式
        ????border?=?copy(cell.border)??????????#?邊框樣式
        ????fill?=?copy(cell.fill)??????????????#?填充樣式
        ????font?=?copy(cell.font)??????????????#?字體樣式
        ????return?alignment,?border,?fill,?font

        wb?=?openpyxl.load_workbook('工資條.xlsx')?
        wb.copy_worksheet(wb['工資條'])
        ws?=?wb.worksheets[-1]
        ws.title?=?'final_工資條'

        #?獲取每一列的值,拼接在一個列表中
        cells_rows?=?[[cell?for?cell?in?row]?for?row?in?ws.rows]

        #?獲取標題
        header?=?[cell.value?for?cell?in?cells_rows[0]]

        #?獲取標題行中,每個單元格中的各種樣式
        alignment,?border,?fill,?font?=?cell_style(cell=cells_rows[0][0])

        for?i,?_?in?enumerate(cells_rows[1:]):
        ????if?i?>?0:
        ????????index?=?i*3
        ????????#?每讀取一行,就在下方插入兩行
        ????????ws.insert_rows(idx=index,?amount=2)
        ????????#?寫表頭
        ????????for?j,?v?in?enumerate(header):
        ????????????r,?c?=?index+1,?j+1
        ????????????cell?=?ws.cell(row=r,?column=c)
        ????????????cell.value?=?v
        ????????????cell.alignment?=?alignment
        ????????????cell.font?=?font
        ????????????cell.border?=?border
        ????????????cell.fill?=?fill
        ????????????#?更新后面的公式
        ????????????if?cell.coordinate[:1]?in?('H',?'J'):
        ????????????????cell?=?ws.cell(row=r+1,?column=c)
        ????????????????cell.value?=?re.sub('\d+',?str(r+1),?cell.value)
        #?整個代碼寫完后,一定要記得保存???????????????
        wb.save('工資條.xlsx')????
        戀習Python

        關注戀習Python,Python都好練

        好文章,我在看??
        瀏覽 49
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            午夜福利一区二区三区在线观看 | 男女成人 免费视频在线播放 | 裸睡室友把我j玩硬了 | 欧美成人性爱视频在线播放 | 国产熟妇毛多 久久久久一区 | 女sm性折磨视频 | 娇妻在办公室伺候上司h | 无码中文字幕一区二区免费蜜桃 | 婷婷欧美| 韩国办公室三级hd观看 |