Pythonを使うとフォルダ内の全てフォルダやファイル名を取得して一覧にすることができます。
これは下位フォルダの内のファイルも含めて取得可能です。
今回は、フォルダ内の全てのファイル名を取得してエクセルへ出力するプログラムを紹介します。
・階層ごとにExcelへ書き込む
それでは以下で詳しく紹介していきます。
指定フォルダ内の全フォルダ・全ファイルを取得する
今回は以下の作業をpythonで行うことを目指します。
1. フォルダ内のフォルダやファイルを取得
2. 取得したフォルダやファイルの名前をExcelに出力
フォルダに下位フォルダが存在する場合、そのフォルダ内のファイルも取得(再帰的に処理)していきます。
詳しいプログラム解説は後半で行います。
Pythonプログラムを実行するための準備
事前の準備としてpathlibを使えるようにライブラリ設定をします。
準備1|openpyxlモジュールのインストール
pip install openpyxl
Excel操作で使用します。
準備2|pathlibモジュールのインストール
pip install pathlib
今回はpathlibで、フォルダ内に存在するファイルやフォルダを全部取得します。
Pythonプログラム解説
この記事で紹介するプログラムを解説しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#プログラム1|ライブラリの設定 import pathlib import os #プログラム2|mainプロシージャ def main(): Folderpath = os.getcwd()#対象フォルダを指定 outputpath = 'list.txt'#テキストファイルを作成 f = open(outputpath, mode='w')#テキストファイルを書き込みモードで開く GetFolderFileNames(Folderpath, 0, f)#GetFolderFileNames(プログラム3)を呼び出す #プログラム3|階層ごとのフォルダやファイルを書き出す関数 def GetFolderFileNames(path, kaiso, f): files = pathlib.Path(path).glob('*')#その階層のフォルダやファイルを取得 # プログラム4|フォルダやファイルを一つずつ書き出す for file in files: output = '\t' * kaiso + file.name + '\n' f.write(output) # プログラム5|フォルダの場合、その下の階層のフォルダやファイルをGetFolderFileNames(プログラム6)を呼び出す if file.is_file() == False: GetFolderFileNames(file, kaiso+1, f) #プログラム6|mainを呼び出す if __name__ == "__main__": main() |
以下で詳しく説明しています。
プログラム1|ライブラリ設定
1 2 3 |
# プログラム1|ライブラリ設定 import openpyxl as px import pathlib |
以下で一行ずつプログラムを解説します
プログラム解説
2 |
import openpyxl as px |
openpyxlはExcel操作で使います。
「openpyxl as px」とすることで、openpyxlをpxという変数で扱うようにしています。
3 |
import pathlib |
フォルダ内のフォルダやファイルを取得するときに使用します。
プログラム2|エクセルを作成して対象フォルダを指定(main)
1 2 3 4 5 6 7 8 |
# プログラム2|エクセルを作成して対象フォルダを指定 def main(): Folderpath = r'D:\DropBox\Dropbox\Python\Program\100_Excel\126_Excel_GetFolderFileName' wb = px.Workbook() ws = wb.active GetFolderFileNames(Folderpath, 4 , 1, ws) filename = 'File一覧.xlsx' wb.save(filename) |
以下で一行ずつプログラムを解説します
プログラム解説
2 |
def main(): |
「def main():」で
Pythonにおいて、関数はdefで記載します。
1 2 |
def 関数名1(): 処理1 |
引数なしで呼び出すときは、()に何も記載せずに記述します。
3 |
Folderpath = r'D:\DropBox\Dropbox\Python\Program\100_Excel\126_Excel_GetFolderFileName' |
取得したいフォルダを指定します。
ここでは画像のフォルダ内に存在するファイルを全て取得していきます。
さてWindowsの場合、パス区切り文字は「\(バックスラッシュ)」です。
しかし、文字列でバックスラッシュを記述するにはエスケープを考慮し、バックスラッシュを2文字連続して書く必要があります。
1 |
'D:\\DropBox\\Dropbox\\Python\\Program\\100_Excel\\126_Excel_GetFolderFileName' |
しかしraw文字列(r”)を使うとエスケープが無効になるため、バックスラッシュを1文字だけで記載可能です。
1 |
r'D:\DropBox\Dropbox\Python\Program\100_Excel\126_Excel_GetFolderFileName' |
このようにWindowsでパスを記述するとき、r”を使うと書きやすくなります。
ただしどちらを記載しても問題ないため、お好みをほうを使えば良いです。
ここではr”を採用しています。
4 |
wb = px.Workbook() |
新しいエクセルファイルを作成します。(新しいエクセルをwbとする)
ここで作成したエクセルファイルにファイル名を出力します。
ファイル名を出力するプログラムはプログラム3で紹介します。
5 |
ws = wb.active |
作成したエクセルのシートをwsとします。
このwsにエクセルを出力します。
6 |
GetFolderFileNames(Folderpath, 4 , 1, ws) |
GetFolderFileNamesという関数(プログラム3)を呼び出します。
GetFolderFileNamesは4つの引数を必要とします。
2. rowIndex:エクセルの行数(ここでは4、つまり4行目)
3. colIndex:エクセルの列数(ここでは1、つまり1列目)
4. ws:エクセルのシート(ここではws)
上記の4つを引数に指定して、プログラム3を呼び出します。
7 |
filename = 'File一覧.xlsx' |
filenameという変数を「File一覧.xlsx」とします。
この名前でエクセルを保存します。
なお、この時点でプログラム3の処理が完了し全ての情報がエクセルに出力されています。
8 |
wb.save(filename) |
filename(File一覧.xlsx)で保存します。
プログラム3|対象フォルダ内のファイルを取得
1 2 3 4 5 6 7 8 9 10 |
# プログラム3|対象フォルダ内のファイルを取得 def GetFolderFileNames(path, rowIndex, colIndex, ws): files = pathlib.Path(path).glob('*') for file in files: ws.cell(row=rowIndex, column=colIndex).value = file.name if file.is_file() == True: rowIndex+=1 else: rowIndex = GetFolderFileNames(file, rowIndex+1, colIndex + 1, ws) return rowIndex |
以下で一行ずつプログラムを解説します
プログラム解説
2 |
def GetFolderFileNames(path, rowIndex, colIndex, ws): |
関数GetFolderFileNames(path, rowIndex, colIndex, ws)を呼び出します。
このとき4つ引数を受け取ります。
2. rowIndex:エクセルの行数
3. colIndex:エクセルの列数
4. ws:エクセルのシート
受け取った引数をもとにエクセルに出力していきます。
以下のプログラムで、受け取ったpath(フォルダパス)の中に存在するファイルを取得します。
3 |
for file in files: |
変数filesにpathで指定したフォルダ内の全てのファイルとフォルダを取得します。
画像ではPythonプログラムがあるフォルダを紹介していますが、再帰的に動かすことで全てのフォルダを調査します。
4 |
ws.cell(row=rowIndex, column=colIndex).value = file.name |
変数filesに含まれるフォルダやファイルをfor文で繰り返し処理をしていきます。
5 |
if file.is_file() == True: |
wsの(rowIndex)行目、(colIndex)列目にfile.nameを出力します。
このようにws, rowIndex, colIndexの3つの引数は、エクセルに出力するときに使用しています。
6 |
rowIndex+=1 |
「もしfileがファイル型であれば」という処理を入れます。
もしこれがTrue、つまりファイル型であれば、以下の処理を実行します。
7 |
rowIndex+=1 |
rowIndexという変数に1を加えます。
こうすることで、次のファイル名が一つ下の行に記載されるようにします。
逆にこれをやっておかないと、エクセルの同じ行にファイル名が出力されてしまいます。
8 |
else: |
6行目の「if file.is_file() == True:」のFalseの際の処理プログラムです。
「fileがファイル型でなければ」を指します。
ファイル型でなければ、以下をプログラムを実行します。
9 |
rowIndex = GetFolderFileNames(file, rowIndex+1, colIndex+1, ws) |
上記のプログラムでは、右辺である「GetFolderFileNames(file, rowIndex+1, colIndex+1, ws)」が処理されます。
その処理結果からrowIndexを新しい値に更新します。
さてGetFolderFileNamesでプログラム3を呼び出すのですが、これはすなわちフォルダの中でフォルダを見つける度に、GetFolderFileNamesを呼び出す処理を行っています。
こうすることで、全ての下位フォルダ内のファイルを取得することが可能です。
このとき、引数は以下です。
2. rowIndex+1:+1することで、次の行に出力させる
3. colIndex+1:+1することで、次の列に出力させる(下位フォルダごとに出力列を右にずらす)
4. ws:対象のエクセルシートは変更なし
イメージとしてはプログラム3を実行中にフォルダを見つけたら、プログラム3を動かすイメージです。
このような処理をする関数は再帰関数と呼ばれます。
再帰的に動かすことで、短いプログラムで複雑な処理を実行できます。
10 |
return rowIndex |
returnとは、関数の呼び出し元に「値」を返すことを指します。
ここではrowIndexの値を返します。
1行前のプログラムで「rowIndex = GetFolderFileNames(file, rowIndex+1, colIndex+1, ws)」としていました。
この左辺はrowIndexとなっていますが、このrowIndexの値を返しています。
rowIndexはファイル名をエクセルに出力ときの行数を指しています。
ファイルをエクセルに出力するたびに、1行加算していく必要があるため、処理が完了したら、それを返すようにしているのです。
これをしておかないと、以下の画像ように1行に1ファイル名(もしくはフォルダ名)を出力できず、重複する行が出てきてしまいます。
それを避けるためにrowIndexの値を返しています。
プログラム4|mainを呼び出す
1 2 3 |
# プログラム4|mainを呼び出す if __name__ == "__main__": main() |
以下で一行ずつプログラムを解説します
プログラム解説
2 |
if __name__ == "__main__": |
もしmainというプログラムがあれば、以下のプログラムを実行します。
3 |
main() |
「main()」というプログラム(プログラム2)を呼び出します。
プログラムの解説はここまでです。
Pythonについて詳しく理解したいなら
Pythonを活用すると、仕事を効率化できる幅を広げることができます。
たとえば私が実際にPythonを活用して効率化してきた作業は以下の記事で紹介しています。
興味がある人は以下の記事もご覧ください。
Python×効率化のサンプル
Pythonで効率化できる事例をサンプルコード付きで紹介しています。
Python×Excel
PythonとExcelで自動化できることを紹介しています。
事例も数多く紹介しているので、ぜひ参考にしてみてください。
Python×PDF
PythonとPDFで自動化できることを紹介しています。
Pythonって難しい?
Pythonの難易度などについては、以下で紹介しています。
勉強の参考になれば幸いです。