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