How to export Google Calendar to Google Sheets
Google Calendar has no "export to Sheets" button, but there are four reliable ways to get your events into a spreadsheet. Which one is right depends on whether you need a one-off export or a report you'll run every week or month.
Quick comparison
| Method | Cost | Effort | Best for |
|---|---|---|---|
| 1. Built-in export (.ics) | Free | High, every time | A one-time backup |
| 2. Apps Script | Free | Medium (copy code once) | People comfortable with code |
| 3. Zapier / Make / IFTTT | Free tier, then paid | Medium | Logging new events as they're created |
| 4. A Sheets add-on | Free / paid tiers | Low | Recurring reports, e.g. hours per client |
Method 1: Google Calendar's built-in export
- On a computer, open Google Calendar and click the gear icon → Settings.
- Choose Import & export → Export. A .zip file downloads with one
.icsfile per calendar. - To export a single calendar instead, open Settings for my calendars, pick the calendar, and click Export calendar.
- Google Sheets can't open .ics files directly. Convert the file with an "ICS to CSV" converter, then use File → Import in Sheets.
Watch out for: the export contains all events ever, recurring events may appear once with a repeat rule instead of as separate rows, and times may be in UTC.
Method 2: Apps Script (free, repeatable)
In a Google Sheet, open Extensions → Apps Script, paste the code below, set your dates, and click Run. The first run asks for permission to read your calendar.
function exportCalendarToSheet() {
var start = new Date(2026, 8, 1); // months are 0-based: 8 = September
var end = new Date(2026, 9, 1); // exclusive
var cal = CalendarApp.getDefaultCalendar();
var rows = [['Title', 'Start', 'End', 'Hours', 'All day', 'Location']];
cal.getEvents(start, end).forEach(function (e) {
rows.push([
e.getTitle(),
e.getStartTime(),
e.getEndTime(),
e.isAllDayEvent() ? '' : (e.getEndTime() - e.getStartTime()) / 36e5,
e.isAllDayEvent(),
e.getLocation()
]);
});
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
sheet.getRange(1, 1, rows.length, rows[0].length).setValues(rows);
}
Unlike the .ics export, recurring events come out as separate rows, one per occurrence. To use a calendar other than your main one, replace getDefaultCalendar() with getCalendarsByName('Work')[0].
Method 3: Automation tools (Zapier, Make, IFTTT)
These services can add a row to a Google Sheet whenever a new event is created in Google Calendar ("New Event → Create Spreadsheet Row"). That's handy for keeping a running log, but it usually only captures events created after you set it up, and free tiers limit how many runs you get per month.
Method 4: A Google Sheets add-on
Add-ons run inside Sheets, so there's nothing to convert and no code to maintain. If your goal is a timesheet or billable hours per client, Calendar Timesheet goes a step further than a raw export:
- Maps events to clients with rules like
acme => Acme Corp | 120(keyword → client → hourly rate). - Rounds to 6, 15 or 30 minutes and skips all-day and declined events.
- Creates a detailed Timesheet tab and a Client Summary with hours and amount per client.
Free for up to 30 events per report. Try it free →
FAQ
Can I export only some events? With Apps Script, filter by title, for example if (e.getTitle().indexOf('Acme') === -1) return; inside the loop. The add-on does this with client rules.
Why are my times off by a few hours? Apps Script uses the script's time zone (Project Settings), while the sheet uses its own (File → Settings). Set both to your local time zone.
Can I export a shared calendar? Yes, as long as you can see its event details; use CalendarApp.getCalendarById('calendar-id').
Related: How to turn Google Calendar into a timesheet · Tracking billable hours with Google Calendar