[Google Sheets API] セルの内容(値、メモ、リッチテキスト、表示形式(書式)、ピボットテーブル、入力規則)を設定する

Google Sheets API v4（Java）を使用して、
スプレットシートのセルに内容を設定する方法
についてご紹介します。

セルに内容を設定します。設定できる内容は下記になります。
・値
・メモ
・リッチテキスト
・表示形式（書式）
・ピボットテーブル
・入力規則

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する](https://qiita.com/doran/items/3d43f776188b2281044c)
を参照ください。
```
例：requests.add(moveDimension(sheetId)); //実行したいリクエストのMethodを指定
```
:::

:::note info
その他のGoogle Sheets APIは、下記の記事を参照ください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
:::

|No||目次|
|---|---|---|
|1||[指定したセルに設定](#1-指定したセルに設定)|
||1|[値 を設定する場合](#11-値-を設定する場合)|
||2|[メモ を設定する場合](#12-メモ-を設定する場合)|
||3|[リッチテキスト を設定する場合](#13-リッチテキスト-を設定する場合)|
||4|[表示形式 を設定する場合](#14-表示形式-を設定する場合)|
||5|[ピボットテーブル を設定する場合](#15-ピボットテーブル-を設定する場合)|
||6|[データの入力規則 を設定する場合](#16-データの入力規則-を設定する場合)|
|2||[指定した範囲のセルに設定](#２-指定した範囲のセルに設定)|
|3||[最後の行にセルを追加](#３-最後の行にセルを追加)|

## 1. 指定したセルに設定
指定したセルに値を設定します。

設定したい内容はCellDataインスタンスで設定します。
更新したいセル分のCellDataインスタンスを設定して複数範囲も更新できます。

<font color=red>指定するセルがない場合はエラーになります。</font>
そのため、行や列が足りない場合は事前に行・列を追加する必要があります。

**設定する種類**
設定したい種類はsetFieldsで指定します。
この指定がない場合は、設定されません。
複数指定したい場合は、「,」で繋げます。
|種類|設定する内容|
|---|---|
|userEnteredValue|値|
|note|メモ|
|textFormatRuns|リッチテキスト|
|userEnteredFormat|表示形式|
|pivotTable|ピボットテーブル|
|dataValidation|データの入力規則|

例えば、値とメモを設定したい場合は下記のように指定します。
「*」も使えますがコードの可読性も考えると、種類を指定した方がよいかと思います。
```
r.setFields("userEnteredValue,note"); //設定する種類
```
**サンプル コード**
ここではCellDataに値を入れていません。
この後の例から実際に値を入れて解説しますので、更新したい内容に沿って
CellDataに値をセットしてください。CellDataには複数の情報をセットできます。
```
public Request updateCells(Integer sheetId) {
    Request request = new Request();

    //設定するセルの開始位置
    GridCoordinate grid = new GridCoordinate();
    grid.setSheetId(sheetId);   //設定するシートID
    grid.setRowIndex(0);        //開始行(0スタート)
    grid.setColumnIndex(0);     //開始列(0スタート)

    //設定するセルの内容
    List<RowData> row = new ArrayList<>();
    RowData d1 = new RowData();
    List<CellData> line1 = new ArrayList<>(); //1行目
    CellData row1_1 = new CellData();    //A列
    line1.add(row1_1);
    CellData row1_2 = new CellData();    //B列
    line1.add(row1_2);
    
    List<CellData> line2 = new ArrayList<>(); //2行目
    CellData row2_1 = new CellData();    //A列
    line2.add(row2_1);
    CellData row2_2 = new CellData();    //B列
    line2.add(row2_2);
    
    row.add(line1);
    row.add(line2);
    
    UpdateCellsRequest r = new UpdateCellsRequest();
    r.setFields("userEnteredValue,note"); //設定する種類
    r.setStart(grid);                     //設定するセルの開始位置
    r.setRows(row);                       //設定するセルの内容
    
    request.setUpdateCells(r);
    return request;
}
```

#### 1.1. 値 を設定する場合
セルに値を設定できます。

設定するデータ型に合わせて使用するExtendedValueのメソッドを変更します。
使えるメソッドは1オブジェクトにつき1つのみです。
1オブジェクトに複数のメソッドで設定するとエラーになります。

|データ型|メソッド|補足|
|---|---|---|
|文字列|setStringValue||
|数値|setNumberValue|日付型の場合、数値(シリアル値)で指定してください。<br>シリアル値については<br>[[Java] java.util.Date型からシリアル値を取得する](https://qiita.com/doran/items/ad2c2e9c4364d7b2110f)<br>を参照ください。|
|真偽値|setBoolValue||
|関数|setFormulaValue|「=」開始の文字列で指定してください。|
```
CellData cell = new CellData();

ExtendedValue ex = new ExtendedValue();
ex.setStringValue("0123456789");     //文字列
//ex.setNumberValue(100d);	         //数値
//ex.setBoolValue(true);		     //真偽値
//ex.setFormulaValue("=SUM(A:B)");	 //関数

cell.setUserEnteredValue(ex);
```

#### 1.2. メモ を設定する場合
セルにメモを設定できます。
```
CellData cell = new CellData();

cell.setNote("これはノートです");
```

#### 1.3. リッチテキスト を設定する場合
セルにリッチテキストを設定できます。

文字のサイズやフォント、色などのレイアウト情報が設定できます。
値自体は上記の「「値」を設定する場合」　の方法で設定します。

リッチテキストはセル内の***文字単位***にレイアウトを設定することができます。
文字の開始位置を指定すると、文字の最後までレイアウトが適用されます。
レイアウトの指定はTextFormatクラスを使用します。

TextFormatクラスについては、下記記事の「表示形式 - テキスト」を参照ください。
[⧉[Google Sheets API] セルに書式を設定する](https://qiita.com/doran/items/19376cdb6177e40843b0)

```
CellData cell = new CellData();

List<TextFormatRun> formats = new ArrayList<>();
TextFormatRun t1 = new TextFormatRun();
t1.setFormat(/**TextFormat*/); //TextFormatを設定する(上記、記事を参照ください）
t1.setStartIndex(3);           //適用するセル内の文字列インデックス(最後まで)
formats.add(t1);

TextFormatRun t2 = new TextFormatRun();
t2.setFormat(/**TextFormat*/); //TextFormatを設定する(上記、記事を参照ください）
t2.setStartIndex(5);           //適用するセル内の文字列インデックス(最後まで)
formats.add(t2);
  
cell.setTextFormatRuns(formats);
```
文字列の途中だけレイアウトを指定したい場合は下記の順番で指定します。

<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/d07a85ce-d8ce-3b4b-a1d1-4295e2b7eff9.png">

・4文字目以降(setStartIndex(3))に、太字、フォントサイズ14、赤
・6文字目以降(setStartIndex(5))に、斜体、フォントサイズ18、緑
・8文字目以降(setStartIndex(7))には無し。
```
List<TextFormatRun> formats = new ArrayList<>();

//4文字目以降
TextFormatRun run1 = new TextFormatRun();
TextFormat format1 = new TextFormat();
format1.setBold(true);	              //太字
format1.setFontSize(14);              //フォントサイズ14
Color color1 = new Color();
color1.setRed(1f);color1.setGreen(0f);color1.setBlue(0f); //赤色
format1.setForegroundColor(color1);   //テキストの色
run1.setFormat(format1);
run1.setStartIndex(3);                //4文字目以降
formats.add(run1);

//6文字目以降
TextFormatRun run2 = new TextFormatRun();
TextFormat format2 = new TextFormat();
format2.setItalic(true);	          //斜体
format2.setFontSize(18);              //フォントサイズ18
Color color2 = new Color();
color2.setRed(0f);color2.setGreen(1f);color2.setBlue(0f); //緑色
format2.setForegroundColor(color2);   //テキストの色
run2.setFormat(format2);
run2.setStartIndex(5);                //6文字目以降
formats.add(run2);

//8文字目以降　[開始位置以外、何も設定しない]
TextFormatRun run3 = new TextFormatRun();
run3.setStartIndex(7);                //8文字目以降
formats.add(run3);
```

#### 1.4. 表示形式 を設定する場合
セルに表示形式を設定できます。

セルの表示形式の他、テキストの色、枠線、配置方法(水平,垂直)などが指定できます。

設定可能な項目は下記記事に全てまとめましたのでこちらを参照ください。
[⧉[Google Sheets API] セルに書式を設定する](https://qiita.com/doran/items/19376cdb6177e40843b0)

```
CellData cell = new CellData();

CellFormat format = getCellFormat();
//formatに対して必要な項目を設定(上記の記事を参照ください。)

cell.setUserEnteredFormat(format);
```
#### 1.5. ピボットテーブル を設定する場合
セルにピボットテーブルを設定できます。

設定可能な項目は下記記事に全てまとめましたのでこちらを参照ください。
[⧉[Google Sheets API] セルにピボットテーブルを設定する](https://qiita.com/doran/items/51d5e9a15656716aec88)

```
CellData cell = new CellData();

PivotTable pivot = getPivotTable();
//pivotに対して必要な項目を設定(上記の記事を参照ください。)

cell.setPivotTable(format);
```
#### 1.6. データの入力規則 を設定する場合
指定範囲のセルにデータの入力規則を設定できます。

設定可能な項目は下記記事に全てまとめましたのでこちらを参照ください。
[⧉[Google Sheets API] セルに入力規則を設定する](https://qiita.com/doran/items/02c75929be3da4f7bd9f)

UpdateCellsRequestでは、データの入力規則は範囲の指定がありません。
そのため、UpdateCellsRequestで複数のセルに跨り入力規則を設定したい場合は、
CellDataに同じオブジェクトを設定してください。
後述するRepeatCellRequestを使用するのが正しい設定の仕方だと思います。

下記例は、2行2列に設定する場合です。
RowDataにDataValidationRuleを計4回設定しています。
```
DataValidationRule rule = getDataValidationRule();　
//ruleに対して必要な項目を設定(上記の記事を参照ください。)

List<RowData> row = new ArrayList<>();
RowData d1 = new RowData();
List<CellData> line1 = new ArrayList<>(); //1行目
CellData row1_1 = new CellData();    //A列
row1_1.setDataValidation(rule);
line1.add(row1_1);
CellData row1_2 = new CellData();    //B列
row1_2.setDataValidation(rule);
line1.add(row1_2);

List<CellData> line2 = new ArrayList<>(); //2行目
CellData row2_1 = new CellData();    //A列
row2_1.setDataValidation(rule);
line2.add(row2_1);
CellData row2_2 = new CellData();    //B列
row2_2.setDataValidation(rule);
line2.add(row2_2);

row.add(line1);
row.add(line2);
    
UpdateCellsRequest r = new UpdateCellsRequest();
r.setRows(row);                       //設定するセルの内容
```
## ２. 指定した範囲のセルに設定
指定した範囲の複数のセルに同じ値を設定します。

[指定したセルに設定](#1-指定したセルに設定)との違いは、1つのCellDataインスタンスを用いて
複数範囲のセルを更新します。
そのため、範囲内のセル毎に異なる値は設定できません。

設定できるセルの内容自体は[指定したセルに設定](#1-指定したセルに設定)と同じなので
内容はそちらを参照ください。

**サンプル コード**
設定する範囲とセルの内容を指定します。
```
public Request repeatCell(Integer sheetId) {
    Request request = new Request();

    //設定する範囲
    GridRange range = new GridRange();    //範囲
    range.setSheetId(sheetId);            //シートID
    range.setStartRowIndex(0);            //開始行(0スタート)
    range.setEndRowIndex(6);              //終了行(1スタート)　省略可能
    range.setStartColumnIndex(1);         //開始列(0スタート)
    range.setEndColumnIndex(4);           //終了列(1スタート)　省略可能

    //設定するセルの内容
    //設定できるセルの内容は、「指定したセルに設定」と同じです。
    //内容の詳細はそちらの記事を参照ください。
    CellData cell = new CellData();
  
    RepeatCellRequest r = new RepeatCellRequest();
    r.setFields("userEnteredValue,note"); //設定する種類
    r.setRange(range);                    //設定する範囲
    r.setCell(cell);                      //設定するセルの内容
    
    request.setRepeatCell(r);
    return request;
}
```

## ３. 最後の行にセルを追加
シート内のデータが含まれる最後の行の後にセルを追加します。

[指定したセルに設定](#1-指定したセルに設定)との違いは、
セルの範囲を指定する代わりに追加するシートのIDを指定します。

設定できるセルの内容自体は[指定したセルに設定](#1-指定したセルに設定)と同じなので
内容はそちらを参照ください。

**サンプル コード**
```
public Request appendCells(Integer sheetId) {
    Request request = new Request();
    
    List<RowData> row = new ArrayList<>();
    RowData d1 = new RowData();
    List<CellData> line1 = new ArrayList<>(); //1行目
    
    CellData row1_1 = new CellData();         //A列
    ExtendedValue ex1 = new ExtendedValue();
    ex1.setStringValue("データを追加");
    row1_1.setUserEnteredValue(ex1);
    line1.add(row1_1);
    
    CellData row1_2 = new CellData();         //B列
    ExtendedValue ex2 = new ExtendedValue();
    ex2.setNumberValue(1000d);
    row1_2.setUserEnteredValue(ex2);
    line1.add(row1_2);
    
    d1.setValues(line1);
    row.add(d1);
    
    AppendCellsRequest r = new AppendCellsRequest();
    r.setSheetId(sheetId);					 //設定するシートID
    r.setFields("userEnteredValue");		 //設定する種類
    r.setRows(row);							 //設定するセルの内容

    request.setAppendCells(r);
    return request;
}
```
**実行結果**
このシートの状態で実行してみます。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/0a83061c-0055-06d6-8cfb-8896f6c2dd45.png">

一番最後のデータがある行(6行目)の次の行(7行目)に追加されました。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2377d9b1-1ff4-f081-3150-56a9322eceed.png">


おしまい。。