Pythonのお勉強:ディレクトリにあるファイルを再帰的に辿って一覧表(EXCEL)を作成する

OpenPyXl

Pythonのos.walk()を使用すると、指定したルートディレクトリ配下を再帰的に辿って、ディレクトリにあるファイルの一覧を取得することが出来ます。下記に記載した「rootフォルダ(./pdf)」配下のサブディレクトリにあるPDFファイルの一覧(「Pdf_DirList.xlsx」)を作成するサンプルプログラムをos.walk()を使用して作成してみました。

対象「rootフォルダ(./pdf)」配下のツリー構造


root(./pdf)
    │
    ├─A社
    │  ├─A支店
    │  │  ├─2021
    │  │  │      注文書_AA2021_01.pdf
    │  │  │      注文書_AA2021_02.pdf
    │  │  └─2022
    │  │          注文書_AA2022_01.pdf
    │  │          注文書_AA2022_02.pdf
    │  └─B支店
    │      ├─2021
    │      │      注文書_AB2021_01.pdf
    │      │      注文書_AB2021_02.pdf
    │      └─2022
    │              注文書_AB2022_01.pdf
    │              注文書_AB2022_02.pdf
    └─B社
        ├─A支店
        │  ├─2021
        │  │      注文書_BA2021_01.pdf
        │  │      注文書_BA2021_02.pdf
        │  └─2022
        │          注文書_BA2022_01.pdf
        │          注文書_BA2022_02.pdf
        └─B支店
            ├─2021
            │      注文書_BB2021_01.pdf
            │      注文書_BB2021_02.pdf
            └─2022
                    注文書_BB2022_01.pdf
                    注文書_BB2022_02.pdf
                    

ディレクトリを再帰的に探索する自作サンプルプログラム (「Os_Walk_Pdf_DirList.py」)

