Create Google Calendar Events from Google Sheets Data Using Apps Script
If you manage events, schedules, or bookings in a spreadsheet, you can push them directly to Google Calendar with a single script run — no copy-pasting required.
Sheet structure
Set up your sheet with these columns:
A: Title
B: Date
C: Start Time
D: End Time
E: Description
F: Location
G: Guest Email
H: Created?
Column H is a flag the script will set to "Yes" after creating each event, so it doesn't create duplicates on re-runs.
Create events from the sheet
functioncreateCalendarEvents(){const sheet =SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();const data = sheet.getDataRange().getValues();const calendar =CalendarApp.getDefaultCalendar();let created =0;for(let i =1; i < data.length; i++){const[title, date, startTime, endTime, description,location, guestEmail, alreadyCreated]= data[i];if(alreadyCreated ==='Yes')continue;if(!title ||!date)continue;// Combine date and time into Date objectsconst startDate =newDate(date); startDate.setHours(newDate(startTime).getHours(),newDate(startTime).getMinutes());const endDate =newDate(date); endDate.setHours(newDate(endTime).getHours(),newDate(endTime).getMinutes());const options ={description: description ||'',location:location||'',};if(guestEmail){ options.guests= guestEmail; options.sendInvites=true;}const event = calendar.createEvent(title, startDate, endDate, options);Logger.log(`Created: ${title} (${event.getId()})`);// Mark as created sheet.getRange(i +1,8).setValue('Yes'); created++;}Logger.log(`Done. Created ${created} event(s).`);}
Create all-day events
functioncreateAllDayEvents(){const sheet =SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();const data = sheet.getDataRange().getValues();const calendar =CalendarApp.getDefaultCalendar();for(let i =1; i < data.length; i++){const[title, date,,, description]= data[i];if(!title ||!date)continue; calendar.createAllDayEvent(title,newDate(date),{description: description ||''});Logger.log(`All-day event created: ${title}`);}}
Add reminders to events
functioncreateEventWithReminders(){const calendar =CalendarApp.getDefaultCalendar();const start =newDate('2025-06-15T10:00:00');const end =newDate('2025-06-15T11:00:00');const event = calendar.createEvent('Team Standup', start, end,{description:'Weekly team standup meeting.',guests:'[email protected],[email protected]',sendInvites:true,}); event.addEmailReminder(60);// Email 60 minutes before event.addPopupReminder(10);// Popup 10 minutes beforeLogger.log('Event created with reminders: '+ event.getId());}
Create recurring events
functioncreateRecurringEvent(){const calendar =CalendarApp.getDefaultCalendar();const start =newDate('2025-05-01T09:00:00');const end =newDate('2025-05-01T09:30:00');// Recurrence: every weekday for 4 weeksconst recurrence =CalendarApp.newRecurrence().addWeeklyRule().onlyOnWeekdays([CalendarApp.Weekday.MONDAY,CalendarApp.Weekday.TUESDAY,CalendarApp.Weekday.WEDNESDAY,CalendarApp.Weekday.THURSDAY,CalendarApp.Weekday.FRIDAY,]).until(newDate('2025-05-30')); calendar.createEventSeries('Daily Standup', start, end, recurrence);Logger.log('Recurring event series created.');}
Tips
When combining date and time from separate cells, be careful with timezone offsets — test with a few rows before running on your full dataset.
Use the "Created?" column flag pattern to make your script safely re-runnable without duplicates.
sendInvites: true sends actual calendar invitations to guests — use carefully in production environments.
For large datasets, add execution time guards to avoid hitting the 6-minute limit.