How to create Google Calendar events from Google Sheets
Short answer: Google Sheets cannot send rows to Google Calendar on its own. The free way is a short Apps Script: open Extensions → Apps Script, paste a script that calls CalendarApp.createEvent for each row, and run it. It works for a one-time copy. Run it again and you get every event twice, and it does not update or delete events when the sheet changes, unless you write that too. An add-on such as EventLane does the sync for you.
1. Set up the sheet
Whatever you use, start with one row per event and one column per field, with names in row 1. For the script below, a tab named Events with:
| A: Title | B: Start | C: End | |
|---|---|---|---|
| 2 | Front desk — Ana | 11/16/2026 9:00:00 | 11/16/2026 17:00:00 |
| 3 | Team training | 11/18/2026 10:00:00 | 11/18/2026 12:00:00 |
Start and End must be real date-time values, not text. If a cell is left-aligned, Sheets is treating it as text: use Format → Number → Date time.
2. The Apps Script way
- In the spreadsheet, open Extensions → Apps Script.
- Replace the code in the editor with the script below and click Save.
- Choose
createEventsin the function list and click Run. The first time, Google asks you to allow the script to manage your calendars.
function createEvents() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Events');
const rows = sheet.getDataRange().getValues(); // row 1 holds the column names
const calendar = CalendarApp.getDefaultCalendar();
for (let i = 1; i < rows.length; i++) {
const [title, start, end] = rows[i];
if (!title || !start) continue; // skip empty rows
calendar.createEvent(title, new Date(start), new Date(end));
}
}
Open Google Calendar: the events are there, in your main calendar. To use another calendar, replace getDefaultCalendar() with getCalendarById('…') and the calendar ID from that calendar’s settings.
3. Where the simple script goes wrong
- Duplicates on every run.
createEventalways makes a new event. Run the script again after adding one row, and every earlier row is created a second time. - Edits do not reach the calendar. Change a time in the sheet and the old event stays as it was. The script has no idea which event belongs to which row.
- Deleted rows leave their events behind. Nothing removes an event when its row goes.
- Time zones. A date-time cell reaches the script as a moment in time worked out in the spreadsheet’s time zone (File → Settings). If your calendar is set to a different zone, every event lands shifted, often by exactly an hour. Check that both zones match.
- All-day events and missing end times. The script needs a start and an end for every row. For an all-day event you have to call
createAllDayEventinstead, and decide in code which rows are which. - Wide access.
CalendarAppasks for access to all your calendars, not only the one the script writes to. - Limits. A script run stops after six minutes, and Google Calendar refuses new events for a while when one account creates a great many in a short time. A long sheet may need several runs, and with this script every run creates duplicates again.
4. Remember the event IDs
The usual fix is to write each event’s ID into the sheet and update the event on the next run instead of creating it again. Add a column D, Event ID, and use this version:
function syncEvents() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Events');
const rows = sheet.getDataRange().getValues(); // A Title, B Start, C End, D Event ID
const calendar = CalendarApp.getDefaultCalendar();
for (let i = 1; i < rows.length; i++) {
const [title, start, end, id] = rows[i];
if (!title || !start) continue;
const event = id ? calendar.getEventById(id) : null;
if (event) {
event.setTitle(title);
event.setTime(new Date(start), new Date(end));
} else {
const created = calendar.createEvent(title, new Date(start), new Date(end));
sheet.getRange(i + 1, 4).setValue(created.getId());
}
}
}
This stops the duplicates and carries edits over. It still leaves events behind when you delete a row, and copying a row copies its ID, so two rows then share one event. Each of those needs more code, and so does the time zone.
Google Forms: to create an event for each form response, link the form to a spreadsheet, then in Apps Script add a trigger (Triggers → Add trigger, event type On form submit) that runs a function like the one above for the new row.
5. With an add-on: EventLane
EventLane is our Google Sheets™ add-on for this job. It is not on Google Workspace Marketplace yet. It does what the scripts above leave to you:
- Each row keeps its event’s ID in an “EventLane ID” column, and each event carries a private tag. Running it again updates events, never duplicates them, and a copied row becomes a new event of its own.
- Edits in the sheet update their events, and deleted rows remove their events, if you leave that option on. It only ever touches events it created.
- A “9:00” in the sheet means 9:00 in the calendar’s time zone, or in the spreadsheet’s if you choose. A 22:00–06:00 night shift ends the next day.
- Rows without a time become all-day events. Location, description, guests, colours and reminders are columns you map in the panel.
- It asks Google for permission to manage events, not the wider permission to manage your calendars themselves.
- Manual Sync now is free, with no row limit. Pro, for $4.99 a month or $39 a year, syncs on edit, on Google Forms submit and every hour.
How to set it up: EventLane help.
Questions
Can Google Sheets add events to Google Calendar by itself?
Not without help. Sheets has no built-in Calendar export. You need a short Apps Script, a CSV file imported into Google Calendar, or an add-on.
Why does my script create duplicate events?
Because createEvent always makes a new event. A script that does not remember which rows it already synced creates every event again on each run. Store the event ID in a column and update the event instead.
Why are my events an hour off?
The date-time in the cell is worked out in the spreadsheet's time zone (File, Settings). If your calendar is set to another zone, every event shows up shifted. Set both to the same zone.
Can Google Forms responses create calendar events?
Yes. Link the form to a spreadsheet, then run a script on form submit, or point an add-on such as EventLane at the responses tab.