How to export Google Calendar to Google Sheets
Google Calendar has no "export to spreadsheet" button. To get your events into Sheets with dates, times and hours you can count, you've got three options: the built-in export (awkward), a short Apps Script (free, a bit of setup), or an add-on. Here's how each one works and where it trips up.
Updated October 2026
Which method should I use?
| Built-in export | Apps Script | Add-on | |
|---|---|---|---|
| Set-up | 10 minutes, plus converting | 15 minutes, some code | 2 minutes |
| Pick a date range | No, it exports everything | Yes, in the code | Yes, from a menu |
| Hours per event | No | Yes | Yes, with rounding |
| Several calendars at once | One file each | With more code | Yes |
| Cost | Free | Free | Free for one calendar, this or last month |
Method 1: Google Calendar's own export
Calendar can export, but only as .ics files (the calendar format), not as a spreadsheet.
- In Google Calendar, open Settings → Import & export → Export. You get a ZIP with one
.icsfile per calendar. To export just one calendar, open its settings under Settings for my calendars and choose Export calendar. - Sheets can't open
.icsfiles. You need to run them through an ICS-to-CSV converter (there are free ones online, but you're uploading your whole calendar to them), then File → Import the CSV into Sheets.
Method 2: an Apps Script that lists events with hours
Apps Script is free and built into Sheets. The script below puts one row per event in a new tab, for a date range you choose, with the hours worked out. Unlike most scripts you'll find, it trims events that run past the start or end of the range, so a meeting overlapping midnight on the 1st doesn't count the hours from the month before.
- Open a spreadsheet and go to Extensions → Apps Script.
- Replace the code with this, change the two dates, and save:
// Lists your Google Calendar events between two dates in a new tab, with hours.
function exportCalendar() {
const start = new Date(2026, 8, 1); // 1 Sep 2026. Months count from 0, so 8 is September
const end = new Date(2026, 9, 1); // up to, but not including, 1 Oct 2026
const events = CalendarApp.getDefaultCalendar().getEvents(start, end);
const rows = [['Date', 'Start', 'End', 'Hours', 'Event']];
for (const e of events) {
if (e.isAllDayEvent()) continue;
if (e.getMyStatus() === CalendarApp.GuestStatus.NO) continue; // you declined it
// Only count the part of the event inside the range
const from = new Date(Math.max(e.getStartTime(), start));
const to = new Date(Math.min(e.getEndTime(), end));
// A title starting with = would otherwise be run as a formula
const title = /^[=+\-@]/.test(e.getTitle()) ? "'" + e.getTitle() : e.getTitle();
rows.push([from, from, to, (to - from) / 3600000, title]);
}
const sheet = SpreadsheetApp.getActive().insertSheet('Calendar ' + Date.now());
sheet.getRange(1, 1, rows.length, 5).setValues(rows);
sheet.getRange('A2:A').setNumberFormat('ddd d mmm yyyy');
sheet.getRange('B2:C').setNumberFormat('HH:mm');
sheet.getRange('D2:D').setNumberFormat('0.00');
}
- Press Run. The first time, Google asks you to allow access to your calendar and spreadsheet.
- For a calendar other than your main one, swap
getDefaultCalendar()forgetCalendarById('…'), using the calendar ID from its settings page.
Things the simple script doesn't handle, and that catch people out:
- Times an hour out. The script works in its own time zone (Apps Script → Project settings). If that doesn't match the spreadsheet's (File → Settings), every time is shifted.
- Overnight events land on the day they started, so a shift from 10pm to 6am puts all 8 hours on one date.
- The same meeting on two calendars is counted twice if you loop over several calendars.
- Out-of-office and working-location entries show up as events. You'd need the Calendar advanced service to tell them apart.
- Formula injection. Anyone can send you an invite, and a title like
=IMPORTXML(…)would run as a formula in your sheet. The line in the script above stops that; many copies of this script online don't.
Method 3: Calendar Timesheets & Billing (an add-on)
Calendar Timesheets & Billing is our add-on. It does what the script does, plus everything on that list: several calendars at once with duplicates removed, overnight events split at midnight, declined events and out-of-office blocks skipped, the spreadsheet's time zone used throughout, and event titles written as plain text.
- Install it from the Google Workspace Marketplace.
- In any spreadsheet, choose Extensions → Calendar Timesheets & Billing → Open timesheet builder.
- Tick your calendars, pick a date range (last month, this week, custom dates and so on) and press Build timesheet.
You get a Timesheet tab with one row per event per day (date, start, end, hours, event and calendar) and a Client summary tab. If you bill by the hour, you can also tag events by client and set rates; the timesheet guide covers that. It's free for one calendar, this month or last month. Pro is $5 a month or $39 a year for every calendar and any dates.
Get Calendar Timesheets & Billing
Common questions
Can I export Google Calendar to Excel?
Yes. Get the events into Google Sheets with any of the methods above, then File → Download → Microsoft Excel (.xlsx).
Can I export just one month?
Not with Calendar's own export, which always includes everything. The script takes start and end dates, and the add-on has presets for this and last week or month, plus custom dates.
Why are recurring meetings missing from my export?
In an .ics file a repeating meeting is one entry with a rule. Converters often turn that into a single row. The script and add-on list each meeting separately.
Can I export a calendar someone shared with me?
Yes, if they shared it with "see all event details". Calendars shared as "see only free/busy" have no titles to export.
Will it keep updating by itself?
The script runs when you press Run, or on a timer if you add one (Apps Script → Triggers). The add-on remembers your settings in the spreadsheet, so next month it's Extensions → Calendar Timesheets & Billing → Rebuild with saved settings.