今回作成したサンプルプログラムを以下に記載します。

  • 「Os_Walk_Pdf_DirList.py」
    import openpyxl
    import os
    import fnmatch
    from openpyxl.styles.alignment import Alignment
    from openpyxl.styles import PatternFill
    from openpyxl.styles import Font
    
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "pdf_list"
    
    root_dir = 'pdf'
    dirname_lst = list()      # ディレクトリ名の格納用リスト
    pdfname_lst = list()      # PDFファイル名の格納用リスト
    lnkname_lst = list()      # HYPERLINK用ファイル名の格納用リスト
    maxlen_dirname = 0      # ディレクトリ名の最大バイト数格納用変数
    maxlen_pdfname = 0      # PDFファイル名の最大バイト数格納用変数
    maxlen_lnkname = 0      # HYPERLINK用ファイル名の最大バイト数格納用変数
    
    # PDFファイル名とHYPERLINK用ファイル名をリストに格納
    for dirpath, dirs, files in os.walk(root_dir):
        for fname in files:
            if fnmatch.fnmatch(fname, '*.pdf'):
    
                # ディレクトリ名をリストに格納            
                # print(dirpath)
                dirname = dirpath   
                dirname_lst.append(dirname)
                if len(dirname.encode()) > maxlen_dirname:
                    maxlen_dirname = len(dirname.encode())
                
                # PDFファイル名をリストに格納
                # print(fname)
                pdfname = fname
                pdfname_lst.append(pdfname)
                if len(pdfname.encode()) > maxlen_pdfname:
                    maxlen_pdfname = len(pdfname.encode())
    
                # HYPERLINK用ファイル名をリストに格納
                  # print(os.path.join(dirpath, fname))
                lnkname = os.path.join(dirpath, fname)
                lnkname_lst.append(lnkname)
                if len(lnkname.encode()) > maxlen_lnkname:
                    maxlen_lnkname = len(lnkname.encode())
    
    start_row = 1 # EXCEL表示開始列
    start_col = 1 # EXCEL表示開始行
    
    # タイトルセルの名前を設定
    ws.cell(start_col,start_row).value='ディレクトリ名'
    ws.cell(start_col,start_row+1).value='PDFファイル名'
    
    # タイトルセルの表示幅を変更
    ws.column_dimensions['A'].width = maxlen_dirname
    ws.column_dimensions['B'].width = maxlen_pdfname
    
    # タイトルセル('A1':'B1')の背景色を変更 「fil_obj(水色 塗り潰し)」
    fil_obj = PatternFill(fgColor='00ffff' , patternType='solid')
    for rows in ws['A1':'B1']:
        for cell in rows:
            cell.fill = fil_obj
    
    # セルにファイル名を書き込む
    
    for i in range(0,len(pdfname_lst)):
        # 現在の行(cur_col)と列(cur_row)を変数に格納
        cur_col = i+start_col+1
        cur_row = start_row
        # シート'A'列にディレクトリ名を書き込む
        hdir_name = dirname_lst[i]
        hdir_str =  hdir_name
        ws.cell(cur_col,cur_row).value = hdir_name
        ws.cell(cur_col,cur_row).hyperlink = hdir_str
    
        # シート'B'列にPDFファイル名とHYPERLINKを書き込む
        hpdf_name = pdfname_lst[i]
        hlnk_name = lnkname_lst[i]
        hlnk_str = hlnk_name
        ws.cell(cur_col,cur_row+1).value = hpdf_name
        ws.cell(cur_col,cur_row+1).hyperlink = hlnk_str 
    
        # ハイパーリンクの書式設定 fnt_obj(色:青 シングルアンダーライン)
        fnt_obj = Font(color='0000FF', u='single')
        ws.cell(cur_col,cur_row).font = fnt_obj
        ws.cell(cur_col,cur_row+1).font = fnt_obj
        
        # シートセル全体の水平方向を左寄せ、高さ方向を中央揃え
        for col in ws:
            for cell in col:
                cell.alignment = Alignment(horizontal='left',vertical='center')
    
        # シートセルの行高さ変更
        for i in range(len(dirname_lst)+2):
            ws.row_dimensions[i].height = 21
    
    # 作成したファイルを名前を付けて保存
    save_filename = 'Pdf_DirList.xlsx'
    wb.save(filename = save_filename)
    wb.close()
    

    サンプルプログラムで作成したExcelファイル(「Pdf_DirList.xlsx」)

    サンプルプログラム(「Os_Walk_Pdf_DirList.py」)で作成したExcelファイル(「Pdf_DirList.xlsx」)は、オープンソースのオフィスソフトLibre Office(Mac版)でも問題なく開くことができました。

    サンプルプログラム作成で得られた知見

    • os.walk()にルートディレクトリを指定すると、その配下にあるファイルの一覧を再帰的に辿って取得することが出来る。
      import os
      :
      root_dir = 'pdf'
      :
      for dirpath, dirs, files in os.walk(root_dir):
          for fname in files:
      :
      
    • fnmatch()を以下のように使用すると、拡張子が「.pdf」である全てのファイルを抽出することが出来る。
      if fnmatch.fnmatch(fname, '*.pdf'):
      
    • 「len(文字列.encode())」で文字列のバイト数を取得することが出来る。(Pythonのデフォルトエンコーディングは、’utf-8’)
      maxlen_dirname = len(dirname.encode())
      
    • リスト変数は、「list() 」で初期化することが出来る。(既知)
      dirname_lst = list()      # ディレクトリ名の格納用リスト
      pdfname_lst = list()      # PDFファイル名の格納用リスト
      lnkname_lst = list()      # HYPERLINK用ファイル名の格納用リスト
      
    • lst.append('追加要素')でリストに要素を追加することが出来る。(既知)
      dirname_lst.append(dirname)
      pdfname_lst.append(pdfname)
      lnkname_lst.append(lnkname)
      
    • for文を使用してPatternFill()で作成したオブジェクト(fil_obj)を指定したセル範囲に代入して、指定範囲のセル色を変更することが出来る。
      # タイトルセル('A1':'B1')の背景色を変更 「fil_obj(水色 塗り潰し)」
      fil_obj = PatternFill(fgColor='00ffff' , patternType='solid')
      for rows in ws['A1':'B1']:
          for cell in rows:
              cell.fill = fil_obj
      
    • セルのhyperlink属性にハイパーリンク先を書き込むことによりEXCELファイルのセルにハイパーリンクを設定することが出来る。(既知)
          # シート'A'列にディレクトリ名を書き込む
          hdir_name = dirname_lst[i]
          hdir_str =  hdir_name
          ws.cell(cur_col,cur_row).value = hdir_name
          ws.cell(cur_col,cur_row).hyperlink = hdir_str
          # シート'B'列にPDFファイル名とHYPERLINKを書き込む
          hpdf_name = pdfname_lst[i]
          hlnk_name = lnkname_lst[i]
          hlnk_str = hlnk_name
          ws.cell(cur_col,cur_row+1).value = hpdf_name
          ws.cell(cur_col,cur_row+1).hyperlink = hlnk_str 
      
    • Font()を使用して作成したオブジェクト(fnt_obj)をCellオブジェクトのfontプロパティに代入することにより、リンク文字列の色やアンダーラインを変更することができる。(既知)
      from openpyxl.styles import Font
      :
          # ハイパーリンクの書式設定 fnt_obj(色:青 シングルアンダーライン)
          fnt_obj = Font(color='0000FF', u='single')
          ws.cell(cur_col,cur_row).font = fnt_obj
          ws.cell(cur_col,cur_row+1).font = fnt_obj
      

    管理人がPythonの勉強のために購入した本

コメント