【python】pySimpleGUIでExcelとWordファイル内の文字列を置換ツール作成してみた。業務効率UP

Python

ad2

【python】pySimpleGUIでExcelとWordファイル内の文字列を置換ツール作成してみた。業務効率UP

pySimpleGUI

pythonでデスクトップアプリケーション開発する際に、GUIで操作できるアプリケーションを開発したいときに、おすすめのパッケージは、「pySimpleGUI」です。

pip install pySimpleGUI

公式サイト:pySimpleGUI

詳しく書いてあり、サンプルも豊富なのでわかりやすいです。

python-Excel

pythonでExcelファイルを操作する場合に必要な「openpyxl」パッケージをインストールします。

pip install openpyxl

python-word

pythonでwordファイルを操作する場合に必要な「python-docx」パッケージをインストールします。

pip install python-docx

Excel&wordファイル準備

一括で文字置換したいファイルをフォルダに入れておくだけ。

例えば、下記の様に、pytestフォルダ配下やsubフォルダ配下すべてのファイル対象です。

pysimplegui_execute_before_folder1 pysimplegui_execute_before_folder2 pysimplegui_execute_before_folder3

python-code

必要なパッケージがインストールできたら、さっそくソースコードを載せます。

import glob
import os
import openpyxl
import time
import PySimpleGUI as sg
import docx
  
# 対象ファイル種別
fileType = ['*.xlsx']         # openpyxlは、[*.xls]拡張子に非対応
fileType_docx = ['*.docx']    # docxファイルのみ対応

# logic 置換処理
def exe_strchange(File_path_str, Before_str, After_str):
    
    start = time.perf_counter() # 実行時間計測開始

    #「対象フォルダのパス」配下にあるExcelファイルのパスを出力
    list_path_file = []
    for ext in fileType:
        # サブフォルダまで検索可能
        list_path_file.extend(glob.glob(os.path.join(File_path_str + r'/**/',ext), recursive=True)) 

    #「対象フォルダのパス」配下にあるWordファイルのパスを出力
    list_path_file_docx = []
    for ext in fileType_docx:
        # サブフォルダまで検索可能
        list_path_file_docx.extend(glob.glob(os.path.join(File_path_str + r'/**/',ext), recursive=True)) 

    print('◆検索対象ファイル数:' + str(len(list_path_file)))

    # 各ファイル数カウント
    total_count = 0    #変換総数
    book_count = 0     #Excel変換数
    doc_count = 0      #Word変換数

    # ------------------
    # Excelファイル数分ループ
    # ------------------
    for book in list_path_file:
        print("■対象ファイル: " + book)
        bookFlg=0
        #ブックの取得
        #openpyxl.load_workbook('Excelファイルのパス')
        actBook = openpyxl.load_workbook(book)
        
        #シート数分ループ
        for actSheetName in actBook.sheetnames:
            print("■対象シート"+ actSheetName)
            count = 0

            #アクティブシートを取得 #ブック変数[シート名]
            actSheet = actBook[actSheetName]

            # userdrange範囲内のセルに対して文字列の一致したセルを置換する
            for row in actSheet.iter_rows(min_row=actSheet.min_row,max_row=actSheet.max_row,min_col=actSheet.min_column,max_col=actSheet.max_column):
                # if any(is_empty(c) for c in row):
                #     continue
                for cell in row:
                    if str(cell.value) in Before_str:
                        cell.value = After_str
                        count+=1
                        bookFlg=1
            
            print(str(count) + "件置換しました。")
            
        #ブックを保存
        if bookFlg == 1:
            total_count+=1
            book_count+=1
            #ブック変数.save(Excelファイルのパス)
            actBook.save(book)
            # elapsed_time_file = time.perf_counter() - start
            # print("1ファイル処理時間(elapsed_time):{0}".format(elapsed_time_file) + "[sec]")
                
        else:
            actBook.close

    # ------------------
    # wordファイル数分ループ
    # ------------------
    for document in list_path_file_docx:
        print("■対象ファイル: " + document)
        doxcFlg=0
        #docxの取得
        #openpyxl.load_workbook('ファイルのパス')
        actdoc = docx.Document(document)
        count = 0
        # userdrange範囲内のセルに対して文字列の一致したセルを置換する
        for para in actdoc.paragraphs:
            # if any(is_empty(c) for c in row):
            #     continue
            
            if para.text in Before_str:
                para.text.replace(Before_str, After_str)
                count+=1
                doxcFlg=1
        
        print(str(count) + "件置換しました。")
            
        #ファイルを保存
        if doxcFlg == 1:
            total_count+=1
            doc_count+=1
            #保存: docx変数.save(ファイルのパス)
            actdoc.save(document)

        else:
            actdoc.close

    # 経過時間
    elapsed_time = time.perf_counter() - start

    result_str_list = [
        '検索対象Excelファイル数:' + str(len(list_path_file)), '変換Excelファイル数:' + str(book_count),
        '検索対象Wordファイル数:' + str(len(list_path_file_docx)), '変換Wordファイル数:' + str(doc_count),
        '変換ファイル総数:' + str(total_count),'Total処理時間:{0}'.format(elapsed_time) + '[sec]']

    return result_str_list


