GUIを表示せねば不可。ダサイ……。でもこれ以外の方法が見つけられず。
成果物
コード
run.sh
soffice --calc --norestore "--accept=pipe,name=librepipe;urp;" & { sleep 3 ./new_doc.py jobs kill %% }
要点は以下。
--headless
を削除した- これがあると
XSCRIPTCONTEXT.getDesktop().getCurrentComponent()
からシートを取得できない。ファイルも新規保存できない。
- これがあると
--norestore
を追加した- これがないと不要なダイアログが起動してしまいマクロが停止してしまう
sleep 3
- LibreOffice Calc の GUI が起動するまでの時間だけ待機させる必要がある。さもなくば以下エラーになる
__main__.NoConnectException: Connector : couldn't connect to pipe librepipe(10)
--headless
がないためGUIが立ち上がってしまう。つまり、ファイルを新規保存するためには、必ずGUIを起動させる必要がある。マクロ実行完了後はkill
しているが、ウザいわ―……。
--invisible
すればいいかと思うでしょ? 残念、以下エラーになりました。
Traceback (most recent call last): File "./new_doc.py", line 29, in <module> sheet = doc.getSheets().getByIndex(0) AttributeError: 'NoneType' object has no attribute 'getSheets'
ヘルプを翻訳したら「非表示モード」って書いてあるのに。ドキュメントとダイアログはAPIを介して制御およびオープンされます。
って書いてあるのに、NoneType
なんですけど。なんか間違ってるの?
--invisible非表示モードで開始します。スタートアップロゴも 最初のプログラムウィンドウが表示されます。応用 制御することができ、ドキュメントとダイアログは APIを介して制御およびオープンされます。パラメータを使用して、 プロセスは、taskmanagerを使用してのみ終了できます (Windows)またはkillコマンド(UNIXライクなシステム)。それ --quickstartと組み合わせて使用することはできません。
どうすればGUIを起動せず新規ファイル作成できるのか……。とりあえずこれで妥協する。
new_doc.py
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import uno import unohelper from pythonscript import ScriptContext import os.path import datetime def connect_script_context(host='localhost', port='2002', namedpipe=None): UNO_RESOLVER = "com.sun.star.bridge.UnoUrlResolver" UNO_DESKTOP = "com.sun.star.frame.Desktop" localCtx = uno.getComponentContext() localSmgr = localCtx.ServiceManager resolver = localSmgr.createInstanceWithContext(UNO_RESOLVER, localCtx) if namedpipe is None: uno_string = 'uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext' % (host, port) else: uno_string = 'uno:pipe,name=%s;urp;StarOffice.ComponentContext' % namedpipe ctx = resolver.resolve(uno_string) smgr = ctx.ServiceManager XSCRIPTCONTEXT = ScriptContext(ctx, smgr.createInstanceWithContext(UNO_DESKTOP, ctx), None) return XSCRIPTCONTEXT XSCRIPTCONTEXT = connect_script_context(namedpipe='librepipe') desktop = XSCRIPTCONTEXT.getDesktop() doc = desktop.getCurrentComponent() sheet = doc.getSheets().getByIndex(0) sheet.getCellByPosition(0,0).Value = 1234 now = datetime.datetime.now() timestamp = now.strftime('%Y%m%d%H%M%S') file = os.path.join(os.path.dirname(os.path.abspath(__file__)), timestamp + '.ods') url = unohelper.systemPathToFileUrl(file) doc.storeToURL(url, ())
現時刻をファイル名にする。yyyymmddHHMMSS.ods
。出力先はnew_doc.pyファイルが存在するディレクトリである。
ググるとよく見つかる以下コードではシートを取得できなかった。APIわけわからん。コマンド引数によってAPIの動作が変化するの?
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.getSheets().getByIndex(0)
Traceback (most recent call last): File "./new_doc.py", line 31, in <module> sheet = doc.getSheets().getByIndex(0) AttributeError: getSheets
所感
GUIを表示せずバッチ処理でods
新規ファイルを作成したかったのに……。soffice
コマンド単独でできてもいいくらい基本的なことだと思うのだが……。
対象環境
- Raspbierry pi 4 Model B
- Raspbian buster 10.0 2019-09-26 ※
- bash 5.0.3(1)-release 学習まとめ
- LibreOffice 6.1.5.2 ※
$ uname -a Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux