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の勉強のために購入した本
- os.walk()にルートディレクトリを指定すると、その配下にあるファイルの一覧を再帰的に辿って取得することが出来る。
コメント