LoginSignup
0
1

More than 1 year has passed since last update.

DockerでLibreOffice Basicマクロを実行する(2022年版)

Last updated at Posted at 2022-12-10

これは LibreOffice Advent Calendar 2022 11日目の記事です。


2年前の Advent Calendar でこういうのを書きました。

ひさしぶりにこれをやってみたら動かなくなっていました。詳しく調べられていませんが バージョン 6.x と 7.x の間のどこかで挙動が変わったみたいです。

おさらい

まずは何をやっていたかを簡単におさらい。詳しくは上記の記事を参照してください。

(1) LibreOffice 本体のユーザ管理のマクロの領域に動かしたい LibreOffice Basic のソースを格納する

(2) 格納したプログラムを以下で実行する

libreoffice \
  --headless --norestore --nologo --nofirststartwizard --nolockcheck \
  "vnd.sun.star.script:Standard.${mod_name}.Main?language=Basic&location=application"

対策

エラーメッセージが出るわけでもないので途方に暮れてしまったのですが、あれこれ試した結果、次のように引数でファイルを渡すと動くことが分かりました。

libreoffice \
  --headless --norestore --nologo --nofirststartwizard --nolockcheck \
  blank.ods \
  "vnd.sun.star.script:Standard.${mod_name}.Main?language=Basic&location=application"

ためしに空のファイルを渡してみたところ、空のファイルでも動きました。ただ、ここは LibreOffice で開けるファイルを渡しておいた方が無難でしょうね。あらかじめファイルを用意しないといけないのは面倒ですが。

また、ユーザの操作を待ち受けるモードに入ってしまうのか、勝手に終了してくれないので StarDesktop.terminate() で明示的に終了させる必要がありました。場合によっては外部からプロセスを kill する方式でもよいかもしれません。

これで動きました

Dockerfile

  • ベースイメージを変更: 18.04 → 22.04
    • これは上記の動作しない問題とは無関係だと思いますが、あわせてバージョンを上げておきました
  • libreoffice-calc のバージョンを明示的に指定
FROM ubuntu:22.04
RUN apt-get update \
  && apt-get -y install --no-install-recommends \
    libreoffice-calc=1:7.3.7-0ubuntu0.22.04.1 \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*

  # ~/.config/libreoffice 以下を生成
RUN libreoffice --headless --terminate_after_init

WORKDIR /root/work

sample.sh

  • libreoffice コマンドの引数にファイルを追加
  • StarDesktop.terminate() を追加
escape_xml() {
  cat \
    | sed -e 's/&/\&/g' \
    | sed -e 's/"/\"/g' \
    | sed -e "s/'/\'/g" \
    | sed -e 's/</\&lt;/g' \
    | sed -e 's/>/\&gt;/g'
}

print_basic_src() {
  cat << BAS
Sub Main
  Dim fid As Integer
  fid = Freefile
  Open "/tmp/output" For Binary Access Write As fid
  Put(fid, 1, CStr(Time()) & Chr(10))
  Close fid
  StarDesktop.terminate()
End Sub
BAS
}

user_bas_dir="${HOME}/.config/libreoffice/4/user/basic"
mod_name=Module1
mod_file="${user_bas_dir}/Standard/${mod_name}.xba"

cat << XML > ${mod_file}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
  <script:module
    xmlns:script="http://openoffice.org/2000/script"
    script:name="${mod_name}"
    script:language="StarBasic"
  >
    $(print_basic_src | escape_xml)
  </script:module>
XML

libreoffice \
  --headless --norestore --nologo --nofirststartwizard --nolockcheck \
  blank.ods \
  "vnd.sun.star.script:Standard.${mod_name}.Main?language=Basic&location=application"

cat /tmp/output

イメージのビルドと実行

  # イメージをビルド
docker build -t libreoffice-basic:2022 .

  # 実行
docker run --rm -v "$(pwd):/root/work" libreoffice-basic:2022 bash sample.sh

次のように時刻が表示されればOKです。

$ docker run --rm -v "$(pwd):/root/work" libreoffice-basic:2022 bash sample.sh
Warning: failed to launch javaldx - java may not function correctly
10:59:40 PM
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1