0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

画像があるフォルダを指定してフォルダ内の画像をエクセルに張り付ける

Last updated at Posted at 2021-05-16

指定したディレクトリ内の画像ファイルをすべてExcelに貼り付けるプログラム。
参考にしたページ

import os
import glob
import imghdr
import openpyxl
from tkinter import filedialog

# 定数設定
INI_IMG_DIR = "D:\Python" # 貼り付ける画像を探す際の初期ディレクトリ
SHEET_TITLE = '画像貼り付け' # 画像を貼り付けるエクエルシート名
DIR_NAME_ROW = 1 # ディレクトリ名を記載するエクセルファイルの行番号

# 変数
max_height = [] # 各行の画像の高さの最大値を保持

def get_file_names(set_dir_name):
    """
    ディレクトリ内のファイル名取得(ファイル名のみの一覧を取得)
    """
    file_names = os.listdir(set_dir_name)
    # ファイルかどうかを判定して、ファイルの場合にはパスを渡す
    temp_full_file_names = [os.path.join(set_dir_name, file_name) 
                            for file_name in file_names 
                            if os.path.isfile(os.path.join(set_dir_name, file_name))]
    return temp_full_file_names

def attach_img(target_full_file_names, set_column_idx, set_dir_name):
    """
    画像を呼び出して、Excelに貼り付け
    """
    column_letter = ws.cell(row=DIR_NAME_ROW, column=set_column_idx).coordinate[0]
    ws.cell(row=DIR_NAME_ROW, column=set_column_idx).value = set_dir_name # 各列の1行目に、貼り付ける画像があるディレクトリ名を入力
    max_width = 0 # 画像の幅の最大値を保持するための変数
    target_full_file_names.sort() # ファイル名でソート
    for set_row_idx, target_file in enumerate(target_full_file_names):
        write_row = set_row_idx+1 # エクセルに書き込む行は0でなく1始まりなので+1
        if imghdr.what(target_file) != None: # 画像ファイルかどうかの判定
            img = openpyxl.drawing.image.Image(target_file)
            print('[' + column_letter + str(write_row+1) + ']' + target_file + ' を貼り付け')

            # 画像のサイズを取得して、セルの大きさを合わせる(画像同士が重ならないようにするため)
            height = img.height
            width = img.width
            if max_width < width:
                max_width = width
            if not max_height[set_row_idx:set_row_idx+1]: # 配列「max_height」において、「set_row_idx」番目の要素が存在しなければ、挿入
                max_height.insert(set_row_idx, height)
            if max_height[set_row_idx] < height:
                max_height[set_row_idx] = height
            ws.row_dimensions[write_row+1].height = max_height[set_row_idx] * 0.75
            ws.column_dimensions[column_letter].width = max_width * 0.13

            cell_address = ws.cell(row=write_row+1, column=set_column_idx).coordinate # セルの行列番号から、そのセルの番地を取得
            img.anchor = cell_address
            ws.add_image(img) # シートに画像貼り付け


# ワークブック設定
wb = openpyxl.Workbook()
ws = wb.worksheets[0] # 1番目のシートを編集対象にする
ws.title = SHEET_TITLE # 1番目のシートに名前を設定

# 貼り付ける画像を置いておくルートディレクトリを指定 ※日本語含むとうまくいかなかった
input_img_file = filedialog.askdirectory(title = "貼り付ける画像のフォルダを指定",
                                        initialdir=INI_IMG_DIR)

# 貼り付ける画像を置いておくルートディレクトリ内のディレクトリ名を再帰的に取得
dirs = glob.glob(os.path.join(input_img_file, '**' + os.sep), recursive=True)

# 各ディレクトリについて操作
for column_idx, dir_name in enumerate(dirs):
    f_names = get_file_names(dir_name) # ファイル名取得
    attach_img(f_names, column_idx+1, dir_name) # 画像貼り付け設定

# ファイルへの書き込み
save_file_path = filedialog.asksaveasfilename(title = "名前を付けて保存",
                                            filetypes = [("xlsx", ".xlsx"), ("xls", ".xls")], # ファイルフィルタ
                                            initialdir = "./", # 自分自身のディレクトリ
                                            defaultextension = ".xlsx")
wb.save(save_file_path)
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?