Apache POIで、行のコピーを行う方法を紹介します。
いきなり残念なお知らせですが、Apache POIには行コピーを行うメソッドは用意されていません。
面倒ですが、行の内容を取得して、その中のセルの値およびスタイルをコピーするという方法しかないようです。
スポンサーリンク
サンプルコード
さっそく、行のコピーを行うサンプルコードを、紹介したいと思います。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
/**
* POIで行をコピーする処理
* @param workbook ワークブック
* @param worksheet ワークシート
* @param sourceRowNum コピー元の行インデックス
* @param destinationRowNum コピー先の行インデックス
*/
private static void copyRow(Workbook workbook, Sheet worksheet, int sourceRowNum, int destinationRowNum) {
Row newRow = worksheet.getRow(destinationRowNum);
Row sourceRow = worksheet.getRow(sourceRowNum);
if (newRow != null) {
//コピー先に行が既に存在する場合、1行下にずらす
worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
newRow = worksheet.createRow(destinationRowNum);
} else {
//存在しない場合は作成
newRow = worksheet.createRow(destinationRowNum);
}
// セルの型、スタイル、値などをすべてコピーする
for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
Cell oldCell = sourceRow.getCell(i);
Cell newCell = newRow.createCell(i);
// コピー元の行が存在しない場合、処理を中断
if (oldCell == null) {
newCell = null;
continue;
}
//スタイルのコピー
CellStyle newCellStyle = workbook.createCellStyle();
newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
newCell.setCellStyle(newCellStyle);
//コメントのコピー
if (oldCell.getCellComment() != null) {
newCell.setCellComment(oldCell.getCellComment());
}
//ハイパーリンクのコピー
if (oldCell.getHyperlink() != null) {
newCell.setHyperlink(oldCell.getHyperlink());
}
//セル型のコピー
newCell.setCellType(oldCell.getCellType());
//セルの値をコピー
switch (oldCell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(oldCell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_ERROR:
newCell.setCellErrorValue(oldCell.getErrorCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(oldCell.getCellFormula());
break;
case Cell.CELL_TYPE_NUMERIC:
newCell.setCellValue(oldCell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(oldCell.getRichStringCellValue());
break;
}
}
//セル結合のコピー
for (int i = 0; i < worksheet.getNumMergedRegions(); i++) {
CellRangeAddress cellRangeAddress = worksheet.getMergedRegion(i);
if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) {
CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(),
(newRow.getRowNum() + (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())),
cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn());
worksheet.addMergedRegion(newCellRangeAddress);
}
}
}
スポンサーリンク
コピーする内容
上のサンプルコードを見てもらえれば、分かると思いますが、今回紹介した行のコピーを行うサンプルコードでは、元の行から以下の内容をコピーする処理になっています。
コピーする内容 |
---|
文字色・背景色などのセルスタイル |
コメント |
ハイパーリンク |
セル型 |
セルの値 |
セル結合 |
スポンサーリンク
コピー先の行に、既に値がある場合
次の表のように、コピー先に既に行が存在する場合、今回紹介したサンプルコードでは、既に存在するコ行を1行ずらしてから、行のコピーを行っています。
[コピー前]
No | 名称 | |
---|---|---|
1 | りんご | ← コピー元 |
2 | みかん | |
3 | もも | ← コピー先 |
[コピー後]
No | 名称 | |
---|---|---|
1 | りんご | |
2 | みかん | |
1 | りんご | ★ |
3 | もも |
ちなみに、この1行ずらす処理はサンプルコード17行目付近の、以下の部分で行っています。
worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
まとめ
いかがでしょうか。
今回紹介したサンプルコードを、共通関数として保存しておけば、今後は共通関数を一発呼ぶだけになり、行のコピーが楽になるかと思います。
参考URL
みんな大好き stack overflow
https://stackoverflow.com/questions/5785724/how-to-insert-a-row-between-two-rows-in-an-existing-excel-with-hssf-apache-poi
※上記URLに掲載されているプログラムだと、うまく動かなかったので、本記事で紹介しているサンプルコードは一部修正しています。
0 件のコメント:
コメントを投稿