diff --git a/libraries/pom.xml b/libraries/pom.xml
index eaa2d9d38f..3627e74472 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -633,9 +633,26 @@
${googleclient.version}
- com.google.http-client
- google-http-client-gson
- ${googleclient.version}
+ com.google.http-client
+ google-http-client-gson
+ ${googleclient.version}
+
+
+
+
+ com.google.api-client
+ google-api-client
+ ${google-api.version}
+
+
+ com.google.oauth-client
+ google-oauth-client-jetty
+ ${google-api.version}
+
+
+ com.google.apis
+ google-api-services-sheets
+ ${google-sheets.version}
@@ -710,5 +727,7 @@
1.0.0
3.8.4
2.5.5
+ 1.23.0
+ v4-rev493-1.21.0
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java b/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java
new file mode 100644
index 0000000000..650a1d084c
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java
@@ -0,0 +1,42 @@
+package com.baeldung.google.sheets;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.List;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
+import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
+import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
+import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.api.client.util.store.MemoryDataStoreFactory;
+import com.google.api.services.sheets.v4.SheetsScopes;
+
+public class GoogleAuthorizeUtil {
+ public static Credential authorize() throws IOException, GeneralSecurityException {
+ InputStream in = GoogleAuthorizeUtil.class.getResourceAsStream("/google-sheets-client-secret.json");
+ GoogleClientSecrets clientSecrets = GoogleClientSecrets
+ .load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));
+
+ List scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);
+
+ GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow
+ .Builder(GoogleNetHttpTransport.newTrustedTransport(),
+ JacksonFactory.getDefaultInstance(),
+ clientSecrets,
+ scopes)
+ .setDataStoreFactory(new MemoryDataStoreFactory())
+ .setAccessType("offline")
+ .build();
+ Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver())
+ .authorize("user");
+
+ return credential;
+ }
+
+}
diff --git a/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java b/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java
new file mode 100644
index 0000000000..bbce96f389
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java
@@ -0,0 +1,23 @@
+package com.baeldung.google.sheets;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.api.services.sheets.v4.Sheets;
+
+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();
+ }
+
+}
diff --git a/libraries/src/main/resources/google-sheets-client-secret.json b/libraries/src/main/resources/google-sheets-client-secret.json
new file mode 100644
index 0000000000..c92ccd6b9b
--- /dev/null
+++ b/libraries/src/main/resources/google-sheets-client-secret.json
@@ -0,0 +1 @@
+{"installed":{"client_id":"394827218507-2ev02b2ha8plt7g2lh5nqse02ee737cf.apps.googleusercontent.com","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":"2MnN1DfenoCGWMay3v8Bf7eI","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
\ No newline at end of file
diff --git a/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsIntegrationTest.java b/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsIntegrationTest.java
new file mode 100644
index 0000000000..5280073be2
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsIntegrationTest.java
@@ -0,0 +1,140 @@
+package com.baeldung.google.sheets;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.api.services.sheets.v4.Sheets;
+import com.google.api.services.sheets.v4.model.AppendValuesResponse;
+import com.google.api.services.sheets.v4.model.BatchGetValuesResponse;
+import com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetRequest;
+import com.google.api.services.sheets.v4.model.BatchUpdateValuesRequest;
+import com.google.api.services.sheets.v4.model.BatchUpdateValuesResponse;
+import com.google.api.services.sheets.v4.model.CopyPasteRequest;
+import com.google.api.services.sheets.v4.model.GridRange;
+import com.google.api.services.sheets.v4.model.Request;
+import com.google.api.services.sheets.v4.model.Spreadsheet;
+import com.google.api.services.sheets.v4.model.SpreadsheetProperties;
+import com.google.api.services.sheets.v4.model.UpdateSpreadsheetPropertiesRequest;
+import com.google.api.services.sheets.v4.model.UpdateValuesResponse;
+import com.google.api.services.sheets.v4.model.ValueRange;
+
+import static org.assertj.core.api.Assertions.*;
+
+public class GoogleSheetsIntegrationTest {
+
+ private static Sheets sheetsService;
+
+ // this id can be replaced with your spreadsheet id
+ // otherwise be advised that multiple people may run this test and update the public spreadsheet
+ private static final String SPREADSHEET_ID = "1sILuxZUnyl_7-MlNThjt765oWshN3Xs-PPLfqYe4DhI";
+
+ @BeforeClass
+ public static void setup() throws GeneralSecurityException, IOException {
+ sheetsService = SheetsServiceUtil.getSheetsService();
+ }
+
+ @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();
+
+ 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();
+
+ 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");
+
+ 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");
+ }
+
+
+ @Test
+ public void whenUpdateSpreadSheetTitle_thenOk() throws IOException {
+
+ UpdateSpreadsheetPropertiesRequest updateRequest = 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(updateRequest));
+
+ BatchUpdateSpreadsheetRequest body =
+ new BatchUpdateSpreadsheetRequest().setRequests(requests);
+
+ sheetsService.spreadsheets().batchUpdate(SPREADSHEET_ID, body).execute();
+ }
+
+ @Test
+ public void whenCreateSpreadSheet_thenIdOk() throws IOException {
+ Spreadsheet spreadSheet = new Spreadsheet()
+ .setProperties(new SpreadsheetProperties().setTitle("My Spreadsheet"));
+ Spreadsheet result = sheetsService.spreadsheets().create(spreadSheet).execute();
+
+ assertThat(result.getSpreadsheetId()).isNotNull();
+ }
+
+}