読者です 読者をやめる 読者になる 読者になる

ほんじゃら堂

めんどくさい仕事をラクにする作業自動化レシピ集

GroovyでExcelデータをコンバートして別Excelファイルとして出力する

Excelデータを分析しやすい形に加工できるよう、 Excelシートから1行ずつ読み込み→データを加工→別Excelファイルとして保存 という流れのスクリプトを書いた。

今後はこのスクリプトをベースにデータ加工ツールを サクサク作っていきたい。

convert_excel_test.groovy

@Grab(group='org.apache.poi', module='poi', version='3.11')
@Grab(group='org.apache.poi', module='poi-ooxml', version='3.11')

import org.apache.poi.hssf.usermodel.*
import org.apache.poi.ss.usermodel.WorkbookFactory

//データが含まれる元Excelファイルのパス
def IN_XLS_PATH = '元データ.xlsx'

//出力先パス
def OUT_XLS_PATH = '変換後データ.xlsx'

//データの並び順をMap化しておく
def cellMap = [
    sagyoDate: 0,
    tantoName: 1,
    comment: 2,
    yearMonth: 3,
    sagyoType: 4
]

//元データファイルを読み込み
new FileInputStream(IN_XLS_PATH).withStream { fis ->
    //ブックオブジェクトを作成
    def workbook = WorkbookFactory.create(fis)

    //対象シートをシートオブジェクトとして取得
    def genkaSheet = workbook.getSheetAt(1)

    def rowNo = 0
    def targetRow = null
    def sagyoDate = null

    //作業日が空になる(最終行に到達する)まで行をループ処理
    while (sagyoDate != '') {
        rowNo += 1
        //行オブジェクトを取得
        targetRow = genkaSheet.getRow(rowNo)
        //行が存在する場合は加工処理を実行。空なら次のループで終了
        if (targetRow == null) {
            sagyoDate = ''
            continue
        } else {

            //列マップを元に行の値をMap化し、列キーで値を呼びだせるようにする
            sagyoDate = targetRow.getCell(cellMap.sagyoDate).toString()
            def cellDatas = [:]
            cellMap.each { k, v ->
                cellDatas[k] = targetRow.getCell(v).toString().trim()
            }

            //yyyy/mm/dd文字列からyyyymm文字列を作成
            def sagyoYearMonth = cellDatas.sagyoDate.replaceAll(/\//, '').substring(0, 6)
            //データが存在しないセルのオブジェクトは新規作成が必要
            def yearMonthCell = targetRow.getCell(cellMap.yearMonth)
            if (yearMonthCell == null) {
                yearMonthCell = targetRow.createCell(cellMap.yearMonth)
            }
            //セルに値をセット
            yearMonthCell.setCellValue(sagyoYearMonth)

            //新規値用セルを空作成
            def typeCell = targetRow.getCell(cellMap.sagyoType)
            if (typeCell == null) {
                typeCell = targetRow.createCell(cellMap.sagyoType)
            }

            //正規表現で条件指定したり
            if (cellDatas.comment =~ /(朝礼)|(開発会議)|(チームMTG)/) {
                typeCell.setCellValue('固定MTG')
            }

            //inでリスト要素とマッチングしたり
            if (cellDatas.tantoName in ['田中', '山田']) {
                typeCell.setCellValue('リーダーMTG')
            }
        }
    }

    //加工したワークブックを別ファイルとして出力
    new File(OUT_XLS_PATH).withOutputStream { workbook.write(it) }
}

Windowsで実行する際はパス指定で文字化けしないように文字コードを指定して実行する。

groovy -c UTF-8 convert_excel_test.groovy

色々とgroovyでの書き方の勉強になった。