Spreadsheets zijn de lijm van veel bedrijfsprocessen: rapportages, voorraadlijsten, dashboards en ad-hoc-databases. Met de Sheets API in Python lees en schrijf je die data programmatisch. Je vult rapporten met verse cijfers, exporteert query-resultaten of gebruikt een sheet als simpele backend. Het is een van de meest dankbare API's om mee te beginnen.
In dit artikel bouw je lezen, schrijven en opmaken stap voor stap op.
De service opzetten
Voordat je waarden leest of schrijft, bouw je een service-object met geldige credentials. Voor server-naar-server-automatisering gebruik je doorgaans een service-account; voor scripts namens een gebruiker een OAuth-flow.
from google.oauth2.service_account import Credentials
from googleapiclient.discovery import build
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
creds = Credentials.from_service_account_file('key.json', scopes=SCOPES)
service = build('sheets', 'v4', credentials=creds)
SHEET_ID = 'jouw-spreadsheet-id'
Deel de sheet met je service-account
Een service-account heeft een eigen e-mailadres (eindigt op .iam.gserviceaccount.com). Deel de spreadsheet met dat adres, anders krijg je een 403-fout, ook al klopt je code. Voor alleen-lezen toegang volstaat de scope spreadsheets.readonly.
Waarden lezen
Je leest een bereik in A1-notatie, bijvoorbeeld Blad1!A1:D10.
resultaat = service.spreadsheets().values().get(
spreadsheetId=SHEET_ID, range='Blad1!A1:D10'
).execute()
rijen = resultaat.get('values', [])
Lege cellen worden weggelaten
Het resultaat is een lijst van lijsten: elke binnenste lijst is een rij. Lege cellen aan het einde van een rij worden weggelaten, dus controleer de lengte van elke rij voordat je een kolom opvraagt om een IndexError te voorkomen.
Waarden schrijven
Met update overschrijf je een bereik. De valueInputOption bepaalt of Google je invoer interpreteert.
body = {'values': [['Naam', 'Omzet'], ['Jansen BV', 15000]]}
service.spreadsheets().values().update(
spreadsheetId=SHEET_ID, range='Blad1!A1',
valueInputOption='USER_ENTERED', body=body
).execute()
USER_ENTERED versus RAW
Gebruik valueInputOption='USER_ENTERED' als je wilt dat Google formules en datums interpreteert zoals een gebruiker die zou typen. Kies RAW als je de waarden letterlijk wilt opslaan zonder interpretatie, bijvoorbeeld voor tekst die toevallig op een formule of datum lijkt.
Rijen toevoegen
Voor het loggen van data wil je vaak onderaan toevoegen zonder te overschrijven. Dat doet append.
service.spreadsheets().values().append(
spreadsheetId=SHEET_ID, range='Blad1!A1',
valueInputOption='USER_ENTERED',
insertDataOption='INSERT_ROWS',
body={'values': [['Nieuwe rij', 42]]}
).execute()
Met insertDataOption='INSERT_ROWS' schuift Google bestaande rijen op in plaats van ze te overschrijven. De API zoekt vanaf het opgegeven bereik naar de eerstvolgende lege rij onder je bestaande tabel.
Een rapportage-pijplijn
Een veelvoorkomend patroon is een sheet die elke nacht ververst wordt met data uit een bron. De stappen daarvoor zien er zo uit.
Nachtelijke ververs-pijplijn
- Haal verse data op uit je database of API.
- Wis het oude databereik met
values().clear(). - Schrijf de nieuwe data met
values().update(). - Pas eventueel opmaak toe met
batchUpdate(). - Plan dit dagelijks via een geplande taak (cron) of een Cloud Function met Cloud Scheduler.
Opmaak en structuur
Voor meer dan platte waarden gebruik je batchUpdate met een lijst van request-objecten. Daarmee voeg je bladen toe, bevries je rijen, kleur je cellen of voeg je voorwaardelijke opmaak toe.
Opmaak toepassen met batchUpdate
- Bouw een lijst van request-objecten op, elk met een bewerking.
- Verpak ze in een body met de sleutel
requests. - Roep
spreadsheets().batchUpdate()aan metspreadsheetIden de body. - Alle bewerkingen worden atomair in een keer toegepast: faalt er een, dan faalt het geheel.
Werk in batches, niet per cel
Honderden losse update-calls lopen snel tegen de rate limits aan en zijn traag. De Sheets API hanteert quota per minuut per gebruiker en per project. Met batchUpdate of een enkele update over een groot bereik bespaar je quota en tijd aanzienlijk. Bouw daarnaast een retry met exponentiele backoff in voor 429- en 503-antwoorden.
Veelgestelde vragen
Hoe vind ik de spreadsheet-ID?
Het is het lange deel in de URL tussen /d/ en /edit wanneer je de sheet in de browser opent.
Kan ik meerdere bereiken in een keer lezen?
Ja, gebruik values().batchGet() met meerdere ranges om in een enkele call meerdere bereiken op te halen. Dat scheelt round-trips en quota.
Hoe maak ik een nieuwe spreadsheet aan?
Roep spreadsheets().create() aan met een body die de titel en eventuele bladen bevat. In het antwoord krijg je de nieuwe spreadsheetId terug.
Werkt de Sheets API met grafieken?
Ja, via batchUpdate met een addChart-request voeg je grafieken programmatisch toe op basis van een databereik.
Waarom krijg ik een 403-fout terwijl mijn code klopt?
Vrijwel altijd is de sheet niet gedeeld met het juiste account. Deel hem met het e-mailadres van je service-account, of controleer of de OAuth-gebruiker schrijfrechten heeft.
Wat is het verschil tussen update en append?
update overschrijft exact het bereik dat je opgeeft. append zoekt de onderkant van je bestaande tabel op en voegt nieuwe rijen daaronder toe, ideaal voor logs.
Met de Sheets API in Python automatiseer je rapportages en datastromen die anders veel handmatig knip- en plakwerk zouden kosten.