---
title: "Google Sheets com Python: ler e escrever planilhas com gspread"
url: "https://python.dev.br/blog/python-google-sheets-gspread/"
markdown_url: "https://python.dev.br/blog/python-google-sheets-gspread.MD"
description: "Aprenda a automatizar planilhas do Google Sheets com Python e gspread: configurar conta de serviço, ler e gravar dados, integrar com pandas, atualizar em lote, formatar células, lidar com cotas da API e proteger credenciais. Guia prático em português brasileiro com exemplos de relatórios compartilhados."
date: "2026-07-18"
author: "Equipe Python Brasil"
---

# Google Sheets com Python: ler e escrever planilhas com gspread

Aprenda a automatizar planilhas do Google Sheets com Python e gspread: configurar conta de serviço, ler e gravar dados, integrar com pandas, atualizar em lote, formatar células, lidar com cotas da API e proteger credenciais. Guia prático em português brasileiro com exemplos de relatórios compartilhados.


Quem já [automatiza planilhas Excel com OpenPyXL](/blog/python-e-excel-openpyxl/) esbarra cedo ou tarde em uma limitação real: o arquivo `.xlsx` é local. Quando mais de uma pessoa precisa ver o número atualizado — um time comercial, a contabilidade, um cliente — o Excel trocado por e-mail ou WhatsApp vira rapidly um pesadelo de versões. É aí que o **Google Sheets** brilha: ele é colaborativo por padrão, grátis, acessível de qualquer lugar e expõe uma API HTTP que o Python lê e escreve com facilidade.

A biblioteca **gspread** é o padrão de facto para falar com a Google Sheets API em Python. Com ela você lê dados, grava resultados de um [pipeline em pandas](/blog/introducao-ao-pandas/), dispara [relatórios por e-mail](/blog/python-para-automacao-de-emails/), monta [dashboards no Streamlit](/blog/criando-dashboards-com-streamlit/) com dados vivos e cria integrações de [CRM e marketing](/blog/python-automacao-crm-marketing/) sem depender de Zapier ou n8n. Este guia mostra o caminho completo, da configuração no Google Cloud até uma automação segura e pronta para produção.

## Google Sheets API vs. OpenPyXL: quando usar qual

A diferença fundamental é onde a planilha vive:

- **OpenPyXL** (e também [leitura/escrita de CSV](/blog/python-csv-leitura-escrita-arquivos/)) opera em **arquivos locais**. É rápido, não tem cota de API e funciona offline, mas só você enxerga o resultado enquanto não enviar o arquivo a alguém.
- **gspread / Google Sheets API** opera em **planilhas na nuvem**. Cada leitura e escrita é uma chamada HTTP sujeita a cotas, mas qualquer pessoa com acesso vê a atualização imediatamente.

Regra prática: use OpenPyXL para gerar relatórios que serão anexados ou versionados localmente, e gspread quando o dado precisa ser **compartilhado e editado em tempo real** por um time. Muitas vezes a melhor arquitetura combina os dois — processa em Python com pandas e publica o resumo em uma planilha do Google.

## Configurando a conta de serviço no Google Cloud

A Google Sheets API exige autenticação. Para automações em servidor, a opção correta é a **conta de serviço** (*service account*), porque ela não depende de um login humano e não expira.

