GPAL.GoogleSheets gives you a fluent client over the Google Sheets API: create spreadsheets and sheets, write and read grids of data, append/prepend/insert at specific cells, apply formatting, run sum and count calculations, and save results to a local file.
Here's the whole workflow, start to finish. Each piece is broken down and explained below.
using System.Collections.Generic;
using GenerallyPositive;
using static GenerallyPositive.Enums;
ICredentials credentials = GPAL.CredentialsFor(CredentialServiceType.Google);
credentials
.WithUsername("me@example.com")
.WithPassword("my-password");
var googleSheets = GPAL.GoogleSheets.ToGPALObject();
// Create and configure a spreadsheet
googleSheets.WithCredentials(credentials)
.WithSpreadsheet("TestSpreadsheet")
.SetSpreadsheetTitle("Test Spreadsheet Title")
.WithSheet("TestSheet")
.SetSheetName("RenamedTestSheet")
.WithSheet("RenamedTestSheet");
// Write a grid of data, then read it back
var data = new List<List<string>>
{
new List<string> { "Name", "Age", "City" },
new List<string> { "John", "30", "New York" },
new List<string> { "Jane", "25", "Los Angeles" }
} as IGPALGrid<string>;
googleSheets.WithCredentials(credentials)
.WithSpreadsheet("TestSpreadsheet")
.WithSheet("RenamedTestSheet")
.WithData(data)
.WithWriteRange("A1:C3")
.WriteToSheet("RenamedTestSheet");
IGPALGrid<string> readData;
googleSheets.WithReadRange("A1:C3")
.SaveTo(out readData);
// Format and calculate
googleSheets
.WithFormatType(FormatType.Bold)
.WithFormatValue(true)
.FormatRange("A1:C1")
.WithFormatType(FormatType.NumberFormat)
.WithNumberFormatValue(NumberFormatType.CURRENCY)
.FormatRange("B2:B3");
string sumResult;
googleSheets.WithReadRange("B2:B3")
.CalculateSum(out sumResult);
// Save to a local file
GPALFile file = GPAL.FileFor("output.csv");
googleSheets.WithReadRange("A1:C3")
.SaveTo(file);
Like other GPAL Google integrations, you get credentials via GPAL.CredentialsFor(CredentialServiceType.Google) and supply username/password (or OAuth client details). GPAL.GoogleSheets.ToGPALObject() returns the reusable client - WithCredentials attaches your identity to subsequent calls.
ICredentials credentials = GPAL.CredentialsFor(CredentialServiceType.Google);
credentials
.WithUsername("me@example.com")
.WithPassword("my-password");
var googleSheets = GPAL.GoogleSheets.ToGPALObject();
WithSpreadsheet picks (or creates) a spreadsheet by name, and SetSpreadsheetTitle sets its display title. WithSheet selects a tab within the spreadsheet, and SetSheetName renames it. Calling WithSheet again with the new name switches the active sheet to it.
googleSheets.WithCredentials(credentials)
.WithSpreadsheet("TestSpreadsheet")
.SetSpreadsheetTitle("Test Spreadsheet Title")
.WithSheet("TestSheet")
.SetSheetName("RenamedTestSheet")
.WithSheet("RenamedTestSheet");
WithData attaches an IGPALGrid<string> of rows, WithWriteRange picks the target cell range, and WriteToSheet performs the write. Reading is the mirror image: WithReadRange picks the range and SaveTo(out grid) pulls the values back into an IGPALGrid<string>.
googleSheets.WithCredentials(credentials)
.WithSpreadsheet("TestSpreadsheet")
.WithSheet("RenamedTestSheet")
.WithData(data)
.WithWriteRange("A1:C3")
.WriteToSheet("RenamedTestSheet");
IGPALGrid<string> readData;
googleSheets.WithReadRange("A1:C3")
.SaveTo(out readData);
Beyond a full-range write, you can target single cells. AppendToCell and PrependToCell add data before or after existing content, and InsertAtCell drops data at a specific position - WithInsertSeparator and WithInsertPosition control how multiple values are joined and where they land.
var appendData = new List<List<string>> { new List<string> { "Extra", "Data", "Here" } } as IGPALGrid<string>;
googleSheets.WithCredentials(credentials)
.WithSpreadsheet("TestSpreadsheet")
.WithSheet("RenamedTestSheet")
.WithData(appendData)
.AppendToCell("A4")
.WithInsertSeparator(", ")
.WithInsertPosition(0)
.InsertAtCell("C4")
.PrependToCell("B4");
FormatRange applies whatever WithFormatType/WithFormatValue (or WithNumberFormatValue) describe - bold text, currency formatting, and so on - to a cell range. CalculateSum and CalculateCount run aggregate formulas over the active read range. Finally, SaveTo(GPALFile) writes the contents of a read range straight to a local file using GPAL's file abstraction.
googleSheets
.WithFormatType(FormatType.Bold)
.WithFormatValue(true)
.FormatRange("A1:C1")
.WithFormatType(FormatType.NumberFormat)
.WithNumberFormatValue(NumberFormatType.CURRENCY)
.FormatRange("B2:B3");
string sumResult;
googleSheets.WithReadRange("B2:B3")
.CalculateSum(out sumResult);
GPALFile file = GPAL.FileFor("output.csv");
googleSheets.WithReadRange("A1:C3")
.SaveTo(file);
GPAL.GoogleSheets also supports DeleteSheet, ListSheets, and even uploading and deploying Apps Script with triggers (UploadScript, DeployScriptAsWebApp, CreateTrigger) for workflows that need automation inside the spreadsheet itself.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();