def main():
    sg.theme('Blue Mono')
    layout = [[sg.Text('指定フォルダ内のサブフォルダ対応')],
            [sg.Text('FolderPath:'), sg.Input(size=(56,1), key='-IN_File-')],
            [sg.Text('置換前(検索値):'), sg.Input(size=(50,1), key='-IN_Before-')],
            [sg.Text('置換後(変換値):'), sg.Input(size=(50,1), key='-IN_After-')],
            [sg.Button('実行', bind_return_key=True)]
            ]

    window = sg.Window('Excel&word 文字列置換ツール', layout) #GUIウィンドウ設定

    event, values = window.read(close=True)
    if event == sg.WIN_CLOSED:
        window.close()
    if event == '実行':
        # 画面テキスト入力内容取得
        File_path_str = values['-IN_File-']
        Before_str = str(values['-IN_Before-'])
        After_str = str(values['-IN_After-'])
        
        # logic関数実行
        result_str =exe_strchange(File_path_str, Before_str, After_str)
        
        # 結果表示
        sg.popup_scrolled('完了!\n' + result_str[0] + '\n' + result_str[1] + '\n' + result_str[2] + '\n' + result_str[4] + '\n' + result_str[5])
    
    window.close()

if __name__ == '__main__':
    main()

ポイント

  • サブフォルダに対応している
  • Excel(全シート)、Wordに対応
  • GUIでわかりやすい
  • exeファイルに変換すれば他のPCでも実行できる
  • 活用すれば業務効率UP

実行

pysimplegui_excel_word_gui

pyファイル実行すると、GUIが表示され、フォルダパスと、検索値と変換値を入力して実行ボタンを押下するだけ。

pysimplegui_excel_word_gui_example

完了したらポップアップメッセージ表示する。

pysimplegui_excel_word_gui_after_popup

 

置換前のExcelファイル

pysimplegui_excel_word_gui_before_excel

置換後のExcelファイル

pysimplegui_excel_word_gui_after_excel

結果

今回の試したのは、Excelファイル15個、Wordファイル15個の計30ファイル数です。

実行PCスペック環境、ファイル内容の一行ずつ読み取っているので一概には言えませんが、30ファイル分の処理で約1秒です。

業務では、会社名の変更、役職名の変更、名前の変更などがあれば、標準テンプレートファイルなどを1ファイルずつ開いて変更して閉じる。を繰り返し作業している人もいるのではないでしょうか。

今回のアプリケーションを活用すれば、一括で変更できて、業務効率UPです。

pyファイルをexeファイルにする

pyファイルを作成しても他のPCで実行したい場合、Python環境が無くても実行できるようにするために、exeファイルを作成できるパッケージがあります。「pyinstaller」

pip install pyinstaller
pyinstaller pythonファイル名 [--onefile] [--noconsole]