[Google Sheets API] Google Sheets API v4をJavaで操作する

Google Sheets API V4を使用してJavaでスプレットシートを操作する方法を
ご紹介します。
APIの呼び出しは、Googleのサービスアカウントを作成して実行します。

***Google Sheets APIとは***
Googleが提供しているAPIで、スプレットシートを操作することを目的としています。
無料で使用できます。
1分単位の制限をクリアしていれば１日の使用量の制限もありません。

読み取り・書き込みリクエスト制限
　・プロジェクトごと、300回/分
　・プロジェクトごと、ユーザーごと、60回/分

|No||目次|
|---|---|---|
|1||[Google Sheets APIを使用するための準備](#1-google-sheets-apiを使用するための準備)|
||1|[プロジェクトの作成](#11-プロジェクトの作成)|
||2|[Google Sheets APIの設定](#12-google-sheets-apiの設定)|
||3|[Googleサービスアカウントの作成](#13-googleサービスアカウントの作成)|
||4|[操作するスプレットシートに権限追加](#14-操作するスプレットシートに権限追加)|
|2||[Spreadsheetsインスタンスの取得](#2-spreadsheetsインスタンスの取得)|
||1|[googleライブラリの読み込み](#21-googleライブラリの読み込み)|
||2|[Sheetsインスタンスの取得](#22-sheetsインスタンスの取得)|
|3||[スプレットシートの操作](#3-スプレットシートの操作)|
||1|[スプレットシート情報の取得](#31-スプレットシート情報の取得)|
||2|[スプレットシートのコピー](#32-スプレットシートのコピー)|
||3|[スプレットシートの操作](#33-スプレットシートの操作)|

# 1. Google Sheets APIを使用するための準備
設定は下記から行います。
[⧉Google クラウド プラットフォーム](https://console.cloud.google.com/)

### 1.1. プロジェクトの作成
|No|手順||
|---|---|:-:|
|1|「プロジェクトの選択」 -> 「新しいプロジェクト」を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/d5b57ab1-dc82-c5b0-2385-c2d55ac26a2e.png">|
|2|「プロジェクト名」 に作成するプロジェクト名を入力し、「作成」ボタンを押します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/71343aac-b544-91f4-1a69-ba30f8b6c09a.png">|

### 1.2. Google Sheets APIの設定
Google Sheets APIを使えるようにします。

|No|手順||
|---|---|:-:|
|1|メニューの 「APIとサービス」 -> 「ライブラリ」 を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2fda7515-ffdf-11d7-4142-fed896cc8413.png">|
|2|Sheetsと入力して「Google Sheets API」を検索します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/82010023-a998-ad16-d8ae-107a29de9595.png">|
|3|「Google Sheets API」が検索されますので、これを選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/7133ed86-58f9-6f58-9883-9f331fa96849.png">|
|4|「有効にする」ボタンを押して「Google Sheets API」を使用可能にします。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f529fce5-1f5c-75db-4bdb-70e5a4f5460b.png">|

### 1.3. Googleサービスアカウントの作成
プログラムに使用するGoogleサービスアカウントのJSONファイルをダウンロードします。

|No|手順||
|---|---|:-:|
|1|メニューの「IAMと管理」 -> 「サービスアカウント」 を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/0a5aaa99-df05-0d94-9dfa-a00dfbb61792.png">|
|2|「サービスアカウントを作成」 を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/ac373e0f-e397-d237-ef46-7085ea6356f7.png">|
|3|「サービスアカウント名」 に入力し、「完了」 ボタンを押します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/c66ef821-cd76-deab-40d3-e2868149d2b5.png">|
|4|「操作」 -> 「鍵を管理」 を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/7d2706e1-95df-7d9f-b23e-a7de65ea5c65.png">|
|5|「鍵を追加」 -> 「新しい鍵を作成」 を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/10b23587-4dbf-2e68-06fe-a2ca602a812a.png">|
|6|キーのタイプに「JSON」を選択して、「作成」ボタンを押します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/450f38fc-5157-1190-a933-40e6610f7850.png">|
|7|キーがダウンロードされます。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/9b6c756d-5e38-cce0-e6bf-edeefafb3937.png">|

このようなjsonファイルがダウンロードされます。
このjsonファイルを使用してプログラムを実行します。
```json
{
  "type": "service_account",
  "project_id": "astute-tractor-400101",
  "private_key_id": "xxxxxxxxxxxxxxxxxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n",
  "client_email": "googlesheets-test@astute-tractor-400101.iam.gserviceaccount.com",
  "client_id": "xxxxxxxxxxxxxxxxxxxxx",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/googlesheets-test%40astute-tractor-400101.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}
```

### 1.4. 操作するスプレットシートに権限追加
Google Sheets APIで操作したいシートに権限を追加します。

|No|手順||
|---|---|:-:|
|1|シートを開いて、「ファイル」 -> 「共有」 -> 「他のユーザーと共有」を選択します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/99e4bd3c-176d-dc31-9c2f-3e96ad147e20.png">|
|2|サービスアカウントのメールアドレスを入力して、「共有」ボタンを押します。|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/1a252184-c57c-37f5-e85e-9c8a6050a185.png">|

操作するスプレットシートのURLからスプレットシートIDとシートIDを控えます。
シートIDは、URLパラメータのgidになります。
```
https://docs.google.com/spreadsheets/d/1pRpwe32zA8zze2xshY4rWt4ndk7lJ7OsxZQXEsSgyrw/edit#gid=0

スプレットシートID：1pRpwe32zA8zze2xshY4rWt4ndk7lJ7OsxZQXEsSgyrw
シートID：0
```

# 2. Spreadsheetsインスタンスの取得
### 2.1. googleライブラリの読み込み
Google Sheets APIを使用するためにライブラリのパスを設定します。
私の環境はpom.xmlで下記を指定しています。
Javaのバージョンは21を使用しています。

```xml
<!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client -->
<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.25.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.oauth-client/google-oauth-client-jetty -->
<dependency>
    <groupId>com.google.oauth-client</groupId>
    <artifactId>google-oauth-client-jetty</artifactId>
    <version>1.34.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-sheets -->
<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-sheets</artifactId>
    <version>v4-rev20230815-2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-drive -->
<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-drive</artifactId>
    <version>v3-rev197-1.25.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.auth/google-auth-library-oauth2-http -->
<dependency>
    <groupId>com.google.auth</groupId>
    <artifactId>google-auth-library-oauth2-http</artifactId>
    <version>1.20.0</version>
</dependency>
```
### 2.2. Sheetsインスタンスの取得
スプレットシートを操作するためのSheetsインスタンスを取得します。
ファイルパスには、[1.3.　Googleサービスアカウントの作成](#13-googleサービスアカウントの作成)
でダウンロードしたJSONファイルのパスを指定してください。
```java
public static Spreadsheets getSpreadsheets() throws IOException, GeneralSecurityException {
    InputStream input = new FileInputStream("/** サービスアカウントキーのファイルパス */");
    GoogleCredentials credential = ServiceAccountCredentials.fromStream(input).createScoped(Arrays.asList(SheetsScopes.SPREADSHEETS));

    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    HttpRequestInitializer httpRequestInitializer = new HttpCredentialsAdapter(credential);

    Sheets service = new Sheets.Builder(transport,jsonFactory,httpRequestInitializer).build();
    
    return service.spreadsheets();
}
```
# 3. スプレットシートの操作

### 3.1. スプレットシート情報の取得
スプレットシート内のさまざまな情報が取得できます。
取得したいスプレットシートのIDとシート名、範囲、内容を指定することで
スプレットシートの情報を取得します。

試しに、[1.4.　操作するスプレットシートに権限追加](#14-操作するスプレットシートに権限追加)
で権限を追加したスプレットシートの情報を取得してみます。
```java
public static void main(String[] args) throws IOException, GeneralSecurityException {
    //操作するスプレットシートのID
    String fileId = "1pRpwe32zA8zze2xshY4rWt4ndk7lJ7OsxZQXEsSgyrw";
    
    Spreadsheets sheet = getSpreadsheets();
    com.google.api.services.sheets.v4.model.Spreadsheet info =
    sheet.get(fileId)										//取得するスプレットシートID
         .setRanges(Arrays.asList(new String[] {"シート1"}))	//取得するシート名とシート範囲
         .setFields("*")									//取得するField
         .execute();										//実行する
    System.out.println(info);
}
```
実行すると、スプレットシートの情報がまるっと取れました。
```json
{"properties":{"autoRecalc":"ON_CHANGE","defaultFormat":{"backgroundColor":{"blue":1.0,"green":1.0,"red":1.0},"backgroundColorStyle":{"rgbColor":{"blue":1.0,"green":1.0,"red":1.0}},"padding":{"bottom":2,"left":3,"right":3,"top":2},"textFormat":{"bold":false,"fontFamily":"arial,sans,sans-serif","fontSize":10,"foregroundColor":{},"foregroundColorStyle":{"rgbColor":{}},"italic":false,"strikethrough":false,"underline":false},"verticalAlignment":"BOTTOM","wrapStrategy":"OVERFLOW_CELL"},"locale":"ja_JP","spreadsheetTheme":{"primaryFontFamily":"Arial","themeColors":[{"color":{"rgbColor":{}},"colorType":"TEXT"},{"color":{"rgbColor":{"blue":1.0,"green":1.0,"red":1.0}},"colorType":"BACKGROUND"},{"color":{"rgbColor":{"blue":0.95686275,"green":0.52156866,"red":0.25882354}},"colorType":"ACCENT1"},{"color":{"rgbColor":{"blue":0.20784314,"green":0.2627451,"red":0.91764706}},"colorType":"ACCENT2"},{"color":{"rgbColor":{"blue":0.015686275,"green":0.7372549,"red":0.9843137}},"colorType":"ACCENT3"},{"color":{"rgbColor":{"blue":0.3254902,"green":0.65882355,"red":0.20392157}},"colorType":"ACCENT4"},{"color":{"rgbColor":{"blue":0.003921569,"green":0.42745098,"red":1.0}},"colorType":"ACCENT5"},{"color":{"rgbColor":{"blue":0.7764706,"green":0.7411765,"red":0.27450982}},"colorType":"ACCENT6"},{"color":{"rgbColor":{"blue":0.8,"green":0.33333334,"red":0.06666667}},"colorType":"LINK"}]},"timeZone":"Asia/Tokyo","title":"Test"},"sheets":[{"properties":{"gridProperties":{"columnCount":26,"rowCount":1000},"index":0,"sheetId":0,"sheetType":"GRID","title":"シート1"}}],"spreadsheetId":"1pRpwe32zA8zze2xshY4rWt4ndk7lJ7OsxZQXEsSgyrw","spreadsheetUrl":"https://docs.google.com/spreadsheets/d/1pRpwe32zA8zze2xshY4rWt4ndk7lJ7OsxZQXEsSgyrw/edit"}
```
取得できる情報の詳細は、
[⧉[Google Sheets API] Javaでスプレットシートの情報を取得する](https://qiita.com/doran/items/20eb63a90f016a549273)
の記事を参照ください。
### 3.2. スプレットシートのコピー
スプレットシートのシートをコピーします。
コピーは、SheetsOperationsのcopyTo()メソッドで実行します。
```java
SheetsOperations operation = getSpreadsheets().sheets();
operation.copyTo()
```
詳細な内容は
[⧉[Google Sheets API] スプレットシートのシートを別のスプレットシートにコピーする](https://qiita.com/doran/items/63e96465a6b9ba300e8a)
の記事を参照ください。

### 3.3. スプレットシートの操作
操作したいリクエストを追加してbachUpdateを実行します。
操作したいリクエストは複数指定できます。
Google Sheets APIは***１分間の実行回数に上限***がありますので、
1つのシートに対して複数の操作がしたい場合は1度に送信することをお勧めします。
```java
public static void main(String[] args) throws IOException, GeneralSecurityException {
    String fileId = "ファイルID";	//操作するスプレットシートのID
    int sheetId = 0;			//操作するシートのID

    List<Request> requests = new ArrayList<>();
    requests.add(/** ここに操作したいリクエストを追加 */);
    BatchUpdateSpreadsheetRequest body = new BatchUpdateSpreadsheetRequest().setRequests(requests);

    Spreadsheets sheets = getSpreadsheets();	//Sheetsインスタンスの取得
    BatchUpdateSpreadsheetResponse update = sheets.batchUpdate(fileId, body).execute();
    List<Response> responses = update.getReplies();
    for(Response response : responses) {
    //例
        AddProtectedRangeResponse res = response.getAddProtectedRange();
        res.getProtectedRange().getProtectedRangeId();
    }
}
```

スプレットシートのメニューとGoogle Sheets APIを関連付けた記事を書きました。
下記の記事にまとめましたので、APIでやりたい事を探してみてください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
<br>
<br>
おしまい。。