2021-12-11に更新

LibreOffice Calcのfodsファイルを読み書きするサンプルをweb API化してみた

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

↓これにちょろっと付け足して web API 化してみただけの記事です。

JRubyでLibreOffice Calcのfodsファイルを読み書きするサンプル 2021

できたもの

webapi-2021 ブランチ

https://github.com/sonota88/libreoffice-jruby-sample/tree/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 クライアントからセルの読み書きができるようになりました。この記事は以上です。

Originally published at qiita.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

sonota486

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント