ブラウザから,Excelマクロ有効ブック(拡張子がxlsmのファイル)をアップロードすると,そこからマクロの部分を取り出して表示する,簡単なWebアプリケーションを更新しました.
最初に公開したときの記事は以下より読めます.
今回更新したWebアプリについて,提供する機能は変更ありません.初期画面は次のとおりです.
CalendarMaker.xlsmをアップロードしてみると,次のように,マクロが表示されました.最初の「olevba 0.55.1 on Python 3.8.1」により,バージョンが上がっているのが確認できました.
olevba 0.55.1 on Python 3.8.1 - http://decalage.info/python/oletools =============================================================================== FILE: **** Type: OpenXML ------------------------------------------------------------------------------- VBA MACRO ThisWorkbook.cls in file: xl/vbaProject.bin - OLE stream: 'VBA/ThisWorkbook' (略) MyInput = InputBox("Type in Month and year for Calendar") If MyInput = "" Then Exit Sub Resume End Sub
サーバでは,Microsoft Officeやオフィススイートを一切使用していません.かわりにDockerと,マクロを抽出するPythonライブラリのoletoolsを用いています.dockerコマンドが利用可能であれば,「docker pull takehiko/getvba」または「docker pull takehiko/getvba:alpine」のコマンドで,Dockerイメージを取得できます.またDockerfileを含むファイル一式は,以下より参照・入手できます.
2年前との違いは,Python 2を使用しなくなったことと,サイズ削減の試みです.https://github.com/decalage2/oletoolsを見ると,2019-04-04リリースのv0.54の中に「olevba, mraptor: full Python 3 compatibility, no separate olevba3/mraptor3 anymore」と書かれています.git cloneして中身を見ると,確かに,olevba.pyが主,olevba3.pyが従の内容になっていました.
そこで更新にあたり,Dockerのベースイメージをpython:3.8にし,実質的な処理を行う自作のpythonスクリプトvbaではPython 3を使用するよう,pythonとolevbaのパスを変更しました.
まずは手元のLinuxのコマンドライン上で,いろいろ実行:
$ docker pull python:3.8 $ docker run -it --rm python:3.8 bash root@****:/# which python /usr/local/bin/python root@****:/# python --version Python 3.8.1 root@****:/# ls /usr/local/bin 2to3 idle pip3 pydoc3.8 python3-config 2to3-3.8 idle3 pip3.8 python python3.8 easy_install idle3.8 pydoc python-config python3.8-config easy_install-3.8 pip pydoc3 python3 wheel root@****:/# ls /usr/bin/python* /usr/bin/python /usr/bin/python2.7 /usr/bin/python3.7 /usr/bin/python3m /usr/bin/python2 /usr/bin/python3 /usr/bin/python3.7m
Python 2.7も入っていますが,3.8を使うことにしましょう.pip install -U oletoolsを実行してolevba.pyの所在を確認してから,exitで抜けました.
Dockerfileをはじめ,gitの管理対象ファイルを一つ一つ読み直してから,必要最小限の箇所を書き換えて保存し,手元でビルドとコンテナ起動.エラーメッセージも出ましたが,中断することなくビルドできました.
次にサイズ削減です.というのも,docker imagesを実行したところ,できあがったイメージは961MBになっているのです.こんなアプリに約1GBは,大きすぎます.よく見ると,ベースイメージのpython:3.8が,932MBを占めています.
ベースイメージを,python:3.8-alpineに切り替えることにしました.ブランチをalpineにして,コミット済みです(https://github.com/takehiko/getvba/tree/alpine).
python:3.8を用いた場合,パッケージ管理はUbuntu系のapt-getでしたが,python:3.8-alpineのAlpine Linuxでは,apkコマンドです.「pip install -U oletools」のコマンド実行中に,ビルドできないというエラーが発生したため,Dockerfileには「apk add --no-cache alpine-sdk libffi-dev openssl-dev」を入れ,あとでapk delしました.
日本語対応も不可欠です.getvbaを使用し始めた当初の目的は,授業で提出されたxlsmファイルからマクロを取り出すことであり,プロシージャ名や文字列に日本語が出現します.これまではapt-get nkfでインストールしていましたが,nkfのAlpine用パッケージはなさそうです.Pythonで処理を書くのも,バグが不安となり,結局,nkf-2.1.5.tar.gzをダウンロードしてmakeし,/usr/bin/nkfに置くようにしました.
以下を参照しながら,少しの試行錯誤で,完成させました.
- tom-tan/alpine-pkg-nkf: This is a nkf (Network Kanji Filter) package for Alpine Linux.
- Docker python:alpineでcffiのコンパイルに失敗する - スタック・オーバーフロー
- pip で Ansible がインストール出来ない。 - Qiita
出来上がったDockerイメージは,138MBとなりました(ちなみにpython:3.8-alpineは112MBでした).マクロに日本語が入ったファイル,入っていないファイルをアップロードしてみて,問題なく表示されました.Docker Hubで,masterとalpineのブランチの自動ビルドを設定し,https://hub.docker.com/r/takehiko/getvba/buildsにアクセスすると,10分もかからずに「Success」となっていました.