JavaのGoogleスプレッドシートとやり取りする

JavaのGoogleスプレッドシートとやり取りする

1. 概要

Googleスプレッドシートを使用すると、スプレッドシートを保存して操作したり、ドキュメント上で他のユーザーと共同作業したりできます。

自動化された操作を実行するなど、アプリケーションからこれらのドキュメントにアクセスすると便利な場合があります。 この目的のために、Googleは開発者が操作できるGoogle Sheets APIを提供します。

この記事では、we’re going to take a look at how we can connect to the API and perform operations on Google Sheets.

2. Mavenの依存関係

APIに接続してドキュメントを操作するには、google-api-clientgoogle-oauth-client-jetty、およびgoogle-api-services-sheetsの依存関係を追加する必要があります。


    com.google.api-client
    google-api-client
    1.23.0


    com.google.oauth-client
    google-oauth-client-jetty
    1.23.0


    com.google.apis
    google-api-services-sheets
    v4-rev493-1.23.0

3. 承認

アプリケーションを介してアクセスする前に、The Google Sheets API requires OAuth 2.0 authorization

最初に、一連のOAuth資格情報を取得してから、これをアプリケーションで使用して承認のリクエストを送信する必要があります。

3.1. OAuth2.0認証情報の取得

認証情報を取得するには、Google Developers Consoleでプロジェクトを作成してから、プロジェクトのGoogle Sheets APIを有効にする必要があります。 Google Quickstartガイドの最初のステップには、これを行う方法の詳細情報が含まれています。

資格情報を含むJSONファイルをダウンロードしたら、アプリケーションのsrc/main/resourcesディレクトリにあるgoogle-sheets-client-secret.jsonファイルの内容をコピーしましょう。

ファイルの内容は次のようになります。

{
  "installed":
    {
      "client_id":"",
      "project_id":"decisive-octane-187810",
      "auth_uri":"https://accounts.google.com/o/oauth2/auth",
      "token_uri":"https://accounts.google.com/o/oauth2/token",
      "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
      "client_secret":"",
      "redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]
    }
}

3.2. Credentialオブジェクトの取得

承認が成功すると、Google Sheets APIとのやり取りに使用できるCredentialオブジェクトが返されます。

上記のJSONファイルのコンテンツを読み取り、GoogleClientSecretsオブジェクトを構築する静的なauthorize()メソッドを使用してGoogleAuthorizeUtilクラスを作成しましょう。

次に、GoogleAuthorizationCodeFlowを作成し、承認リクエストを送信します。

public class GoogleAuthorizeUtil {
    public static Credential authorize() throws IOException, GeneralSecurityException {

        // build GoogleClientSecrets from JSON file

        List scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);

        // build Credential object

        return credential;
    }
}

この例では、Googleスプレッドシートにアクセスし、メモリ内のDataStoreFactoryを使用して受信した認証情報を保存するため、SPREADSHEETSスコープを設定しています。 別のオプションは、FileDataStoreFactoryを使用して資格情報をファイルに保存することです。

GoogleAuthorizeUtil class,の完全なソースコードについては、the GitHub projectを確認してください。

4. Sheetsサービスインスタンスの構築

Googleスプレッドシートを操作するには、a Sheets object which is the client for reading and writing through the APIが必要です。

上記のCredentialオブジェクトを使用してSheets:のインスタンスを取得するSheetsServiceUtilクラスを作成しましょう

public class SheetsServiceUtil {
    private static final String APPLICATION_NAME = "Google Sheets Example";

    public static Sheets getSheetsService() throws IOException, GeneralSecurityException {
        Credential credential = GoogleAuthorizeUtil.authorize();
        return new Sheets.Builder(
          GoogleNetHttpTransport.newTrustedTransport(),
          JacksonFactory.getDefaultInstance(), credential)
          .setApplicationName(APPLICATION_NAME)
          .build();
    }
}

次に、APIを使用して実行できる最も一般的な操作のいくつかを見ていきます。

5. シートに値を書く

既存のスプレッドシートを操作するには、そのスプレッドシートのIDを知っている必要があります。これはURLから見つけることができます。

この例では、次の場所にある「Expenses」という公開スプレッドシートを使用します。

このURLに基​​づいて、このスプレッドシートのIDを「1sILuxZUnyl_7-MlNThjt765oWshN3Xs-PPLfqYe4DhI」として識別できます。

また、to read and write values, we’re going to use spreadsheets.values collections.

値はValueRangeオブジェクトとして表されます。これは、シートの行または列に対応するJavaObjects,のリストのリストです。

SheetsサービスオブジェクトとSPREADSHEET_ID定数を初期化するテストクラスを作成しましょう。

public class GoogleSheetsLiveTest {
    private static Sheets sheetsService;
    private static String SPREADSHEET_ID = // ...

