LoginSignup
7
6

More than 5 years have passed since last update.

ScalaでExcelを操作する コピーした行を挿入する編

Last updated at Posted at 2015-10-28

ExcelのUI操作だと行を右クリックでコピーして挿入とかする訳ですが、それと同じことをScalaでやる方法です。

「コピーした行を挿入」みたいな便利メソッドはないので(もしくは、見つけられなかった)、以下の手順を踏みます。

  • コピー元の行を取得
  • ワークシートに新しい行を追加
  • 行を追加する位置以降の行を追加行分ずらす
  • 追加した行の各セルに、コピー元セルの
    • スタイルをコピー
    • セル値をコピー
    • マージ状態をコピー

準備

  • POIの導入と基本的な読み書きについてはこちらを参照

コピー元の行を取得

import java.io.{File, FileOutputStream}

import org.apache.poi.ss.usermodel._
import org.apache.poi.ss.util.CellRangeAddress

val workbook = WorkbookFactory.create(new File("/path/to/excel"))

val sheet = workbook.getSheetAt(0)

val originalRow = sheet.getRow(0)

新しい行を追加

シート末尾に1行追加します。

val lastRowNum = sheet.getLastRowNum

sheet.createRow(lastRowNum + 1)

行を追加する位置以降の行を下にずらす

行を追加したい位置をstartRowNumberとすると、そこから下の全行を1行下にずらします。

val startRowNumber = 5

sheet.shiftRows(startRowNumber, lastRowNum + 1, 1)

追加した行のスタイル・セル値を設定

今回はスタイルとタイプ、値のみコピーしていますが、他にもセルのコメントなども必要ならば同じようにコピー&設定します。

  val newRow = sheet.getRow(startRowNumber)

  for{
    index <- 0 until originalRow.getLastCellNum
  } {
    val originalCell = originalRow.getCell(index)
    val newCell = newRow.createCell(index)

    // セルのスタイルのコピー
    val newCellStyle = workbook.createCellStyle
    newCellStyle.cloneStyleFrom(originalCell.getCellStyle)
    newCell.setCellStyle(newCellStyle)
    // セルタイプのコピー
    newCell.setCellType(originalCell.getCellType)
    // セル値のコピー
    originalCell.getCellType match {
      case Cell.CELL_TYPE_BLANK =>
        newCell.setCellValue(originalCell.getStringCellValue)
      case Cell.CELL_TYPE_BOOLEAN =>
        newCell.setCellValue(originalCell.getBooleanCellValue)
      case Cell.CELL_TYPE_ERROR =>
        newCell.setCellErrorValue(originalCell.getErrorCellValue)
      case Cell.CELL_TYPE_FORMULA =>
        newCell.setCellFormula(originalCell.getCellFormula)
      case Cell.CELL_TYPE_NUMERIC =>
        newCell.setCellValue(originalCell.getNumericCellValue)
      case Cell.CELL_TYPE_STRING =>
        newCell.setCellValue(originalCell.getStringCellValue)
    }

  }

追加した行にマージ状態を設定

val newRow = sheet.getRow(startRowNumber)
for{
    index <- 0 until originalRow.getLastCellNum
} {
// 略
  for {
    index <- 0 until sheet.getNumMergedRegions
    cellRangeAddress <- Option(sheet.getMergedRegion(index)) if cellRangeAddress.getFirstRow == originalRow.getRowNum
  } {
    sheet.addMergedRegion(new CellRangeAddress(
      newRow.getRowNum,
      newRow.getRowNum + (cellRangeAddress.getLastRow - cellRangeAddress.getFirstRow),
      cellRangeAddress.getFirstColumn,
      cellRangeAddress.getLastColumn
    ))
  }

  // ファイルに書き出す
  val out = new FileOutputStream("/path/to/output")
  workbook.write(out)
  out.close
}

以上で、行を追加したい位置にコピー元と同じ行が追加されていると思います。
これをちょっとアレンジすれば複数行のコピーもいけます。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6