Kasasagi’s memorandum

JavaとかProcessingとか。最近はAtcoderとか。

ExcelをJavaで操作する

こんにちは、かささぎです。ねむい。

なんとなく全国高専リンク地図のような地図を作ろうと思い立ったのですが、某パズル大会のような手動ではなく、プログラミングでやると割りといろんな技術が必要そうだったので、おもしろそうなので書きます。
たぶん3回に分けてWriteUPします。
今回は高専の情報をまとめるExcelデータを、Javaで操作するところを書きます。Javaで操作するのは、次回GoogleMapのAPIを利用しデータを取ってくるからです。
なお、Excelなんて使わずデータベースを使えというマジレスは受け付けません。あしからず。

とりあえず、元データとして以下のものを作成しました。
f:id:yh9092:20171226144456p:plain
MOS試験御用達のCONCATENATE関数を使っていること以外に言うことはないと思います。
この「検索名」のデータをAPIで検索していくことになります。

まずはこのデータを、Javaで読み込んでみました。
参考文献です→https://www.javadrive.jp/poi/
JavaExcelを利用するにはApache POIというライブラリを利用します。ぽいー。
こちらからダウンロードし、解凍します。
この中の
poi-
poi-ooxml
poi-ooxml-schemas
と、ooxml-lib内の
xmlbeans
の4つのjarファイルを取り込みます。
コードは以下の通りです。

<プログラムコード>


gist6a4e4c74388a36547b195a8e31e1f524

解説します。Excelはバージョンによりxls、xlsxという2つの拡張子のファイルがあり、それぞれ別の関数などが定義されています。
.xlsの場合はHSSFWorkbook, .xlsxの場合はXSSFWorkbookを使うのですが、それをどちらもカバーした(ラッパーの様な感じ)、Workbookというものが用意されています。
よほど特殊な場合でない限りは、こちらを利用すればいいそうです。
wbに格納されたデータを、シート→行→列の順で拡張for文で回しコマンドラインに表示しています。
この順番は変えることができないので注意です。
getCellValue関数は、得たデータの型に見合ったデータを返す関数です。
Object型はこういうことが簡単にできてすごいですね。まあ写経なんですが。

これを実行するとエラー。commons/collection/~がないと言われたので、こちらからApache Commons Collectionsをダウンロード。ファッションショーみたいな名前ですね。なんか脆弱性がうんたらみたいなのが出てきたけど気にせずダウンロードします。
解凍したら、commons-collecitons4.jarを取り込んで再実行。

<実行結果>

f:id:yh9092:20171226151340p:plain

どうやら空白セルは取り除かれるみたいですね。


読み込みが完了した後、書き込みのサンプルも作ることにしました。
割と簡単でした。GASでスプレッドシートに書き込んだ時とだいたい一緒です。
先ほどのコードのpsvm内に以下を書き加えます。

        try{
            Sheet sheet = wb.getSheet("sheet1");

            int r = 2;
            int c = 4;
            String data = "北海道函館市戸倉町14−1";
            Row row = sheet.getRow(r);
            Cell cell = row.getCell(c);
            cell.setCellValue(data);

            FileOutputStream os = new FileOutputStream(f);

            wb.write(os);
            wb.close();
        }
        catch(Exception e){
            e.printStackTrace();
        }

勝手に函館高専の住所載せていいのだろうか。まあいっか。
2行4列目(0からカウントのため実際はE3セル)に住所のデータを書きだします。
これを実行します。するとエラー。
f:id:yh9092:20171226152517p:plain
Excel開いてたらダメでした(そりゃそう)。読み込みだけなら大丈夫なんですね。

<実行結果>
f:id:yh9092:20171226152622p:plain

データベース技術皆無の自分にとっては、こういうことは割と役立ちそうです。
この住所・緯度・経度のデータは、GoogleMapのAPIから取ってこれるので、次回はそれを書く予定です。
緯度・経度から地図にマッピングはどうやってやろうか迷ってます。

それでは。