How do you convert A1 Notation into GridRange for Google Spreadsheet API

Viewed 11

The Google Sheet API, in some cases, requires the expression of range using a GridRange, for example when you wish to format some cells, as shown here: https://developers.google.com/sheets/api/samples/formatting

However, I cannot find any conversion utility from A1 notation, e.g. Sheet2!A3:B4 into GridRange.

There are two difficulties, the first is knowing what sheetId corresponds to the named sheet and the second encoding the range into 0-based indices

1 Answers

Answering my own question. First you need a live lookup to discover the sheetId

In Kotlin:

import com.google.api.services.sheets.v4.Sheets

fun getSheetId(sheets: Sheets, spreadsheetId: String, sheetName: String): Int {
    val spreadsheet = sheets.spreadsheets().get(spreadsheetId).execute()
    val sheet = spreadsheet.sheets.firstOrNull { it.properties.title == sheetName }
    requireNotNull(sheet) {
        "Sheet $sheetName not found, only found these sheets: " +
                spreadsheet.sheets.map { it.properties.title }.joinToString()
    }
    return sheet.properties.sheetId
}

Then to translate the coordinates I used a dependency from Apache POI. A better solution would be recode the 2 classes you need from there, since POI is big and brings other dependencies in turn you may not want:

import com.google.api.services.sheets.v4.Sheets
import com.google.api.services.sheets.v4.model.GridRange
import org.apache.poi.ss.util.CellRangeAddress
import org.apache.poi.ss.util.CellReference

fun convertToGridRange(sheets: Sheets, spreadsheetId: String, range: String): GridRange {
    val sheetName = CellReference(range.substringBefore(":")).sheetName
    val cr = CellRangeAddress.valueOf(range)
    return GridRange().apply {
        sheetId = getSheetId(sheets, spreadsheetId, sheetName)
        startRowIndex = cr.firstRow
        startColumnIndex = cr.firstColumn
        endRowIndex = cr.lastRow + 1
        endColumnIndex = cr.lastColumn + 1
    }
}

Unit Test

@Test
fun convertToGridRangeTest() {
    val gr = googleSpreadsheetService.convertToGridRange(TEST_SHEET, "Sheet2!A3:B4")
    gr.sheetId shouldBe 413044831
    gr.startRowIndex shouldBe 2
    gr.startColumnIndex shouldBe 0
    gr.endRowIndex shouldBe 4
    gr.endColumnIndex shouldBe 2
}

Dependencies are:

Related