Apache POI の使い方

今日はPOIの使い方について簡単に説明していこうと思います

詳細は下記の公式サイトを参照ください
[Apache POI ](https://poi.apache.org/)

#ワークブックを作成する
まずは作業対象となるワークブックを作成します
一つ注意点があるのですが、既存のファイルを読み込む場合は先にFileInputStreamを生成しておく必要があります
書き込みの場合は書き込みたい時にFileOutputStreamを生成すれば大丈夫です


```java
//書き込みの場合
    Workbook workbook = new XSSFWorkbook();//xlsx、xlsmファイルの場合

    //いろいろな処理

    //出力先の生成
    String filePath = "エクセルファイル.xlsx"
    tyr(FileOutputStream output = new FileOutputStream(filePash)){
        //書き込み
        workbook.write(output);
    }

//読み込みの場合
    //入力元の生成
    String filePath = "エクセルファイル.xlsx"
    tyr(FileInputStream input = new FileInputStream(filePash)){
        //workbookの生成
        Workbook workbook = WorkbookFactory.create(input);
    
    //いろいろな処理
    }
```

もし古いxlsファイル等を操作したいときはXSSFWorkbookではなくHSSFWorkbookを使ってworkbookを生成してください

この後は基本的にworkbookを使ってインスタンスを生成したりすることになります

#シートを作成する
作業対象のシートを作成します
書き込むときはcreateSheetを使ってシートの生成を行い、読み込むときはgetSheetまたはgetSheetAtを使ってシートの生成を行います

```java
//書き込みの場合
    Sheet sheet = workbook.createSheet("シート名");

//読み込みの場合
    Sheet sheet = workbook.getSheetAt(0);//0番目のシートを取得
    //または
    Sheet sheet = workbook.getSheet("シート名")//シート名がわかっている場合はこちらで
```

実際に文字を書き込んだり読み込んだりする際には今回作成したsheetを使って専用のインスタンスを生成していくことになります

#行(Row)を作成する
POIではシートを作成しただけでは中身が無い、というようなイメージになります
そのため、行を生成する必要があります

```java

//書き込みの場合
    Row row = sheet.createRow(0);//0行目を生成(行は0行目から数える)

//読み込みの場合
    Row row = sheet.getRow(0);//0行目を読み取り
```

注意点としては、予めRowを生成しておかないといけない、ということです
使い方としてはどこかで最大行を決めておき、その行数分だけ生成する…というようになると思います

#セルを生成する
行(Row)ごとにセル(Cell)を生成します
行がないセルは生成することはできません

```java

//書き込みの場合
    Cell cell = row.createCell(0);

//読み込みの場合
    Cell cell = row.getCell(0);
```

文字や色やフォント等はこのセルに対して設定していくことになります

#文字を操作する
ここまでできていれば後は簡単です

```java
//書き込みの場合
    cell.setCellValue("あいうえお");

//読み込みの場合
    String cellValue = cell.getStringCellValue();
```
読み込みの場合にはgetxxxCellValueメソッドを使います
xxxにはデータ型を指定することができます

#フォントの設定をする
フォントはworkbookの持ち物なので、workbookから生成する必要があります
注意点ですが、Fontのスコープを間違えると全てのセルにフォントの設定がされてしまうことになります
色や太さ等を別々にしたい場合には別々のFontを生成するようにしてください

```java
Font font = workbook.createFont();

//太字にする
    font.setBold(true);

//文字の色を変える
    //まずは色を生成する
    XSSFColor color = new XSSFColor();
    color.setARGBHex("FF0000"/* 赤色 */);//カラーコードで指定する場合
    //または
    XSSFColor color = new XSSFColor(new java.awt.Color(255,0,0)/* 赤色 */);//RGBで指定する場合
       
    //フォントに色を設定する
    XSSFFont font = (XSSFFont) workbook.createFont();
    font.setColor(color);
```

POIではworkbookからインスタンスを貰う場合、ダウンキャストが必要になることがあります
XSSFFont型ではなくFont型(interface)で受け取ってしまうと使いたいメソッドの部分でコンパイルエラーになる可能性があります

#セルの背景色を設定する
セルスタイルに対して設定をしていき、セルにセルスタイルを適用させる、という方法でやっていきます
セルスタイルはworkbookの持ち物なので、workbookから取得する必要があります
フォントと同じく、セルごとに別々の背景色等にしたい場合には別々のセルスタイルを生成する必要があります

```java


//まずは色を生成する
XSSFColor color = new XSSFColor();
color.setARGBHex("FF0000"/* 赤色 */);

//セルスタイルを生成する
XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();

//セルスタイルに色を設定する
cellStyle.setFillForegroundColor(color);

//塗りつぶしの仕方を設定する
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//単に塗りつぶす

//セルにセルスタイルを適用する
cell.setCellStyle(cellStyle);
```
セルスタイルを生成するときにダウンキャストを行っています
本来のJavaの思想から言えばinterfaceの型(CellStyle)で受け取るのが良いのですが、XSSFCellStyleでないと使えないメソッドがあるためXSSFCellStyleで受け取っています

#罫線の設定
罫線(枠線)の設定はセルスタイルを使って行います
その後、セルにセルスタイルを適用する…というやり方です

```java
//セルスタイルを生成する
XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();

//罫線の設定
cellStyle.setBorderTop(BorderStyle.THIN/* 良く使う細い線 */);//上の罫線の設定
cellStyle.setBorderLeft(BorderStyle.THIN);//左の罫線の設定
cellStyle.setBorderRight(BorderStyle.THIN);//右の罫線の設定
cellStyle.setBorderBottom(BorderStyle.THIN);//下の罫線の設定

//セルにセルスタイルを適用する
cell.setCellStyle(cellStyle);

```

#セルの幅の自動調整
セルの幅の設定はシートに対して行います
日本語がある場合、フォントを明示的に設定してあげないとセルの幅が少し狭くなってしまいます

```java
//フォントを生成する
XSSFFont font = (XSSFFont) workbook.createFont();
font.setFontName("遊ゴシック");//フォント名はエクセルから直接コピペすれば使えます

//セルスタイルを生成し、フォントの設定を適用する
XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
cellStyle.setFont(font);

//全セルの幅を自動調整
sheet.autoSizeColumn();
```

#おまけ
・予め必要な分の行とセルを生成しておくことをおすすめします
セルスタイルも適用させた状態で生成しておくと後はセルの中の値をいじるだけでいいので！
生成されていない行にアクセスしようとすると例外が発生します

・セルに値をセットしようとするとき、nullの場合は何も入力されません

・DBのカラム名のようなものをエクセルファイルに入れたい、という場合には自分でその部分を作る必要があります