[Google Sheets API] 条件付き書式を追加・更新・削除する

Google Sheets API v4（Java）を使用して、
スプレットシートのセルに条件付き書式を追加・更新・削除する方法
についてご紹介します。

**条件付き書式とは**
シートメニュー：「表示形式」 ⇨　「条件付き書式」
で設定することができます。

条件付き書式には２種類存在します。
・単一色
　　セルの値が条件を満たした場合、セルに指定した書式を設定します。

　　条件を満たしたセルに設定できる書式は下記になります。
  　　・太字
  　　・斜体
  　　・下線
  　　・取り消し線
  　　・文字色
  　　・背景色


・カラースケール
　　複数セル（行または列）内の値の大小により、
　　背景色を薄くしたり濃くしたりします。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f5313dc7-e2d8-05ee-2ea7-d4f3d53fc8be.png">

:::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-単一色)|
|||1|[書式を適用する条件の設定](#111-書式を適用する条件の設定)|
|||2|[適用する書式の設定](#112-適用する書式の設定)|
||2||[カラースケール](#12-カラースケール)|
|2|||[条件付き書式の更新](#2-条件付き書式の更新)|
|3|||[条件付き書式の削除](#3-条件付き書式の削除)|

## 1. 条件付き書式の追加
条件付き書式を追加します。

単一色とカラースケールは同時に設定することもできます。

**サンプル コード**
```
public Request addConditionalFormatRule(Integer sheetId) {
    Request request = new Request();

    ConditionalFormatRule rule = new ConditionalFormatRule();
    
    //単一色
    BooleanRule booleanRule = new BooleanRule();
    BooleanCondition con = new BooleanCondition();
    con.setType("");//状態のタイプ。
    List<ConditionValue> vals = new ArrayList<>();
    ConditionValue val = new ConditionValue();
    val.setRelativeDate("");//相対日付 (現在の日付に基づく)。タイプが DATE_BEFORE、DATE_AFTER、DATE_ON_OR_BEFORE、または DATE_ON_OR_AFTER の場合にのみ有効です。相対日付はデータ検証ではサポートされていません。これらは、条件付き書式設定と条件付きフィルターでのみサポートされます。
    val.setUserEnteredValue("");//条件の基礎となる値。値は、ユーザーがセルに入力したかのように解析されます。数式はサポートされています (「=」または「+」で始まる必要があります)。
    vals.add(val);
    con.setValues(vals);//条件の値。サポートされる値の数は条件タイプによって異なります。ゼロ値をサポートするものもあれば、1 つまたは 2 つの値をサポートするものもあり、ConditionType.ONE_OF_LIST は任意の数の値をサポートします。
    booleanRule.setCondition(con);//ルールの条件。条件が true と評価されると、形式が適用されます。
    
    CellFormat format = getCellFormat();
    booleanRule.setFormat(format);//適用する形式。条件付き書式では、太字、斜体、取り消し線、前景色、背景色などの書式設定のサブセットのみを適用できます。
    rule.setBooleanRule(booleanRule);//書式設定はルールに従って「オン」または「オフ」のいずれかになります。
    
    //カラースケール
    GradientRule gradientRule = new GradientRule();
    InterpolationPoint maxpoint = new InterpolationPoint();
    Color color = new Color();
    maxpoint.setColor(color);//この補間ポイントが使用する色。	//setColorStyle
    maxpoint.setValue("");//この補間点が使用する値。方程式かもしれない。タイプが MIN または MAX の場合は使用されません。
    maxpoint.setType("");//値をどのように解釈するか。
//		MIN	最小値（最小点）
//		MAX	最大値（最大点）
//		NUMBER	値（最小点、中央、最大点）
//		PERCENT	パーセント（最小点、中央、最大点）
//		PERCENTILE	パーセンタイル（最小点、中央、最大点）
    gradientRule.setMaxpoint(maxpoint);//最終的な補間点。
    InterpolationPoint midpoint = new InterpolationPoint();
    gradientRule.setMidpoint(midpoint);//オプションの中間補間点。
    InterpolationPoint minpoint = new InterpolationPoint();
    gradientRule.setMinpoint(minpoint);//補間開始点。
    rule.setGradientRule(gradientRule);//書式設定はルール内のグラデーションに応じて異なります。
    
    //適用する範囲
    List<GridRange> ranges = new ArrayList<>();
    GridRange range = new GridRange(); //枠線の範囲
    range.setSheetId(sheetId); //設定するシートID
    range.setStartRowIndex(2); //開始行(0スタート)
    range.setEndRowIndex(4); //終了行(0スタート)
    range.setStartColumnIndex(1); //開始列(0スタート))
    range.setEndColumnIndex(3); //終了列(0スタート)
    ranges.add(range);
    rule.setRanges(ranges);//条件が true の場合にフォーマットされる範囲。すべての範囲は同じグリッド上にある必要があります。
    
    AddConditionalFormatRuleRequest r = new AddConditionalFormatRuleRequest();
    r.setIndex(0);//追加する「条件付き書式」のインデックスNo
    r.setRule(rule);//追加するルール。
    
    request.setAddConditionalFormatRule(r);
    return request;
}
```
**実行結果**
「フィルタビューテスト」という名前のフィルタビューがない状態で実行すると
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/4f751d24-c873-b0e2-d16e-f98eaae85271.png">

フィルタビューが追加され、A列の指定した日付以降が表示され、
B列が降順にソートされています。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f01edf8c-8f15-a207-c486-474ab18fe8b1.png">

### 1.1. 単一色
単一色の設定はBooleanRuleクラスで設定します。

**サンプル コード**
```
BooleanRule booleanRule = new BooleanRule();
```
#### 1.1.1. 書式を適用する条件の設定
BooleanRuleクラスのsetConditionメソッドで
BooleanConditionインスタンスを設定します。

BooleanConditionクラスでType、ConditionValueクラスで条件の内容を設定します。
表中のvalueは、ConditionValueクラスのsetUserEnteredValueの必須数です。
|メニュー|サブ|type/RelativeDate|value|
|---|---|---|---|
|空白||BLANK|0|
|空白ではない||NOT_BLANK|0|
|次を含むテキスト||TEXT_CONTAINS|1|
|次を含まないテキスト||TEXT_NOT_CONTAINS|1|
|次で始まるテキスト：||TEXT_STARTS_WITH|1|
|次で終わるテキスト：||TEXT_ENDS_WITH|1|
|完全一致するテキスト||TEXT_EQ|1|
|日付||DATE_EQ||
||本日|TODAY|0|
||明日|TOMORROW|0|
||昨日|YESTERDAY|0|
||過去1週間以内|PAST_WEEK|0|
||過去1ヶ月以内|PAST_MONTH|0|
||過去1年以内|PAST_YEAR|0|
||正確な日付||1|
|次より前の日付||DATE_BEFORE||
||本日|TODAY|0|
||明日|TOMORROW|0|
||昨日|YESTERDAY|0|
||過去1週間以内|PAST_WEEK|0|
||過去1ヶ月以内|PAST_MONTH|0|
||過去1年以内|PAST_YEAR|0|
||正確な日付||1|
|次より後の日付||DATE_AFTER||
||本日|TODAY|0|
||明日|TOMORROW|0|
||昨日|YESTERDAY|0|
||正確な日付||1|
|次より大きい||NUMBER_GREATER|1|
|以上||NUMBER_GREATER_THAN_EQ|1|
|次より小さい||NUMBER_LESS|1|
|以下||NUMBER_LESS_THAN_EQ|1|
|次と等しい||NUMBER_EQ|1|
|次と等しくない||NUMBER_NOT_EQ|1|
|次の間にある||NUMBER_BETWEEN|2|
|次の間にない||NUMBER_NOT_BETWEEN|2|
|カスタム数式||CUSTOM_FORMULA|1|

次のサンプルでは、「値が1と10の間にある」を条件に設定しています。

**サンプル コード**
```
BooleanCondition condition = new BooleanCondition();
List<ConditionValue> values = new ArrayList<>();
ConditionValue v1 = new ConditionValue();
v1.setUserEnteredValue("1");   //値を2つ設定（1つ目）
ConditionValue v2 = new ConditionValue();
v2.setUserEnteredValue("10");  //値を2つ設定（2つ目）
values.add(v1);
values.add(v2);
condition.setValues(values);
condition.setType("NUMBER_BETWEEN");  //「次の間にある」を指定

booleanRule.setCondition(condition);
```
#### 1.1.2. 適用する書式の設定
条件を満たした際にセルに設定する書式を指定します。
BooleanRuleクラスのsetFormatメソッドで設定します。

**サンプル コード**
```
CellFormat format = getCellFormat();

TextFormat txFormat = new TextFormat();
//太字(true:有効,false:無効)
txFormat.setBold(true);

//斜体(true:有効,false:無効)
txFormat.setItalic(true);

//下線(true:有効,false:無効)
txFormat.setUnderline(true);

//取り消し線(true:有効,false:無効)
txFormat.setStrikethrough(false);

//文字色
Color textColor = new Color();
textColor.setRed(0f).setGreen(0f).setBlue(1f);
txFormat.setForegroundColor(textColor); //または、setForegroundColorStyle()
format.setTextFormat(txFormat);

//背景色
Color color = new Color();
color.setRed(1f).setGreen(0f).setBlue(0f);
format.setBackgroundColor(color);

booleanRule.setFormat(format);
```

### 1.2. カラースケール

カラースケールはGradientRuleクラスのメソッドで最小点、中央、最大点を設定します。
それぞれでtypeを設定できますが、指定可能な値のタイプは
最小点、中央、最大点で異なります。
また、値の指定(value)はMINとMAX以外で設定できます。
|type|内容|最小点|中央　|最大点|value|
|---|---|---|---|---|---|
|MIN|最小値|○||||
|MAX|最大値|||○||
|NUMBER|値|○|○|○|○|
|PERCENT|パーセント|○|○|○|○|
|PERCENTILE|パーセンタイル|○|○|○|○|

**サンプル コード**
```
GradientRule gradientRule = new GradientRule();

//最小点
InterpolationPoint minpoint = new InterpolationPoint();
minpoint.setType("NUMBER");
minpoint.setValue("1");
Color minColor = new Color();
minColor.setRed(1.0f).setGreen(1.0f).setBlue(1.0f);
minpoint.setColor(minColor);   //または　setColorStyle()
gradientRule.setMinpoint(minpoint);

//中央
InterpolationPoint midpoint = new InterpolationPoint();
midpoint.setType("NUMBER");
midpoint.setValue("100");
Color midColor = new Color();
midColor.setRed(0.5f).setGreen(0f).setBlue(0f);
maxpoint.setColor(midColor);   //または　setColorStyle()
gradientRule.setMidpoint(midpoint);

//最大点
InterpolationPoint maxpoint = new InterpolationPoint();
maxpoint.setType("NUMBER");
maxpoint.setValue("100");
Color maxColor = new Color();
tabColor.setRed(1.0f).setGreen(0f).setBlue(0f);
maxpoint.setColor(maxColor);   //または　setColorStyle()
gradientRule.setMaxpoint(maxpoint);
```

## 2. 条件付き書式の更新
設定済みの条件付き書式を更新します。

更新する「条件付き書式」があるシートIDと、
「条件付き書式」の追加時に指定したインデックスNoを指定します。

**サンプル コード**
```
public Request updateConditionalFormatRule(Integer sheetId) {
    Request request = new Request();

    ConditionalFormatRule rule = new ConditionalFormatRule();
    
    //カラースケール
    GradientRule gradientRule = new GradientRule();
    InterpolationPoint maxpoint = new InterpolationPoint();
    Color color = new Color();
    maxpoint.setColor(color);//この補間ポイントが使用する色。	//setColorStyle
    maxpoint.setValue("");//この補間点が使用する値。方程式かもしれない。タイプが MIN または MAX の場合は使用されません。
    maxpoint.setType("");//値をどのように解釈するか。
//		MIN	最小値（最小点）
//		MAX	最大値（最大点）
//		NUMBER	値（最小点、中央、最大点）
//		PERCENT	パーセント（最小点、中央、最大点）
//		PERCENTILE	パーセンタイル（最小点、中央、最大点）
    gradientRule.setMaxpoint(maxpoint);//最終的な補間点。
    InterpolationPoint midpoint = new InterpolationPoint();
    gradientRule.setMidpoint(midpoint);//オプションの中間補間点。
    InterpolationPoint minpoint = new InterpolationPoint();
    gradientRule.setMinpoint(minpoint);//補間開始点。
    rule.setGradientRule(gradientRule);//書式設定はルール内のグラデーションに応じて異なります。
    
    //適用する範囲
    List<GridRange> ranges = new ArrayList<>();
    GridRange range = new GridRange(); //枠線の範囲
    range.setSheetId(sheetId); //設定するシートID
    range.setStartRowIndex(2); //開始行(0スタート)
    range.setEndRowIndex(4); //終了行(0スタート)
    range.setStartColumnIndex(1); //開始列(0スタート))
    range.setEndColumnIndex(3); //終了列(0スタート)
    ranges.add(range);
    rule.setRanges(ranges);//条件が true の場合にフォーマットされる範囲。すべての範囲は同じグリッド上にある必要があります。

    UpdateConditionalFormatRuleRequest r = new UpdateConditionalFormatRuleRequest();
    r.setSheetId(sheetId);//更新する「条件付き書式」があるシートID
    r.setIndex(0);//「条件付き書式」のインデックスNo
    r.setRule(rule);
    
    request.setUpdateConditionalFormatRule(r);
    return request;
}
```
**実行結果**
このフィルタを更新します。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f01edf8c-8f15-a207-c486-474ab18fe8b1.png">

「名前」と「範囲」と「並べ替え(B列を昇順に)」が更新されました。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/6f55e7ed-9cef-0bf6-0a8c-75dce3e20880.png">


## 3. 条件付き書式の削除
設定済みの条件付き書式を削除します。

削除する「条件付き書式」があるシートIDと、
「条件付き書式」の追加時に指定したインデックスNoを指定します。

**サンプル コード**
```
public Request deleteConditionalFormatRule(Integer sheetId) {
    Request request = new Request();

    DeleteConditionalFormatRuleRequest r = new DeleteConditionalFormatRuleRequest();
    r.setSheetId(sheetId); //削除する「条件付き書式」があるシートID
    r.setIndex(0);         //削除する「条件付き書式」のインデックスNo
    
    request.setDeleteConditionalFormatRule(r);
    return request;
}
```

おしまい。。