tag:crieit.net,2005:https://crieit.net/tags/JRuby/feed
「JRuby」の記事 - Crieit
Crieitでタグ「JRuby」に投稿された最近の記事
2021-12-11T12:05:57+09:00
https://crieit.net/tags/JRuby/feed
tag:crieit.net,2005:PublicArticle/17844
2021-12-11T12:03:55+09:00
2021-12-11T12:05:57+09:00
https://crieit.net/posts/libreoffice-calc-jruby-sinatra
LibreOffice Calcのfodsファイルを読み書きするサンプルをweb API化してみた
<p>これは <a target="_blank" rel="nofollow noopener" href="https://adventar.org/calendars/6425">LibreOffice Advent Calendar 2021</a> の11日目の記事です。</p>
<p>↓これにちょろっと付け足して web API 化してみただけの記事です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sonota88/items/b88c89d763cf872db5a1">JRubyでLibreOffice Calcのfodsファイルを読み書きするサンプル 2021</a></p>
<h1 id="できたもの"><a href="#%E3%81%A7%E3%81%8D%E3%81%9F%E3%82%82%E3%81%AE">できたもの</a></h1>
<p><code>webapi-2021</code> ブランチ</p>
<p><a target="_blank" rel="nofollow noopener" href="https://github.com/sonota88/libreoffice-jruby-sample/tree/webapi-2021">https://github.com/sonota88/libreoffice-jruby-sample/tree/webapi-2021</a></p>
<p>Java 版でやろうかと考えていたのですが、億劫になって JRuby 版でやりました。 JRuby で Sinatra 使った方が速い。</p>
<p>主な部分だけ抜き出すとこんな感じ。考えるのが面倒だったので REST ではなく RPC風で。普通に <a target="_blank" rel="nofollow noopener" href="http://sinatrarb.com/">Sinatra</a> を使ってるだけですね。あんまり書くことがない…… 😓</p>
<pre><code class="ruby"># 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
</code></pre>
<h1 id="動かし方"><a href="#%E5%8B%95%E3%81%8B%E3%81%97%E6%96%B9">動かし方</a></h1>
<p>イメージをビルド</p>
<pre><code>docker build \
--build-arg USER=$USER \
--build-arg GROUP=$(id -gn) \
-t my:libo-jruby-webapi-2021 .
</code></pre>
<p>APIサーバ起動</p>
<pre><code>./docker_run.sh ./jruby.sh app.rb -o 0.0.0.0
</code></pre>
<h1 id="curl で動作確認"><a href="#curl+%E3%81%A7%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">curl で動作確認</a></h1>
<p>ファイル、シート名、コマンド、パラメータを POST で渡します。</p>
<pre><code class="bash">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"
]
]
}
</code></pre>
<p>読み書きできてます。</p>
<h1 id="Ruby + Faraday"><a href="#Ruby+%2B+Faraday">Ruby + Faraday</a></h1>
<p>適当な HTTP クライアントライブラリを使って試してみました。</p>
<pre><code class="ruby">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
</code></pre>
<pre><code class="bash">$ 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"
]
]
}
</code></pre>
<p>大丈夫ですね。普通ですね。</p>
<hr />
<p>というわけで、任意の HTTP クライアントからセルの読み書きができるようになりました。この記事は以上です。</p>
sonota486
tag:crieit.net,2005:PublicArticle/16693
2021-02-20T11:51:56+09:00
2021-02-20T11:51:56+09:00
https://crieit.net/posts/JRuby-LibreOffice-Calc-fods-2019
JRubyでLibreOffice Calcのfodsファイルを読み書きするサンプル 2019
<p>(2021-01-02) 2021年版書きました: <a target="_blank" rel="nofollow noopener" href="https://memo88.hatenablog.com/entry/2021/01/02/171445">JRubyでLibreOffice Calcのfodsファイルを読み書きするサンプル 2021</a></p>
<hr />
<p><a target="_blank" rel="nofollow noopener" href="https://memo88.hatenablog.com/entry/20140726/1406375184">以前 JavaScript(Rhino/jrunscript)で書いた</a>ものを今さらながら Nashorn 向けに書きなおそうとして調べたところ、非推奨になっていました。</p>
<p>2018-06-07 <a target="_blank" rel="nofollow noopener" href="https://www.publickey1.jp/blog/18/javajavascriptnashornecmascriptgraalvm.html">JavaでJavaScriptを実行する「Nashorn」が非推奨に、ECMAScriptの速い進化に追いつけないと。代替案はGraalVM - Publickey</a></p>
<p>去年のニュースですね。全然気づいてませんでした。GraalVM を使えとあり、それも面白そうではありますが時期尚早な感じもします。ちょっと考えて JRuby で書き直してみることにしました。</p>
<p>(※ <a target="_blank" rel="nofollow noopener" href="https://memo88.hatenablog.com/entry/2019/12/02/230545">2019-12-02 に書いた記事</a>のクロスポストです)</p>
<hr />
<p>sonota88/libreoffice-jruby-sample (tag: 20191202)<br />
<a target="_blank" rel="nofollow noopener" href="https://github.com/sonota88/libreoffice-jruby-sample/tree/20191202">https://github.com/sonota88/libreoffice-jruby-sample/tree/20191202</a></p>
<p>Ubuntu で動かす前提のサンプルになっていて、 <code>libreoffice-java-common</code> をインストールしておく必要があります。ライブラリまわりについては<a target="_blank" rel="nofollow noopener" href="https://memo88.hatenablog.com/entry/2019/12/02/070925">一つ前の記事</a>なども参考にしてください。Windows などでもライブラリのパスの修正だけで動くんじゃないかと思います。</p>
<p>なんかデッドロックが発生してプログラムが終了しなかったのでサンプルスクリプトでは明示的に <code>exit</code> しています。jstack を使ってデッドロックしているなーというとこまで調べたあたりで気力が尽きました。また気が向いたら調べるかも……。</p>
<hr />
<p>今回はじめて JRuby を使ってみましたが、 zip をダウンロードして展開して <code>bin/</code> にパスを通すだけで使えて、いいですね。分かりやすい。</p>
<p>JRuby から Java のライブラリなどを使う場合、下記は必読でした。まずこれを読みましょう。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby">CallingJavaFromJRuby · jruby/jruby Wiki</a></p>
<hr />
<p>次のようにシートをダンプしてくれる <code>dump.rb</code> もおまけで追加しました。値が入っている最大の行・列の取り方が分からなかったため、いったん100行・100列まで見るようにしました。サンプルということで許してください……。</p>
<pre><code>$ jruby dump.rb foo.fods {シート名}
["a1", "b1"]
["a2", "b2"]
</code></pre>
<p>参考: <a target="_blank" rel="nofollow noopener" href="https://memo88.hatenablog.com/entry/2019/04/20/101713">もっとお手軽な機械可読テキストテーブルフォーマット - memo88</a></p>
sonota486