    @BeforeClass
    public static void setup() throws GeneralSecurityException, IOException {
        sheetsService = SheetsServiceUtil.getSheetsService();
    }
}

次に、次の方法で値を書き込むことができます。

  • 単一の範囲への書き込み

  • 複数の範囲への書き込み

  • テーブルの後にデータを追加する

5.1. 単一範囲への書き込み

シートの単一の範囲に値を書き込むには、spreadsheets().values().update()メソッドを使用します。

@Test
public void whenWriteSheet_thenReadSheetOk() throws IOException {
    ValueRange body = new ValueRange()
      .setValues(Arrays.asList(
        Arrays.asList("Expenses January"),
        Arrays.asList("books", "30"),
        Arrays.asList("pens", "10"),
        Arrays.asList("Expenses February"),
        Arrays.asList("clothes", "20"),
        Arrays.asList("shoes", "5")));
    UpdateValuesResponse result = sheetsService.spreadsheets().values()
      .update(SPREADSHEET_ID, "A1", body)
      .setValueInputOption("RAW")
      .execute();
}

ここでは、最初に、2か月間の経費のリストを含む複数の行を持つValueRangeオブジェクトを作成します。

次に、update()メソッドを使用して、「A1」セルから開始して、指定されたIDでスプレッドシートに値を書き込むリクエストを作成します。

リクエストを送信するために、execute()メソッドを使用しています。

値セットを行ではなく列と見なしたい場合は、setMajorDimension(“COLUMNS”)メソッドを使用できます。

「RAW」入力オプションは、値が計算されずにそのまま書き込まれることを意味します。

このJUnitテストを実行する場合、the application will open a browser window using the system’s default browser that asks the user to log in and give our application permission to interact with Google Sheets on the user’s behalf:

image

OAuth Service Accountがある場合は、この手動の手順をバイパスできることに注意してください。

A requirement for the application to be able to view or edit the spreadsheet is that the signed-in user has a view or edit access to it.それ以外の場合、リクエストは403エラーになります。 この例で使用するスプレッドシートは、パブリック編集アクセスに設定されています。

ここで、スプレッドシートを確認すると、範囲「A1:B6」が値セットで更新されていることがわかります。

1つのリクエストで複数の異なる範囲に書き込むことに移りましょう。

5.2. 複数の範囲への書き込み

シート上の複数の範囲を更新する場合は、BatchUpdateValuesRequestを使用してパフォーマンスを向上させることができます。

List data = new ArrayList<>();
data.add(new ValueRange()
  .setRange("D1")
  .setValues(Arrays.asList(
    Arrays.asList("January Total", "=B2+B3"))));
data.add(new ValueRange()
  .setRange("D4")
  .setValues(Arrays.asList(
    Arrays.asList("February Total", "=B5+B6"))));

BatchUpdateValuesRequest batchBody = new BatchUpdateValuesRequest()
  .setValueInputOption("USER_ENTERED")
  .setData(data);

BatchUpdateValuesResponse batchResult = sheetsService.spreadsheets().values()
  .batchUpdate(SPREADSHEET_ID, batchBody)
  .execute();

この例では、最初に、月の名前と総経費を表す2つのセルで構成されるValueRanges,のリストを作成しています。

次に、他の2つのセルを追加するthe input option “USER_ENTERED”, as opposed to “RAW”, meaning the cell values will be computed based on the formulaを使用してBatchUpdateValuesRequestを作成します。

最後に、batchUpdateリクエストを作成して送信します。 その結果、範囲「D1:E1」と「D4:E4」が更新されます。

5.3. テーブルの後にデータを追加する

シートに値を書き込む別の方法は、テーブルの最後に値を追加することです。

このために、append()メソッドを使用できます。

ValueRange appendBody = new ValueRange()
  .setValues(Arrays.asList(
    Arrays.asList("Total", "=E1+E4")));
AppendValuesResponse appendResult = sheetsService.spreadsheets().values()
  .append(SPREADSHEET_ID, "A1", appendBody)
  .setValueInputOption("USER_ENTERED")
  .setInsertDataOption("INSERT_ROWS")
  .setIncludeValuesInResponse(true)
  .execute();

ValueRange total = appendResult.getUpdates().getUpdatedData();
assertThat(total.getValues().get(0).get(1)).isEqualTo("65");

まず、追加するセル値を含むValueRangeオブジェクトを作成します。

この場合、これには、“E1”“E2”のセル値を加算して見つけた両方の月の合計費用を含むセルが含まれています。

次に、「A1」セルを含むテーブルの後にデータを追加するリクエストを作成します。

INSERT_ROWSオプションは、データを新しい行に追加し、テーブルの後の既存のデータを置き換えないことを意味します。 これは、例が最初の実行で範囲「A7:B7」を書き込むことを意味します。

