コワーキングスペースの申請のため Groovy x POI で Word ファイルを操作する
ふくもく会では、福井産業情報センターのコワーキングスペースにお世話になることが多いのだけど、ここを使うには利用申請書を提出する必要がある。この利用申請書が .doc ファイルで、これをなんとかしてサクッと記入できないか考えてみた。
最初は勉強のために Rust で書こうとしたけど、Rust には docx を編集するライブラリ、その名も docx しかなさそうだった。じゃぁ Python でいいかと調べてみても、こちらも docx を編集するライブラリしかなさそう。例えば python-docx。
諦めて手書きするかなーと @macoshita にぼやいてたら「この分野は POI が最強っすね」と言われて Apache POI のことを思い出した。Java かー。もうちょっと軽い気持ちで書きたいんだよなー。ということで Groovy から使ってみることにした。
Groovy 書くのが5億年ぶりなので、イチから調べてみたところ、Grape という仕組みがあって、依存をすっと書けるらしい。サンプルとして次のコードが書かれていた。
@Grab('org.springframework:spring-orm:3.2.5.RELEASE') import org.springframework.jdbc.core.JdbcTemplate
build.gradle
とかが無くても、こんな感じで groovy ファイルに @Grab
で書いとくだけで、勝手に依存する jar を取ってきてくれるんだって。夢か?Denoか?
そんなわけで、これを活用して POI でコワーキングスペースの利用申請書の doc ファイルを開いて、適当にテキスト置換して、書き出すコードを書いてみた。
// TextRangeReplatement test as an HWPFDocument example // http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestRangeReplacement.java?revision=1872041&view=markup @Grab('org.apache.poi:poi:4.1.2') @Grab('org.apache.poi:poi-scratchpad:4.1.2') import org.apache.poi.hwpf.HWPFDocument import org.apache.poi.hwpf.usermodel.Range import org.apache.poi.hwpf.usermodel.Section FILENAME = 'coworking_format1.doc' try (HWPFDocument daDoc = openSampleFile(FILENAME)) { Range range = daDoc.getRange() def 申請日 = '令和2年 11月 5日' def 住所 = '福井県福井市' def 利用日 = '令和2年 11月 23日(月)' def 氏名 = '福井太郎' // dump(range) range.replaceText('平成 年 月 日( )', 利用日) range.replaceText('年 月 日', 申請日) range.replaceText('住所 ', '住所 ' + 住所) range.replaceText('氏名 ', '氏名 ' + 氏名) dump(range) daDoc.write(new File('coworking.doc')) } void dump(Range range) { println("numParagraphs: " + range.numParagraphs()) for (int j = 0; j < range.numParagraphs(); j++) { println(j + '[' + range.getParagraph(j).text() + ']') } } HWPFDocument openSampleFile(String filename) { try { InputStream is = new FileInputStream(filename) try { return new HWPFDocument(is) } catch (Throwable e) { is.close() throw e } } catch (IOException e) { throw new RuntimeException(e) } }
これを groovy main.groovy
とかで実行するだけ。
おー、できたできた。便利すぎるな。この方向で進めてみようと思う。
細かいメモ:
- POI の数ある機能のなかで Word ファイル (.doc) を操作する機能は HWPF という部分。
- Word ファイルを読むと
HWPFDocument
という形になる。 - コメントに書いた通り TextRangeReplacement というテストコードが
HWPFDocument
でテキスト置換するときのいい例になっている。実際、このコードからすべてを学んだと言ってもいいぐらい。 - 「住所」を「住所 福井県」に
Range#replaceText
すると処理が終わらない。たぶん無限ループにハマってる。仕方なく「住所 」を「住所 福井県」に置換して無限ループを回避した。他にもSection
を特定してRange#insertAfter
を駆使するなど、細かい工夫が要りそう。