<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用Python手撕一個批量填充數(shù)據(jù)到excel表格的工具,解放雙手!

          共 11475字,需瀏覽 23分鐘

           ·

          2021-08-02 09:46

          Hi~大家好!

          今天這篇文章是根據(jù)批量填充數(shù)據(jù)的進階版。基礎(chǔ)版本就一段很簡單的代碼。雖然簡單,但如果這個模板或者數(shù)據(jù)發(fā)生變化,還是要改來改去的,所以本文就在基礎(chǔ)版本上進行改進,只需要動動鼠標就可以填充大量數(shù)據(jù)到Excel工作表中。

          文末附完整源碼示例文件工具獲取方式!

            GUI界面設(shè)計

          GUI是用PySimpleGUI庫創(chuàng)建的,安裝命令直接用pip命令安裝即可!

          在開始設(shè)計GUI界面時,要明確我們需要實現(xiàn)什么功能,可以先設(shè)計出圖紙,再動手去寫代碼!本文根據(jù)需求,最后得出以下GUI界面圖紙:

          GUI界面中按鈕和框的一些功能:
          • 通過打開文件按鈕選擇數(shù)據(jù)文件或者在輸入框中輸入數(shù)據(jù)文件文件路徑,但只支持csvxlsxxls格式的文件,并把數(shù)據(jù)文件中的列標題傳入選擇或輸入數(shù)據(jù)列標題框中。
          • 通過打開模板按鈕選擇模板文件或者在輸入框中輸入模板文件的路徑,只支持xlsxxls格式的文件,并把模板表格中的空白單元格坐標傳入選擇或輸入單元格坐標框中。
          • 通過選擇或輸入數(shù)據(jù)列標題框選擇要填充的數(shù)據(jù)列。
          • 通過選擇或輸入單元格坐標框選擇各個數(shù)據(jù)列填充的位置。
          • 通過繼續(xù)按鈕把數(shù)據(jù)列標題和單元格坐標存儲入列表中。
          • 通過開始填充按鈕選擇保存路徑和輸入文件名稱,最后開始填充數(shù)據(jù)。
          • 通過信息展示框展示操作信息。
          • 當數(shù)據(jù)列標題和單元格坐標選擇錯誤時,可以通過刪除元素按鈕刪除列表中的錯誤數(shù)據(jù)。
          • 通過退出程序按鈕直接結(jié)束工具的運行

          根據(jù)圖紙和基本功能思路最后得出以下代碼:

          # 主題設(shè)置
          sg.theme('BrownBlue')

          # 布局設(shè)置
          layout = [
              # 選擇數(shù)據(jù)文件框和按鈕   file_types 后面跟的是支持的文件格式,傳入的是元組,元組中只包含一個元素時,需要在元素后面添加逗號
              [sg.Text('請選擇文件:', font=("微軟雅黑"12)),
               sg.InputText(key='please_select_file', size=(781), font=("微軟雅黑"10), enable_events=True),
               sg.FileBrowse('打開文件', file_types=(("Text Files""*.csv*"), ("Text Files""*.xls*")), font=("微軟雅黑"12))],
              # 選擇模板框和按鈕 xls包括xlsx格式
              [sg.Text('請選擇模板:', font=("微軟雅黑"12)),
               sg.InputText(key='template', size=(781), font=("微軟雅黑"10), enable_events=True),
               sg.FileBrowse('打開模板', file_types=(("Text Files""*.xls*"),), font=("微軟雅黑"12))],
              
              [sg.Text('請選擇或輸入數(shù)據(jù)列標題:', font=("微軟雅黑"12)),
               sg.Combo(values='', tooltip='請選擇或輸入數(shù)據(jù)列:', font=("微軟雅黑"10), auto_size_text=True,
                        size=(1510), key='value'),

               sg.Text('請選擇或輸入單元格坐標:', font=("微軟雅黑"12)),
               sg.Combo(values='', tooltip='請選擇或輸入單元格坐標:', font=("微軟雅黑"10), auto_size_text=True,
                        size=(1510), key='keys'),
               
               sg.Button('繼續(xù)', font=("微軟雅黑"12)),
               sg.Button('開始填充', font=("微軟雅黑"12))],

              [sg.Text('信息展示:', justification='center')],
              [sg.Output(size=(10010), font=("微軟雅黑"10))],

              [sg.Text('', font=("微軟雅黑"12), size=(00)), sg.Button('刪除元素', font=("微軟雅黑"12)),
               sg.Text('', font=("微軟雅黑"12), size=(620)), sg.Button('退出程序', font=("微軟雅黑"12))]
          ]
          # 創(chuàng)建窗口
          window = sg.Window('數(shù)據(jù)填充工具', layout, font=("微軟雅黑"12), default_element_size=(801))
          # 事件循環(huán)
          while True:
              # 退出按鈕
              event, values = window.read()
              if event in (None'退出程序'):
                  break
          window.close()

          界面效果:

            事件循環(huán)設(shè)置

          打開文件按鈕只要實現(xiàn)的是傳入數(shù)據(jù)文件,然后獲取數(shù)據(jù)文件的標題行并傳入對應(yīng)的框中:

          if event == 'please_select_file':
               fileName = values['please_select_file']
               if os.path.exists(fileName):
                   # 因為pandas讀取文件因格式而異,所以需要判斷
                   if fileName.split('.')[-1] == 'csv':
                       df = pd.read_csv(fileName, encoding='utf-8')
                       # 獲取標題行
                       keys = df.columns.to_list()
                       # 傳入相應(yīng)的的框
                       window["value"].Update(values=keys, font=("微軟雅黑"10), size=(158))
                   elif fileName.split('.')[-1] == 'xls' or 'xlsx':
                       df = pd.read_excel(fileName, encoding='utf-8')
                       keys = df.columns.to_list()
                       window["value"].Update(values=keys, font=("微軟雅黑"10), size=(158))
                   else:
                       print('文件格式不正確,請重新選擇文件!')
                       sg.popup('文件格式不正確,請重新選擇文件!')
               else:
                   print('文件不存在,請重新選擇文件!')
                   sg.popup('文件不存在,請重新選擇文件!')

          打開模板按鈕只要實現(xiàn)的是傳入模板文件,以及獲取模板表格中的空白表格坐標;其中,之所以使用openpyxl打開模板文件,是因為后面是openpyxl進行填充數(shù)據(jù)的。而列表推導式中,第一個for循環(huán)取出單元格對象,第二個循環(huán)把對象內(nèi)容轉(zhuǎn)換為字符串格式,通過正則表達式取出單元格坐標,最后通過if判斷單元格內(nèi)容是否為None,是的話就傳入列表中,需要注意的是:如果是合并單元格的,會被分開計算為單個單元格

          if event == 'template':
             fileName = values['template']
             if os.path.exists(fileName):
                 wb = openpyxl.load_workbook(fileName)
                 sheets = wb.sheetnames  # 獲取全部sheet
                 ws = wb[sheets[0]]  # 默認獲取第一個工作表
                 data_row = []
                 # 列表推導式,獲取模板表格中的空白表格坐標
                 data = [data_row.append(i) for row in ws.rows for i in
                         re.findall("<.*? '.*?'.([A-Z]+\d+)>", str("{}".format(row))) if ws[str(i)].value == None]
                 window["keys"].Update(values=data_row, font=("微軟雅黑"10), size=(158))
             else:
                 print('文件不存在,請重新選擇文件')
                 sg.popup('文件不存在,請重新選擇文件')

          繼續(xù)選擇按鈕只要實現(xiàn)的是:獲取用戶在選擇或輸入數(shù)據(jù)列標題框選擇或輸入單元格坐標框一次次輸入的內(nèi)容,存儲到valuelistkeyslist列表中:

           if event == '繼續(xù)':
               if values['value'and values['keys']:
                   a = values['value']
                   b = values['keys']
                   valuelist.append(a)
                   keyslist.append(b)
                   print(f'選擇: {a}:{b} 完畢,請繼續(xù);或者點擊開始進行數(shù)據(jù)填充!')
               else:
                   print('數(shù)據(jù)列標題或者單元格坐標未選擇!')
                   sg.popup('數(shù)據(jù)列標題或單元格坐標未選擇!')

          判斷兩個列表中的內(nèi)容是否存在,存在就把數(shù)據(jù)傳入Datainput函數(shù)中,files是一個保存路徑彈窗,先選擇路徑,然后在輸入文件名稱,最后開始填充:

          if event == '開始填充':
              if len(keyslist) and len(valuelist) != 0:
                  files = sg.popup_get_folder('請選擇存儲路徑和輸入文件名稱:')
                  Datainput(files, valuelist, keyslist)
              else:
                  print('數(shù)據(jù)列標題或者單元格坐標未選擇!')
                  sg.popup('數(shù)據(jù)列標題或單元格坐標未選擇!')

          刪除元素按鈕只要用python自帶函數(shù)remove來刪除列表中的元素,為了防止元素不存在而導致報錯,這里加一個條件判斷:

          if event == '刪除元素':
            if values['value'] or values['keys']:
                a = values['value']
                b = values['keys']
                if a in valuelist:
                    valuelist.remove(a)
                    print('刪除成功!')
                else:
                    print('表格列標題不存在!')
                    sg.popup('表格列標題不存在!')
                if b in keyslist:
                    keyslist.remove(b)
                    print('刪除成功!')
                else:
                    print('單元格坐標不存在!')
                    sg.popup('單元格坐標不存在!')

            數(shù)據(jù)填充函數(shù)

          Datainput函數(shù)接收通過開始填充按鈕傳入的列標題和單元格坐標,并開始填充數(shù)據(jù):

          def Datainput(files, key, value):
              for p in range(len(df[key[0]])):  # 計算excel工作表其中一列數(shù)據(jù)的數(shù)目,然后進行遍歷這個數(shù)值
                  sheet = wb.copy_worksheet(ws)  # 復制原有工作表
                  sheet.title = str(df[key[0]][p])  # 設(shè)置工作表名稱
                  for i in range(len(key)):  # 計算excel工作表中標題數(shù)目
                      sheet[value[i]].value = df[key[i]][p]  # 寫入數(shù)據(jù)
                  print('正在填充,請稍等!')
                  # 彈窗進度條
                  sg.one_line_progress_meter('正在填充,請稍等!', p + 1100, orientation='h',
                                             bar_color=('#F47264''#FFFFFF'))
              wb.save(
          files)
              print(
          '已完成...')
              sg.popup(
          '已完成!')  # 彈窗

            打包運行

          打包可以通過pyinstaller庫,安裝只需要pip命令即可!安裝后在命令行窗口cd到文件所在的文件目錄中,最后用下面命令進行打包。

          pyinstaller -F -w 名稱.py

          打包時可能會報錯:

          報錯源于一個hook-sqlalchemy.py文件,一個簡單的解決方法是找到它直接回收刪除它(最后暫未發(fā)現(xiàn)刪除它對打包后的exe文件有什么影響),等打包完成后在放回去即可:

          最終效果展示。沒錄到鼠標,后面選擇完單元格坐標后,是點擊了繼續(xù),選擇完成后是點擊了開始填充;如果你選擇錯誤標題和單元格坐標,可以點擊刪除元素按鈕刪除;打開表格時有點卡,后面出現(xiàn)的兩個彈窗直接點擊“是”和“關(guān)閉”即可:

            結(jié)語

          把一個簡單的腳本制作成一個可運行的工具,代碼量變多了,但用起來方便了很多,只要是能節(jié)省時間,解放雙手(雖然還要動手),避免重復性、機器式操作。

          以上便是本文全部內(nèi)容,代碼在測試過程中暫未發(fā)現(xiàn)什么bug,可正常運行。如果你感興趣的話,點個贊和在看支持一下唄。

          完整源碼、示例文件和工具可在公眾號后臺發(fā)送填充數(shù)據(jù)獲取!


          往期推薦

          1、保護源碼!加密你的 Python 程序代碼!

          25行Python代碼就能讓你的電腦 “永不息屏”?

          3、谷歌程序員少輸一個“&”,差點讓全球Chrome筆記本變磚

          4、Python 里最強的Web框架,早就不是Django和Flask了

          5、程序員的內(nèi)卷,一行注釋就能生成代碼!GitHub原生AI代碼生成工具Copilot上線


          今天因為您的點贊和在看,讓我元氣滿滿!

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  激情婷婷丁香五月天 | 鸥美一级操逼片 | 欧美操逼一级片 | www.我操 | 成人黄色在线播放 |