概要
業務でJavaプログラムからExcelファイルを参照、出力(作成)する必要があり、その際に Apache POI を用いて対応したので、その基本的な操作をまとめた。
Apache POI とは?
Apacheプロジェクトの1つで、Word や Excel などの Microsoft Office 形式のファイルを読み書きできる 100% Java ライブラリ。
※ POI という名称は、Office のファイル形式をリバースエンジニアリングした際、その形式が意図的、中途半端に分かりにくくされていたため、皮肉を込め "Poor Obfuscation Implementation"(質の悪い難読な実装)と呼んだものの頭字語に由来している。
Apache POI の入手
Apache POI の公式サイトより、ライブラリを取得する。
(2020年3月時点の最新バージョンは 4.1.2 だが、今回は業務対応時点での最新だった、3.17 にて実装)
サンプルコード
既存のExcelファイルから値を取得し、内容を追記して別のExcelファイルに出力するサンプル。
コード
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
public class ApachePoiSample {
/** 入力Excelファイルパス */
public static final String IN_EXCEL_FILE_PATH = "excel/in/sample.xlsx";
/** 出力Excelファイルパス */
public static final String OUT_EXCEL_FILE_PATH = "excel/out/output.xlsx";
public static void main(String[] args) {
//---- Excelファイルを開く ----
Workbook wb = null;
try ( InputStream is = new FileInputStream(IN_EXCEL_FILE_PATH); ) {
wb = WorkbookFactory.create(is);
} catch (FileNotFoundException e) {
// 対象のExcelファイルが存在しない場合に発生
e.printStackTrace();
} catch (IOException e) {
// 対象のExcelファイルの読み込みに失敗した場合に発生
e.printStackTrace();
} catch (EncryptedDocumentException e) {
// 対象のExcelファイルにパスワードが設定されている場合に発生
e.printStackTrace();
} catch (InvalidFormatException e) {
// 対象のExcelファイルが無効な形式である場合に発生
e.printStackTrace();
}
// 対象のシートを選択する
Sheet sheet1 = wb.getSheet("Sheet1");
//---- A列の各セルから値を取得する ----
System.out.println("<入力>");
// 文字列を取得する
Row row = sheet1.getRow(0); // 1行目
Cell cell = row.getCell(0); // A列
String a1 = cell.getStringCellValue();
System.out.println("A1 : " + a1);
// 数値を取得する
row = sheet1.getRow(1); // 2行目
cell = row.getCell(0); // A列
double a2 = cell.getNumericCellValue();
System.out.println("A2 : " + a2);
// 数式を取得する
row = sheet1.getRow(2); // 3行目
cell = row.getCell(0); // A列
String a3 = cell.getCellFormula();
System.out.println("A3 : " + a3);
//---- 出力用にB列に値を追記する(B列は空のため、新規にセルを作成する)----
System.out.println("<出力>");
// 文字列を出力する
row = sheet1.getRow(0); // 1行目
cell = row.createCell(1); // B列の作成
cell.setCellValue(a1 + a1);
System.out.println("B1 : " + cell.getStringCellValue());
// 数値を出力する
row = sheet1.getRow(1); // 2行目
cell = row.createCell(1); // B列の作成
cell.setCellValue(a2 + a2);
System.out.println("B2 : " + cell.getNumericCellValue());
// 数式を出力する
row = sheet1.getRow(2); // 3行目
cell = row.createCell(1); // B列の作成
cell.setCellFormula("B2*2");
System.out.println("A3 : " + cell.getCellFormula());
//---- Excelファイルに出力する ----
try ( FileOutputStream os = new FileOutputStream(OUT_EXCEL_FILE_PATH); ) {
wb.write(os);
} catch (FileNotFoundException e) {
// 出力先に指定されたパスが存在しない場合に発生
e.printStackTrace();
} catch (IOException e) {
// Excelファイルの出力に失敗した場合に発生
e.printStackTrace();
}
}
}
実行結果
入力ファイル(sample.xlsx)
A1セルに文字列(Sample)、A2セルに数値(1.23)、A3セルに数式(A2*2)が入力されている。
コンソールログ
入力ファイルのA列の各値が取得されている。
また、出力ファイル用の値を以下の様に設定。
<入力>
A1 : sample
A2 : 1.23
A3 : A2*2
<出力>
B1 : samplesample
B2 : 2.46
A3 : B2*2