xlwingsを使用して画像一括貼り付けをしてみた

2023年2月10日

概要

こんにちは、xlwingsというPythonからExcelを自動化および相互操作ができるライブラリを使用して、特定フォルダーに置いた画像ファイル群を一括でエクセルファイルへ貼り付ける処理を自動化してみましたので備忘録ガテラ紹介します。

「xlwings」は「Excel」導入済であることが必須となりますので、基本的に、Windows環境で実行する想定となりますので、Linux等の環境で実行する場合は注意してください。

実行環境

  • Python 3.9.0
    • 依存ライブラリ
      • xlwings
  • Microsoft Windows [Version 10.0.19043.1469]
  • Microsoft® Excel® 2016 MSO (バージョン 2212 ビルド 16.0.15928.20196) 32 ビット

画像ファイル群をファイル名ソートする版

処理コードを以下に記載します。

import glob
import xlwings

# 貼り付ける画像を探す際のディレクトリ
# 「r"{ディレクトリパス}\*"」 左記のように先頭に「r」およびファイルパス末尾に「\*」を付与すること
INI_IMG_DIR = glob.glob( r"C:\Users\hoge\Desktop\images\*" )
# 保存先エクセルファイルファイルパス
SAVE_FILE_PATH = str( r".\hoge.xlsx" )
# 画像を貼り付けるエクエルシート名
SHEET_TITLE = 'hoge'
# 貼り付ける画像の横幅サイズ
PICTURE_PASTE_WIDTH = 700

try:
    xl = xlwings.main
    wb = xl.Book( )

    wb.sheets.add( SHEET_TITLE )
    wb.sheets[ 'Sheet1' ].delete( )

    start_picture_paste_locate_height = wb.sheets.active.range( 'A1:A3' ).height

    for index, value in enumerate( sorted( INI_IMG_DIR ) ): # ファイル名でソート
        print( str( index ) + ' : ' + value )

        if index == 0:
            wb.sheets.active.pictures.add( value, top = start_picture_paste_locate_height
                                            , width = PICTURE_PASTE_WIDTH )
        else:
            wb.sheets.active.pictures.add( value, top = wb.sheets[ 0 ].pictures[ index - 1 ].height
                                            + wb.sheets[ 0 ].pictures[ index - 1 ].top
                                            , width = wb.sheets[ 0 ].pictures[ index - 1 ].width )

        print( str( index ) + ' : ' + wb.sheets[ 0 ].pictures[ index ].name + ', '
                    + str( wb.sheets[ 0 ].pictures[ index ].height )
                    + ', ' + str( wb.sheets[ 0 ].pictures[ index ].width ) + '\n' )

    wb.save( SAVE_FILE_PATH )
    wb.close( )
except Exception as e_x:
    print( '例外が発生しました。' + str( Exception( e_x ) ) )
    wb.close( )
    exit( 1 )

処理内容

「INI_IMG_DIR」の変数に、Excelへ貼り付けたい画像群を置いたフォルダーのパスをいれます。

「SHEET_TITLE」で貼り付けたエクセルファイルを保存するフォルダーを指定します。

横幅を「PICTURE_PASTE_WIDTH」で定義しており、貼り付けられる画像はこちらで定義したサイズに固定され、縦幅は元の画像サイズに従い、画像が重複しないよう縦一列に貼り付けられていきます。

画像ファイル群をファイル更新日時で昇順ソートする版

#!/usr/bin/env python
from pathlib import Path
import os
import xlwings
​
# 貼り付ける画像を探す際のディレクトリ
# 「r"{ディレクトリパス}\*"」 左記のように先頭に「r」を付与すること
INI_IMG_DIR = r'C:\Users\hoge\Desktop\images'
# 保存先エクセルファイルファイルパス
SAVE_FILE_PATH = str( r".\hoge.xlsx" )
# 画像を貼り付けるエクエルシート名
SHEET_TITLE = 'hoge'
# 貼り付ける画像の横幅サイズ
PICTURE_PASTE_WIDTH = 700
​
dir_tmp = list( Path( INI_IMG_DIR ).glob( r'*' ) )
​
date_time_sort = dir_tmp
​
date_time_sort.sort( key = os.path.getmtime ) # 日時昇順ソート
​
try:
    xl = xlwings.main
    wb = xl.Book( )
​
    wb.sheets.add( SHEET_TITLE )
    wb.sheets[ 'Sheet1' ].delete( )
​
    start_picture_paste_locate_height = wb.sheets.active.range( 'A1:A3' ).height
​
    for index, value in enumerate( date_time_sort ):
        print( str( index ) + ' : ' + str( value ) )
​
        if index == 0:
            wb.sheets.active.pictures.add( value, top = start_picture_paste_locate_height
                                            , width = PICTURE_PASTE_WIDTH )
        else:
            wb.sheets.active.pictures.add( value, top = wb.sheets[ 0 ].pictures[ index - 1 ].height
                                            + wb.sheets[ 0 ].pictures[ index - 1 ].top
                                            , width = wb.sheets[ 0 ].pictures[ index - 1 ].width )
​
        print( str( index ) + ' : ' + wb.sheets[ 0 ].pictures[ index ].name + ', '
                    + str( wb.sheets[ 0 ].pictures[ index ].height )
                    + ', ' + str( wb.sheets[ 0 ].pictures[ index ].width ) + '\n' )
​
    wb.save( SAVE_FILE_PATH )
    wb.close( )
except Exception as e_x:
    print( '例外が発生しました。' + str( Exception( e_x ) ) )
    wb.close( )
    exit( 1 )

まとめ

画像をいちいちサイズ調整してExcelへ貼り付けていくのが手間と時間が掛かっていたので今回、こちらの自動化をできたことで、手間が大幅に省けて良かったです。