Rubyと筋肉とギターとわたし

エンジニア二年目の雑魚です。プログラミング・ギター・筋トレのことをメインにブログを書いていきます。

バイナリーで保存したexcelデータをRubyXLを使って編集する

新年明けましておめでとうございます。

ブログ開設して初の技術記事です\(^o^)/

技術記事を書くときは特に業務でやったことの復習と備忘録代わりに書いてます。
今回も同じで、最近久しぶりに触ったRubyXLというgemに関して書いていきたいと思います。

RubyXLとは

主にexcel書き込み専用のgemです。
xlsxとxlsmに対応してます(確か)

あとは主なところはgithubを見ていただければ使い方はわかるかと\(^o^)/
ここ

github.com

僕は読み込みではrooを、書き込みではRubyXL使っています。
rooにはちょっとした罠があるので、それはまた今度記事として書きたいなと。

動作環境

本題

ブログのタイトルにあるとおり、DBに登録しているバイナリーデータに対して書き込みを行います。
実はまだ出力が未検証なので、後日そこは別の記事としてあげたいと思う所存です。

フレームワークはもちろんRuby on Railsです。

ExcelFileというモデルにbinary型のexcel_binカラムが存在するものとして話を進めていきます。
ファイルサイズ(limit)は特段設けずにそのままで。

まずバイナリーファイルの保存

適当なexcelファイルを準備します。 ここでは test.xlsxとします。
保存してアクセスしたときに、データがちゃんと取得できているのかどうか確認するために、エクセルファイルのB2に テスト、シート名をテストシートとしておきます。

excel = File.binread('該当ファイルパス/test.xlsx')
ExcelFile.create(name: 'テストエクセル', excel_bin: excel)

test.xlsxを置く場所はRailsプロジェクトの中でも別のディレクトリでもどこでもいいです。
File#binreadでバイナリーファイルとして読み込むときにファイルパスを指定するので問題ありません。
(なんの説明もなくExcelFileモデルにnameカラムがありますが、飾りみたいなもんです。気にしないでください。)

macなら、この状態でパンケーキと呼ばれるSequel Proを使い、該当のバイナリーデータをxlsxで保存すると、 test.xlsxと同じ内容のエクセルファイルを取得できるはずです。
興味のある方はやってみてください。

RubyXLを使ってバイナリーファイルを解析

何をするにしても一次情報を見ろとよくいいますが、実感しました。

というのも、RailsをやっていないPLの下で働いている僕なのですが、PLから教えていただいた一次情報で助けられたからです。
まだまだカスだなと、ゴミクズだなと実感しましたね。。。

ここを見せていただきました。PLに感謝です。
http://www.rubydoc.info/gems/rubyXL/3.3.21/RubyXL/Parser

RubyXL::Parser.parseでファイルパスを指定してやる方法は知っていたのですが、バイナリーファイルを展開する方法は知りませんでした。 むしろ、バイナリーファイルはRubyXLでは展開できないものと思っていましたが、違いました。
RubyXL::Parser.parse_bufferでバイナリーファイルを展開できるようです。

excel_bin = ExcelFile.find_by(name: 'テストエクセル').excel_bin
book = RubyXL::Parser.parse_buffer(excel_bin)
worksheet = book[0]
worksheet.sheet_name #=> テストシート
worksheet[1][1] #=> テスト

RubyXLでは座標を[y][x]で指定していきますが、A1が[0][0]になります。 なので、B2は[1][1]
RubyXLで展開ができたので、あとは書き込んで出力するだけです。
簡単ですね。

最後に

一次情報を見る前には詰んでてどうしようもない状態が続いていたんですが、なんとか実装できました。
後日、Railsのコードと一緒にまた記事にしたいなと思います。

ではでは。