No [Google Cloud Console](https://console.cloud.google.com/):

1. Crie um projeto (ou reutilize um existente).
2. Em **APIs e serviços → Biblioteca**, ative a **Google Sheets API** *e* a **Google Drive API** (a segunda é necessária para a gspread localizar planilhas pelo nome).
3. Em **APIs e serviços → Credenciais**, crie uma **Conta de serviço** e, na aba **Chaves**, adicione uma chave do tipo **JSON**. O Google vai baixar um arquivo como `robosheets-abc123.json`.
4. Abra a planilha que quer automatizar no Google Sheets, clique em **Compartilhar** e adicione o e-mail da conta de serviço (algo como `robosheets@meu-projeto.iam.gserviceaccount.com`) como **Editor**.

Esse último passo é o que mais escapa iniciantes: sem compartilhar a planilha com a conta de serviço, a API retorna `SpreadsheetNotFound` ou erro 403 mesmo com a credencial certa.

## Protegendo a credencial

O arquivo JSON baixado é uma chave privada — **nunca faça commit dele**. Use [variáveis de ambiente com python-dotenv](/blog/python-dotenv-env-vars-config/) para guardar o caminho:

```bash
pip install gspread python-dotenv pandas
```

Crie um `.env` (e adicione `.env` e `credentials*.json` ao `.gitignore`):

```ini
GOOGLE_CREDENTIALS_FILE=/home/voce/secrets/robosheets-abc123.json
SPREADSHEET_ID=1AbC...seu-id...xyz
```

A mesma recomendação vale para [uploads e secrets em cloud](/blog/python-s3-r2-minio-upload-arquivos/): mantenha credenciais fora do repositório.

## Primeiro script: lendo dados

Com a credencial no lugar, ler uma aba inteira leva quatro linhas:

```python
import os
import gspread
from dotenv import load_dotenv

load_dotenv()

gc = gspread.service_account(filename=os.environ["GOOGLE_CREDENTIALS_FILE"])
planilha = gc.open_by_key(os.environ["SPREADSHEET_ID"])
aba = planilha.worksheet("Vendas")

registros = aba.get_all_records()  # primeira linha vira o nome das colunas
for r in registros:
    print(r["Produto"], r["Quantidade"], r["Preço"])
```

Também é possível abrir pelo nome com `gc.open("Minha Planilha")` ou pela URL com `gc.open_by_url(...)`. Para acessar células específicas, use `aba.acell("B2").value` ou `aba.cell(row=2, col=2).value`.

## Escrevendo e atualizando valores

Gravar é tão direto quanto ler:

```python
# Atualizar uma célula
aba.update_acell("D2", 42)

# Atualizar um intervalo (lista de listas: linha → coluna)
aba.update("A1", [["Produto", "Total"], ["Notebook", 3500], ["Mouse", 250]])

# Adicionar linhas no final
aba.append_row(["Teclado", 18, 129.90])
aba.append_rows([
    ["Monitor", 12, 1899.00],
    ["Headset", 30, 199.90],
])
```

Prefira `update` com intervalos grandes e `append_rows` em vez de chamar `append_row` em loop — menos requisições, menos risco de bater na cota por minuto.

## Integração com pandas

A ponte mais útil do dia a dia é converter uma aba diretamente em `DataFrame`:

```python
import pandas as pd

df = pd.DataFrame(aba.get_all_records())
df["Total"] = df["Quantidade"] * df["Preço"]

# Publica o resultado de volta, começando em uma aba nova
resumo = planilha.add_worksheet(title="Resumo", rows=1, cols=2)
resumo.update(
    "A1",
    [df.columns.tolist()] + df.values.tolist(),
)
```

Para preservar tipos e cabeçalho com mais cuidado, instale o pacote `gspread-dataframe` e use `set_with_dataframe(resumo, df)`.

## Operações em lote e formatação

A gspread expõe `batch_update` para gravar vários intervalos de uma vez e `format` para estilizar células — útil para destacar cabeçalhos ou pintar valores fora da meta:

```python
aba.batch_update([
    {"range": "A1:C1", "values": [["Produto", "Quantidade", "Preço"]]},
    {"range": "E1:E3", "values": [["Status"], ["OK"], ["OK"]]},
])

aba.format("A1:C1", {
    "textFormat": {"bold": True},
    "backgroundColor": {"red": 0.19, "green": 0.41, "blue": 0.60},
    "horizontalAlignment": "CENTER",
})
```

Em planilhas com milhares de células, sempre prefira `batch_update` e `get_all_values`/`get_all_records` a muitas chamadas individuais — além de mais rápido, isso evita estourar as [cotas da API](https://developers.google.com/sheets/api/limits) (300 leituras e 300 escritas por minuto na camada gratuita).

## Automação brasileira de ponta a ponta

O cenário mais comum: um script roda todo dia, busca dados em uma [API pública brasileira](/blog/apis-publicas-brasileiras-python/), calcula indicadores com pandas e publica o resumo em uma planilha compartilhada. Para evitar confusão de fuso, registre a atualização com [datas e horas em zoneinfo](/blog/datas-e-horas-python-datetime-zoneinfo/):

```python
from datetime import datetime, timezone, timedelta
from zoneinfo import ZoneInfo

brt = ZoneInfo("America/Sao_Paulo")
agora = datetime.now(brt).strftime("%d/%m/%Y %H:%M:%S")
aba.update_acell("G1", f"Atualizado em {agora}")
```

Agende a execução com `cron`, GitHub Actions ou um orquestrador como o [Airflow](/blog/airflow-python-orquestracao-pipelines/). Se o resultado precisa chegar também por mensageria, combine com [integração com a API do WhatsApp](/blog/python-e-whatsapp-api-automacao/) ou [bots de Telegram](/blog/criando-bots-telegram-python/).

## Boas práticas e armadilhas

- **Cotas e retentativas:** a gspread já implementa retentativas com *backoff* para erros 429, mas vale reduzir o número de chamadas com operações em lote.
- **Tipos de dado:** a Sheets API grava números e fórmulas quando a célula está no formato certo; ao importar de volta com `get_all_records`, valores numéricos vêm como `int`/`float` e vazios como string vazia — limpe antes de processar.
- **Vírgula decimal brasileira:** a interface em português mostra `1.234,56`, mas a API trafega com `1234.56`. Formate só na apresentação.
- **Tratamento de erros:** capture `gspread.exceptions.SpreadsheetNotFound`, `WorksheetNotFound` e `APIError` para mensagens claras.
- **Ambiente isolado:** rode tudo dentro de um [ambiente virtual](/blog/virtual-environments-python/) para não misturar dependências.

## Conclusão

Google Sheets com Python via gspread fecha um ciclo poderoso: dados processados em pandas viram números vivos em uma planilha que o time inteiro consulta, sem ninguém precisar abrir um arquivo anexado. Para quem trabalha com [automação de escritório](/blog/automatizacao-com-python/), analytics ou [transição de carreira para dados](/carreira/python-freelancer/), dominar essa integração é um diferencial concreto — é o tipo de projeto que resolve dor real em qualquer empresa brasileira e brilha em portfólio e entrevistas.

Comece pelo script de leitura deste guia, compartilhe uma planilha de teste com a sua conta de serviço e, em poucos minutos, você terá um pipeline de dados colaborativo rodando de verdade.
