5
5

More than 3 years have passed since last update.

エクセルにスクショ貼り付けの自動化プログラムを作ったよ

Posted at

はじめに

こんにちは、rickyです。
皆さんはスクショをエクセルに張り付ける仕事が実在すると思いますか?
私はその日までそんな仕事は都市伝説だと思っていました。
ですが、ついこの前私はその仕事をさせられることになりました。
ただひたすらフォルダから画像をエクセルに張り付ける仕事・・・
そんな時ふと気づきました。
これ、プログラムで自動化できるんじゃ?
調べてみるとエクセルに画像を張り付けるライブラリと、画像のフォルダを読み込み、ファイル名を取得するライブラリがあることがわかりました!
そこで私はプログラムにおこしてみることにしました。

概要

前提:貼り付ける画像フォルダがすでにあることを前提とします。
今回のソースコードはエクセルのパスと画像フォルダのパスを変数に初期化して実行します。
処理の流れとしては指定したエクセルに接続、シートを末尾に追加し、そのシートに画像ファイルを張り付けます。
またシートの名前の付け方は画像フォルダに従い1-1-1のように3つの数字で表されます。
ちなみに1-1-1_1や1-1-1_2などは1-1-1のシートに一緒に張り付けられます。
処理が終了したら文字列を表示します。

以下ソースコードです。

png_file_name.py
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
import glob, os, re, cv2

'''
Description to shorten the interval of pasting 
when the already pasted image is small
'''
def check_img_size(img):
    img_check = cv2.imread(img)
    img_check_hight = img_check.shape[0]
    cell_interval = 0
    if img_check_hight < 500:
        cell_interval = 20
    elif img_check_hight < 600:
        cell_interval = 23
    elif img_check_hight < 700:
        cell_interval = 26
    elif img_check_hight < 800:
        cell_interval = 30
    elif img_check_hight < 900:
        cell_interval = 33
    else:
        print("ERROR 予期しないサイズのファイルがあります。")
    return cell_interval

def paste_image(ws2, right_num_groups):
    before_cell_num = 0
    for num in range(len(right_num_groups)):
        capture_num = 2
        if num != 0:
            cell_size = check_img_size(right_num_groups[num - 1])
            capture_num = before_cell_num + cell_size + 2
        capture_area = 'A' + str(capture_num)
        before_cell_num = capture_num
        ws2.add_image(Image(right_num_groups[num]), capture_area)

def connect_excel(right_num_groups, folder_num):
    wb = load_workbook(filename = excel_name)
    sheet_name = str(folder_num + 1) + "-" + str(sheet_name_list[1]) + "-" + str(sheet_name_list[2])
    sheet_name = sheet_name.rstrip("\'>[0-9]")
    ws2 = wb.create_sheet(title = sheet_name)
    ws2['A1'] = "※画面キャプチャーを添付する"
    paste_image(ws2, right_num_groups)
    wb.save(filename = excel_name)

# TODO: change excel's path and evidence folder path
excel_name = 'test.xlsx'
evidence_folder = "C:\\Users\\username\\Documents\\evidence"
folder_list = os.listdir(evidence_folder)
re_word = r'([0-9]-){2}[0-9]'
check_list = []
for folder_num in range(len(folder_list)):
    num_folder = evidence_folder + "\\" + folder_list[folder_num]
    png_list = os.listdir(num_folder)
    for png_num in range(len(png_list)):
        re_png_name = re.match(re_word, png_list[png_num])
        sheet_name_list = str(re_png_name).split("-")
        png_re_name = num_folder + "\\" + re_png_name.group() + "*"
        right_num_groups = glob.glob(png_re_name)
        if right_num_groups == check_list:
            continue
        connect_excel(right_num_groups, folder_num)
        print(right_num_groups)
        check_list = right_num_groups
print("Finish!!")

ソースコードの解説

check_img_size(img)

対象の画像の高さを評価し、数値を返しています。
これはエクセルに張り付ける際に画像が重なり合ったり、離れすぎないようにするための記述です。

paste_image(ws2, right_num_groups)

画像の貼り付けを実行する処理です。
before_cell_numという変数で貼り付けを実行する画像が重ならないように、先に張り付けた画像の大きさを評価するためのものです。

connect_excel(right_num_groups, folder_num)

エクセルに接続する処理です。
指定されたエクセルへの接続と、シートの追加、文字列の挿入を行っています。

main

画像ファイルの特定と階層の移動、そしてglobライブラリによる正規表現での全画像の取得になります。
そして最後に処理が終了すると文字列が表示されます。

終わりに

今回、画像を扱った処理を始めてプログラムにおこしました。
画像の処理の仕方に不安があったのですが、うまく実行できてよかったです。
終わった後にソースコードを見返した感想としては変数名の付け方に問題があると感じました。
folder_numとnum_folderが同時に存在するのはどうかと思う・・・
しかし、うまく処理が動いて、画像がすべてエクセルに張り付けられているのを見たときは純粋にうれしかったです。
このコードがほかの方の役に立てば幸いです。
GitHubからコードをクローン出来ます。
ぜひ使ってみてください。
感想、まさかり大歓迎です。
ここまで読んでくださってありがとうございます。

5
5
2

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
5
5