以降の実行では、“A1”セルで始まるテーブルが拡張され、“A7:B7”行が含まれるようになるため、新しい行は“A8:B8”行に移動します。

また、リクエストへの応答を検証する場合は、includeValuesInResponseプロパティをtrueに設定する必要があります。.その結果、応答オブジェクトには更新されたデータが含まれます。

6. シートから値を読み取る

シートから値を読み取って、値が正しく書き込まれたことを確認しましょう。

これを行うには、spreadsheets().values().get()メソッドを使用して単一の範囲を読み取るか、batchUpdate()メソッドを使用して複数の範囲を読み取ります。

List ranges = Arrays.asList("E1","E4");
BatchGetValuesResponse readResult = sheetsService.spreadsheets().values()
  .batchGet(SPREADSHEET_ID)
  .setRanges(ranges)
  .execute();

ValueRange januaryTotal = readResult.getValueRanges().get(0);
assertThat(januaryTotal.getValues().get(0).get(0))
  .isEqualTo("40");

ValueRange febTotal = readResult.getValueRanges().get(1);
assertThat(febTotal.getValues().get(0).get(0))
  .isEqualTo("25");

ここでは、範囲“E1”“E4”を読み取り、前に書き込んだ各月の合計が含まれていることを確認しています。

7. 新しいスプレッドシートの作成

値の読み取りと更新に加えて、spreadsheets()およびspreadsheets().sheets()コレクションを使用してシートまたはスプレッドシート全体を操作することもできます。

新しいスプレッドシートを作成する例を見てみましょう。

@Test
public void test() throws IOException {
    Spreadsheet spreadSheet = new Spreadsheet().setProperties(
      new SpreadsheetProperties().setTitle("My Spreadsheet"));
    Spreadsheet result = sheetsService
      .spreadsheets()
      .create(spreadSheet).execute();

    assertThat(result.getSpreadsheetId()).isNotNull();
}

ここでは、最初に「MySpreadsheet”」というタイトルのSpreadsheetオブジェクトを作成し、次にcreate()メソッドとexecute()メソッドを使用してリクエストを作成して送信します。

新しいスプレッドシートは非公開になり、サインインしたユーザーのドライブに配置されます。

8. その他の更新操作

他のほとんどの操作はRequestオブジェクトの形式を取り、それをリストに追加してBatchUpdateSpreadsheetRequest.を構築するために使用します

スプレッドシートのタイトルを変更し、セルのセットを1つのシートから別のシートにコピーして貼り付ける2つのリクエストを送信する方法を見てみましょう。

@Test
public void whenUpdateSpreadSheetTitle_thenOk() throws IOException {
    UpdateSpreadsheetPropertiesRequest updateSpreadSheetRequest
      = new UpdateSpreadsheetPropertiesRequest().setFields("*")
      .setProperties(new SpreadsheetProperties().setTitle("Expenses"));

    CopyPasteRequest copyRequest = new CopyPasteRequest()
      .setSource(new GridRange().setSheetId(0)
        .setStartColumnIndex(0).setEndColumnIndex(2)
        .setStartRowIndex(0).setEndRowIndex(1))
      .setDestination(new GridRange().setSheetId(1)
        .setStartColumnIndex(0).setEndColumnIndex(2)
        .setStartRowIndex(0).setEndRowIndex(1))
      .setPasteType("PASTE_VALUES");

    List requests = new ArrayList<>();
    requests.add(new Request()
      .setCopyPaste(copyRequest));
    requests.add(new Request()
      .setUpdateSpreadsheetProperties(updateSpreadSheetRequest));

    BatchUpdateSpreadsheetRequest body
      = new BatchUpdateSpreadsheetRequest().setRequests(requests);

    sheetsService.spreadsheets().batchUpdate(SPREADSHEET_ID, body).execute();
}

ここでは、新しいタイトルを指定するUpdateSpreadSheetPropertiesRequestオブジェクト、操作のソースと宛先を含むCopyPasteRequestオブジェクトを作成し、これらのオブジェクトをListRequests.

次に、両方のリクエストをバッチ更新として実行します。

他の多くのタイプのリクエストも同様の方法で使用できます。 たとえば、スプレッドシートにAddSheetRequestで新しいシートを作成したり、FindReplaceRequest.で値を変更したりできます。

境界線の変更、フィルターの追加、セルの結合など、他の操作を実行できます。 Requestタイプの完全なリストは、hereで入手できます。

9. 結論

この記事では、JavaアプリケーションからGoogle Sheets APIに接続する方法と、GoogleSheetsに保存されているドキュメントを操作するいくつかの例を見てきました。

例の完全なソースコードはover on GitHubにあります。