これは LibreOffice Advent Calendar 2021 の11日目の記事です。
↓これにちょろっと付け足して web API 化してみただけの記事です。
できたもの
webapi-2021
ブランチ
Java 版でやろうかと考えていたのですが、億劫になって JRuby 版でやりました。 JRuby で Sinatra 使った方が速い。
主な部分だけ抜き出すとこんな感じ。考えるのが面倒だったので REST ではなく RPC風で。普通に Sinatra を使ってるだけですね。あんまり書くことがない……
# app.rb
require "sinatra"
require_relative "libo_calc"
post "/calc" do
file = params["file"]
sheet_name = params["sheet"]
data = {}
Calc.open(file) do |doc|
sheet = doc.get_sheet_by_name(sheet_name)
case params["command"]
when "cell_get"
data = cell_get(sheet, params)
when "cell_set"
cell_set(sheet, params)
doc.save()
when "dump"
data = dump(sheet)
else
raise "unsupported command"
end
end
content_type :json
JSON.pretty_generate(data)
end
動かし方
イメージをビルド
docker build \
--build-arg USER=$USER \
--build-arg GROUP=$(id -gn) \
-t my:libo-jruby-webapi-2021 .
APIサーバ起動
./docker_run.sh ./jruby.sh app.rb -o 0.0.0.0
curl で動作確認
ファイルのパス、シート名、コマンド、パラメータを POST で渡します。
curl -XPOST 'http://localhost:4567/calc' \
-d 'file=./sample.fods' -d 'sheet=Sheet1' \
-d 'command=cell_set' \
-d 'col=0' -d 'row=2' -d "val=$(date "+%F_%T")"
#=>
{}
curl -XPOST 'http://localhost:4567/calc' \
-d 'file=./sample.fods' -d 'sheet=Sheet1' \
-d 'command=cell_get' \
-d 'col=0' -d 'row=2'
#=>
{
"val": "2021-12-11_11:03:20"
}
curl -XPOST 'http://localhost:4567/calc' \
-d 'file=./sample.fods' -d 'sheet=Sheet1' \
-d 'command=dump'
#=>
{
"rows": [
[
"(0, 0) 日本語テキスト 2021-01-02 14:34:26 +0900",
"b1"
],
[
"a2",
"(1, 1) 2021-01-02 14:34:26 +0900"
],
[
"2021-12-11_11:03:20",
"12.34"
],
[
"",
"0"
]
]
}
読み書きできてます。
Ruby + Faraday
適当な HTTP クライアントライブラリを使って試してみました。
require "faraday"
puts "cell_set =>"
res = Faraday.post(
"http://localhost:4567/calc",
{
file: "./sample.fods", sheet: "Sheet1",
command: "cell_set",
col: 0, row: 2, val: Time.now.to_s
}
)
puts res.body
puts "cell_get =>"
res = Faraday.post(
"http://localhost:4567/calc",
{
file: "./sample.fods", sheet: "Sheet1",
command: "cell_get",
col: 0, row: 2
}
)
puts res.body
puts "dump =>"
res = Faraday.post(
"http://localhost:4567/calc",
{
file: "./sample.fods", sheet: "Sheet1",
command: "dump"
}
)
puts res.body
$ bundle exec ruby sample_webapi_client.rb
cell_set =>
{
}
cell_get =>
{
"val": "2021-12-11 11:09:49 +0900"
}
dump =>
{
"rows": [
[
"(0, 0) 日本語テキスト 2021-01-02 14:34:26 +0900",
"b1"
],
[
"a2",
"(1, 1) 2021-01-02 14:34:26 +0900"
],
[
"2021-12-11 11:09:49 +0900",
"12.34"
],
[
"",
"0"
]
]
}
大丈夫ですね。普通ですね。
というわけで、任意の HTTP クライアントからセルの読み書きができるようになりました。この記事は以上です。