ねもぷらす

ふぁいんでぃんぐねもの日記。プログラミングとか育児とか

SikuliX-2.0.5 で openpyxl を使う

qiita.com
Qiitaに書いてみました。技術系はQiitaのほうが書きやすい…


sikulix で openpyxl を利用する方法が見当たらなかったので、整理のため久々にブログを更新しました。


sikulix.com


2022/8/22現在、SikuliXの最新安定バージョンは 2.0.5 です。
無料で使えるRPAツールの先駆者ですが、エクセルの操作は Excel2003 以前の拡張子「.xls」しか操作できません。
また、エクセルは読み込みのみか、書き込みのみで操作する必要があり、
編集したい場合は xlrd で全件読み込んだ後、xlwt で1発で保存する、という必要があります。

import xlrd
import xlwt

openpyxl であれば、拡張子「.xlsx」に対する 読み・書き が可能です。
エクセルを利用した転記や情報収集などをRPA化したいとき、逐次エクセルへ操作中の状況が書込・保存できれば
SikuliXが予期せず終了した場合に安心できます。

ここから SikuliX-2.0.5 で openpyxl を無理やり利用する方法を記載しますが、
下記Q/Aのとおり、現バージョンでは推奨されていない手法になりますので利用にはご注意ください。

answers.launchpad.net


お品書き

  1. Python2.7用の openpyxl を収集、配備する
    1. openpyxl 2.6.4
    2. jdcal-1.4.1
    3. et_xmlfile-1.0.1
  2. Java用の XMLパーサ(Apache Xerces)を入手する
  3. SikuliX-2.0.5 をコマンドから起動する

1. Python2.7用の openpyxl を収集、配備する

SikuliX は Python2.7 相当で動作する Jython2.7 が採用されており、
pypi からダウンロードしたソースコード
手作業で『%USERPROFILE%\AppData\Roaming\Sikulix\Lib\site-packages』へ配備することで利用できるようになります。

Pythonは2.x系と3.x系に大別され、2.x系のサポートは 2021/2/1 に終了していますが、
バージョンを指定することで 2.x系 に対応した Python モジュールを入手可能です。
モジュールの利用可否を判断するのが大変なので、Python2.7.18 をインストールして
pipコマンドで入手することにしました。

$ pip download openpyxl==2.6.4 -d src
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Collecting openpyxl==2.6.4
  Using cached openpyxl-2.6.4.tar.gz (173 kB)
Collecting jdcal
  Using cached jdcal-1.4.1-py2.py3-none-any.whl (9.5 kB)
Collecting et_xmlfile
  Using cached et_xmlfile-1.0.1.tar.gz (8.4 kB)
Saved c:\python27\src\openpyxl-2.6.4.tar.gz
Saved c:\python27\src\jdcal-1.4.1-py2.py3-none-any.whl
Saved c:\python27\src\et_xmlfile-1.0.1.tar.gz
Successfully downloaded openpyxl jdcal et-xmlfile

openpyxl 2.6.4 をダウンロードすると、合わせて jdcal-1.4.1、et_xmlfile-1.0.1 がダウンロードされるので、すべてSikuliXのライブラリフォルダに格納します。

  • openpyxl-2.6.4.tar.gz

圧縮ファイルを解凍し、
dist\openpyxl-2.6.4.tar\openpyxl-2.6.4\openpyxl をフォルダごと
%USERPROFILE%\AppData\Roaming\Sikulix\Lib\site-packages にコピー

  • jdcal-1.4.1-py2.py3-none-any.whl

拡張子「.whl」は圧縮ファイル。
解凍して、直下の「jdcal.py」ファイルを
%USERPROFILE%\AppData\Roaming\Sikulix\Lib\site-packages にコピー

  • et_xmlfile-1.0.1.tar.gz

圧縮ファイルを解凍し、
et_xmlfile-1.0.1\et_xmlfile をフォルダごと
%USERPROFILE%\AppData\Roaming\Sikulix\Lib\site-packages にコピー


これでPythonモジュールは配備されましたが、SikuliXを起動し、

import openpyxl

とすると、下記のエラーが得られます。

[error] JythonRunner: runPython: (
import openpyxl
) raised: Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "%USERPROFILE%\AppData\Roaming\Sikulix\Lib\openpyxl\__init__.py", line 6, in <module>

... 略 ...

ory.loadClass(XMLReaderFactory.java:200)
	at java.xml/org.xml.sax.helpers.XMLReaderFactory.createXMLReader(XMLReaderFactory.java:191)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
org.xml.sax.SAXException: org.xml.sax.SAXException: SAX2 driver class org.apache.xerces.parsers.SAXParser not found
java.lang.ClassNotFoundException: org.apache.xerces.parsers.SAXParser


org.apache.xerces.parsers.SAXParser がない、と怒られているので、
Apache Xerces のクラスファイルを入手・配備します。


2. Java用の XMLパーサ(Apache Xerces)を入手する

Apache Xerces(アパッチ ザーシーズ)から、Java用のバイナリファイルを入手します。
xerces.apache.org

作業時点で、バージョンは Xerces2 Java 2.12.2 - zip でした。
入手した圧縮ファイルから「xercesImpl.jar」ファイルを取得し、
C:\Users\fccl8912\AppData\Roaming\Sikulix\Extensions」フォルダに格納します。

以上で準備が整いました。

3. SikuliX-2.0.5 を起動する

sikulixide-2.0.5.jar ファイルをダブルクリックするか、
配備されたフォルダ内で

$ java -jar sikulixide-2.0.5.jar

と実行することで SikuliX を起動できます。

自己責任の操作となりますが、
以下のような簡単な操作であれば特に問題なく動作させることができました。

import openpyxl

# エクセルを作成
wb = openpyxl.Workbook()

# シート名を変更し、A1セルに値を書き込み
ws = wb.worksheets[0]
ws.title = u"サンプル"
ws.cell(row=1, column=1).value = u"A1セルに値を書き込み"

# 保存
wb.save(u"テスト.xlsx")

popup(u"作成しました。")


# エクセルの更新
wb = openpyxl.load_workbook(u"テスト.xlsx")

# シートを選択して、内容編集
ws = wb[u"サンプル"]
ws.cell(row=2,column=1).value = u"値を設定"
ws.cell(row=3,column=1).value = ws.cell(row=2,column=1).value

# 更新
wb.save(u"テスト.xlsx")

popup(u"更新しました。")


特殊な操作をするとどうなるかわかりませんが、データの読み書き程度の操作であれば行けるかも?
SikuliXなら簡単に GUI 操作の自動化が可能です。
高価な RPA ツールからの脱却に、SikuliX、いかがでしょうか!