Excelファイルから画像を取り出す

Python

なぜかメールで写真を送るだけなのに、Excelに貼り付けて送ってくる上司、あなたの会社にもいませんか?Excel以外はアプリにあらず。そんなExcel原理主義者が生み出す謎ファイル、ありますよね。

はたまた、いわゆる神エクセルの報告書やら台帳やらに貼り付けてある写真。よけいなものはいらないから写真だけをくれという場合ありませんか?

Excelファイルの正体

Excelファイルの正体は、XMLと付帯するバイナリデータをまとめたZIPファイルである。というのは結構有名な話かと思います。このXMLには、どのシートのどのセルにどんな値があるよ、ということが延々と記述されています。画像などのファイルはまとめてフォルダに保存され、どの画像がどこに貼ってあるんだよ、という情報がXMLに記されています。

Excelアプリは、このXMLを読み取りワークブックとして組み立てて表示しているわけです。

実は、Excelファイルの拡張子をむりやり変更してZIPファイルとして展開することで、これらの「Excelの中身」を見ることができます。よって、その中から画像が保存されているフォルダを取り出すことで画像だけを手に入れられるのです。

と、ここまではネット上でぼちぼち出回っている情報なので、ご存じの方や、実際にやってみた方もいらっしゃるでしょう。たしかにこの方法で画像ファイルを抜き出すことはできます。

しかし!神エクセル撲滅協会理事(自称)の私としては、それでは納得できません!もっとスマートかつスタイリッシュに神エクセルを葬り去りたい!

ということで、神エクセルをゴミ箱に放り込む感覚で、画像だけを取り出すアプリを完成させました。


理屈は簡単で、前述の拡張子を変更して取り出す手順を自動化しているだけです。スクリプトはPythonで次のような極めて簡単なコードです。

import os
import sys
import zipfile

try:
    file = sys.argv[1]

    p = sys.executable if getattr(sys, 'frozen', False) else __file__
    cd = os.path.dirname(os.path.abspath(p))

    with zipfile.ZipFile(file) as xlsx:
        for file_name in xlsx.namelist():
            if 'xl/media/' in file_name:
                xlsx.extract(file_name, cd)
except:
    pass

これをPyInstallerで実行ファイルとしてアプリ化しています。

アプリに神エクセルをドラッグ&ドロップすることでこのスクリプトが走ります。取り出した画像ファイルはアプリがある場所へ[xl/media/]というフォルダ構成で出力されます。なぜこんなフォルダ構成かというと、Excelがそうだからです。本当に、そのまま抜き出しているだけです。面倒くさいので。

(全然スマートじゃないじゃんという突っ込みは聞こえません。)

元になったExcelファイルには何も影響を与えませんので、そのまま利用できます。いずれ、放ったファイルを画像だけ抜いてそのままゴミ箱へ直行させる機能をつけたいですね。

アプリはページ下部からダウンロードできます。

使用方法

拡張子xlsのファイルは処理できません。xlsxに保存しなおすか、あきらめてください。

サンプルとしてこのようなファイルを手元にあったので使います。準備しました。ここから画像だけ取り出します。

1.アプリを入手して適当なフォルダへ配置してください。

2.アプリへ対象のExcelファイルをドラッグ&ドロップします。コマンドプロンプトの黒い画面が一瞬見えると思いますが、こいつの仕業です。ウイルスではありません。ご安心ください。

3.アプリがあるフォルダへ【xl】というフォルダができます。

4.【xl】フォルダの中の【media】フォルダに画像データがあります。

エラーはすべて握り潰す仕様ですので、何も起こらなかったらエラーしています。

アプリを入手する

利用上のご注意

  • ダウンロードしたファイルを利用したことにより生じた結果については、利用者ご自身に責任を負っていただきます。
  • ご利用前に使用方法をご確認ください。
  • 当方は成果物の正確性について最善を尽くしますが保証はいたしません。
  • Windows11 Microsoft365 環境でのみ動作確認済み。

Downloadボタンを押下した時点で注意事項に同意したものとみなします。

excel_image_extraction.exe

おわり。