Excel書込ユーティリティが業務で重要になる理由
Excel(.xlsx)は、業務システムの「データ出力フォーマット」として圧倒的に使われています。 レポート、集計結果、外部ベンダーへのデータ提供、管理画面からのダウンロードなど、 “Excelを書き出す処理”はほぼすべての企業システムで必要になります。
しかし、初心者がやりがちな「セルに文字列を入れるだけ」「数値や日付を文字列化して書く」といった実装は、 後から必ず破綻します。Excel は セル型(文字列・数値・日付・式) を持ち、 型を正しく扱わないと、Excel 側で計算できない、フィルタできない、並び替えできないなどの問題が起きます。
そこで役に立つのが Excel書込ユーティリティ です。 Apache POI を使い、セル型を意識しながら安全に Excel を生成できるようにします。
Excel書込の基本発想
「Workbook → Sheet → Row → Cell」の階層構造を“作る側”として理解する
Excel 読込のときと同じく、書込も階層構造を順番に作っていきます。
- Workbook(Excelファイル)を作る
- Sheet(シート)を作る
- Row(行)を作る
- Cell(セル)を作る
この順番で構築することで、Excel の構造を正しく生成できます。
Excel書込の最小構成(初心者向け)
まずは「文字列だけ書く」シンプルな例
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.nio.file.Files;
import java.nio.file.Path;
import java.io.OutputStream;
import java.util.List;
public class SimpleExcelWriter {
public static void write(Path path, List<String[]> rows) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
for (int r = 0; r < rows.size(); r++) {
Row row = sheet.createRow(r);
String[] cols = rows.get(r);
for (int c = 0; c < cols.length; c++) {
Cell cell = row.createCell(c);
cell.setCellValue(cols[c]);
}
}
try (OutputStream out = Files.newOutputStream(path)) {
workbook.write(out);
}
workbook.close();
}
}
Java使い方の例です。
List<String[]> rows = List.of(
new String[]{"ID", "Name", "Email"},
new String[]{"1", "MONO", "mono@example.com"},
new String[]{"2", "TARO", "taro@example.com"}
);
SimpleExcelWriter.write(Path.of("out/simple.xlsx"), rows);
Javaここで重要なのは 「Workbook を閉じる」 ことです。 閉じ忘れるとメモリリークやファイル破損の原因になります。
Excel書込で必ず意識すべき「セル型」
数値・日付・式は文字列として書いてはいけない
Excel はセル型によって動作が変わります。
- 数値セル → 数値として計算できる
- 日付セル → Excel の日付フォーマットで表示される
- 式セル → Excel が計算してくれる
これらを文字列として書いてしまうと、Excel 側で正しく扱えません。
数値セルを書き込む例
setCellValue(double) を使う
Cell cell = row.createCell(1);
cell.setCellValue(123.45); // 数値セルとして書き込む
JavaExcel 側で計算・並び替え・フィルタが正しく動きます。
日付セルを書き込む例
CellStyle を使ってフォーマットを設定する
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
Cell cell = row.createCell(2);
LocalDate date = LocalDate.of(2026, 8, 7);
Date legacyDate = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
cell.setCellValue(legacyDate);
CellStyle style = workbook.createCellStyle();
CreationHelper helper = workbook.getCreationHelper();
style.setDataFormat(helper.createDataFormat().getFormat("yyyy-mm-dd"));
cell.setCellStyle(style);
Javaここで深掘りしたいポイントは 「Excel の日付は内部的には数値」 ということです。 Java の LocalDate をそのまま書けないため、java.util.Date に変換して書き込みます。
式セルを書き込む例
setCellFormula を使う
Cell cell = row.createCell(3);
cell.setCellFormula("A2 + B2");
JavaExcel 側で自動計算されます。
実務向け Excel書込ユーティリティ(テンプレート)
型を意識した汎用的な書込処理
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
public class ExcelWriter {
public static void write(Path path, List<List<Object>> rows) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
CreationHelper helper = workbook.getCreationHelper();
CellStyle dateStyle = workbook.createCellStyle();
dateStyle.setDataFormat(helper.createDataFormat().getFormat("yyyy-mm-dd"));
for (int r = 0; r < rows.size(); r++) {
Row row = sheet.createRow(r);
List<Object> cols = rows.get(r);
for (int c = 0; c < cols.size(); c++) {
Cell cell = row.createCell(c);
Object value = cols.get(c);
if (value instanceof Number) {
cell.setCellValue(((Number) value).doubleValue());
} else if (value instanceof LocalDate) {
Date d = Date.from(((LocalDate) value)
.atStartOfDay(ZoneId.systemDefault()).toInstant());
cell.setCellValue(d);
cell.setCellStyle(dateStyle);
} else if (value instanceof Boolean) {
cell.setCellValue((Boolean) value);
} else if (value instanceof String) {
cell.setCellValue((String) value);
} else {
cell.setCellValue("");
}
}
}
try (OutputStream out = Files.newOutputStream(path)) {
workbook.write(out);
}
workbook.close();
}
}
Java使い方の例です。
List<List<Object>> rows = List.of(
List.of("ID", "Name", "Score", "Date"),
List.of(1, "MONO", 95.5, LocalDate.of(2026, 8, 7)),
List.of(2, "TARO", 88.0, LocalDate.of(2026, 8, 8))
);
ExcelWriter.write(Path.of("out/business.xlsx"), rows);
JavaExcel書込で絶対に意識すべき重要ポイント
1. セル型を正しく使う
文字列で書いてしまうと Excel 側で計算できません。 数値・日付・式は必ず専用の setter を使います。
2. 日付は LocalDate のまま書けない
Excel は日付を「数値」として扱うため、java.util.Date に変換する必要があります。
3. CellStyle を使ってフォーマットを設定する
日付や数値のフォーマットは Excel 側で設定する必要があります。 Java 側で文字列化すると Excel の機能が使えなくなります。
4. Workbook を必ず close する
閉じ忘れるとメモリリークやファイル破損の原因になります。
Excel書込ユーティリティの実務的な使いどころ
レポート出力
売上レポート、顧客レポートなどを Excel で出力できます。
外部ベンダーへのデータ提供
Excel 形式でデータを渡す場合、セル型を正しく扱うことで品質が安定します。
管理画面からのダウンロード
「Excelダウンロード」機能の品質が統一され、保守性が高まります。
バッチ処理での集計結果出力
夜間バッチで Excel を生成する場合にも、ユーティリティ化が有効です。
まとめ:Excel書込ユーティリティで身につけてほしい感覚
Excel書込ユーティリティは、業務データを正しく外部へ届けるための“出口”です。 そこには次のような大事なポイントがあります。
- Excel の階層構造(Workbook → Sheet → Row → Cell)を意識する
- セル型(文字列・数値・日付・式)を正しく使う
- 日付は
LocalDate→java.util.Dateに変換して書く - CellStyle を使ってフォーマットを設定する
- Workbook を必ず close する
