Google Sheets / Сменить формат ячейки если значения в ней совпадает с переменной
Есть необходимость менять визуальное отображение значения переменной в ячейке (фон заливки, жирность начертания или цвет отображения), если оно совпадает с установлены образцом. Conditional Formatting
Пробую разобраться с документацией, но чёт пока туго. Вот что удалось напечатать.
const {google} = require('googleapis');
const keys = require('./keys.json'); // доступы к API
const client = new google.auth.JWT(
keys.client_email,
null,
keys.private_key,
["https://www.googleapis.com/auth/spreadsheets"]
)
let testingName = "aaa"; // то по чем фильтруем, ищем совпадение
client.authorize(function (err, tokens){
if(err){
console.log(err);
return;
}else{
console.log('Connected');
colorize(client) // ф-ция разукрашка
}
})
///// Теоретически эта функция должна сейчас поменять фоновый цвет для ячейки A1 Но оно не срабатывает не знаю что не так
function colorize(cl){
const sheets = google.sheets({ version: "v4", cl });
const spreadsheetId = "19SXVyvV_58IDjwukm06OepvNOCWp5n2NJxBuNj9k4fU"; // Please set the Spreadsheet ID.
const ucfSelectedRowIndex = 1; // Please set more than 0.
const request = {
requests: [
{
"updateBorders": {
"range": {
"sheetId": spreadsheetId,
startRowIndex: ucfSelectedRowIndex - 1,
endRowIndex: ucfSelectedRowIndex,
startColumnIndex: 1, // Column "A"
endColumnIndex: 2 // Column "A"
},
format: {
backgroundColor: {red: 1, green: 0.4, blue: 0.4},
},
}
}
]
};
sheets.spreadsheets.batchUpdate(
{ spreadsheetId: spreadsheetId, requestBody: request, cl },
function(err, response) {
if (err) {
console.error(err);
return;
} else {
console.info(response);
console.log("Client Feedback Sent Col Values updated");
}
})
}
Подскажите, пожалуйста кто работает с данной API К сожалению приведенные примеры только для php как написать для nodejs не получается разобраться.
Ответы (1 шт):
Условное форматирование создается запросом addConditionalFormatRule
Примерно так выглядит отправка запроса:
res = await api.spreadsheets.batchUpdate({
spreadsheetId,
requestBody: {
requests: [
{
addConditionalFormatRule: {
rule: {
ranges: [
{
sheetId: 0,
startColumnIndex: 2,
endColumnIndex: 3,
}
],
booleanRule: {
condition: {
type: "TEXT_CONTAINS",
values: [{ userEnteredValue: "foo" }]
},
format: {
textFormat: {
bold: true,
foregroundColor: { blue: 1 }
},
backgroundColor: { red: 1, green: 1 }
}
}
},
index: 0
}
},
],
},
})
Значения для spreadsheetId и sheetId берем из адресной строки самой таблицы: spreadsheetId это хэш-строка, а sheetId это gid (для первого листа обычно равен 0).
В правиле указываем диапазоны ячеек (набор GridRange) и одно из двух правил - либо booleanRule, либо gradientRule (нам будет достаточно первого).
BooleanRule разбито на две части: необходимое условие condition и применяемый при его выполнении формат ячейки format. Возможные типы условий перечислены здесь (в примере использован TEXT_CONTAINS), а параметры форматирования здесь.
Вот полный код демонстрационной программы (используется легковесный пакет @googleapis/sheets).
При первом запуске в консоль выдается url страницы авторизации и ожидается ввод кода с последней страницы, после запроса токен сохраняется в файле token.json и последующие запуски используют его напрямую (если токен уже есть, можно скопировать его и не шаманить с командной строкой).
const fs = require('fs/promises')
const readline = require('readline/promises') // node 17+
const { sheets, auth } = require('@googleapis/sheets')
const { installed } = require('./credentials.json')
async function runSample(spreadsheetId) {
let client
try {
const { client_secret, client_id, redirect_uris } = installed
client = new auth.OAuth2(client_id, client_secret, redirect_uris[0])
} catch (error) {
console.log('Error loading client credentials file:', error)
return
}
try {
// Check if we have previously stored a token.
const token = await fs.readFile('token.json')
client.setCredentials(JSON.parse(token))
} catch (error) {
if (error.code === 'ENOENT') {
const token = await getNewToken(client)
client.setCredentials(token)
} else {
console.error(error)
return
}
}
const api = sheets({ version: "v4", auth: client })
res = await api.spreadsheets.batchUpdate({
spreadsheetId,
requestBody: {
requests: [
{
addConditionalFormatRule: {
rule: {
ranges: [
{
sheetId: 0,
startColumnIndex: 2,
endColumnIndex: 3,
}
],
booleanRule: {
condition: {
type: "TEXT_CONTAINS",
values: [{ userEnteredValue: "the" }]
},
format: {
textFormat: {
bold: true,
foregroundColor: { blue: 1 }
},
backgroundColor: { red: 1, green: 1 }
}
}
},
index: 0
}
}
]
},
})
console.log(res.data)
}
async function getNewToken(client) {
const authUrl = client.generateAuthUrl({
access_type: 'offline',
scope: 'https://www.googleapis.com/auth/spreadsheets',
})
console.log('Authorize this app by visiting this url:', authUrl)
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
const code = await rl.question('Enter the code from that page here: ')
rl.close()
try {
const { tokens } = await client.getToken(code)
// Store the token to disk for later program executions.
await fs.writeFile('token.json', JSON.stringify(tokens))
console.log("Token stored to `token.json`")
return tokens
} catch (error) {
console.error('\nError while trying to retrieve access token\n', error)
throw error
}
}
const spreadsheetId = '_________________________________________'
runSample(spreadsheetId)
Добавлю, что создание правил условного форматирования через api мало отличается от их создания непосредственно в таблице: каждое новое правило добавляется к предыдущим, а не заменяет его, если условие выполняется сразу в нескольких правилах, то срабатывает только самое первое. Порядок правил определяет значение поля index и изменить его можно запросом updateConditionalFormatRule, ну и конечно же правило можно удалить запросом deleteConditionalFormatRule. Правила не фиксируют формат при создании, а отслеживают изменение данных (и соответственно условия правила).
Если такое поведение вас в корне не устраивает, то можно пойти другим путем: первым запросом прочитать данные из таблицы, программно проанализировать их и сформировать данные для updateCells запроса.
Примерно так будет выглядеть запрос на выборочное форматирование ячеек:
res = await api.spreadsheets.batchUpdate({
spreadsheetId,
requestBody: {
requests: [
{
updateCells: {
range: {
sheetId: 0,
startColumnIndex: 2,
endColumnIndex: 3,
startRowIndex: 10,
endRowIndex: 14,
},
rows: [
{ values: { userEnteredFormat: { backgroundColor: { red: 1, green: 1 } } } },
{ values: null },
{ values: null },
{ values: { userEnteredFormat: { backgroundColor: { red: 1, green: 1 } } } },
],
fields: "userEnteredFormat.backgroundColor",
}
}
]
},
})
Здесь в диапазоне из четырех строк формат применяется только к первой и последней строке, а в строках со значением null цвет фона будет сброшен в исходное состояние.
