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: TitleB: DateC: Start TimeD: End TimeE: DescriptionF: LocationG: Guest EmailH: 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

function createCalendarEvents() { 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 objects const startDate = new Date(date); startDate.setHours(new Date(startTime).getHours(), new Date(startTime).getMinutes()); const endDate = new Date(date); endDate.setHours(new Date(endTime).getHours(), new Date(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

function createAllDayEvents() { 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, new Date(date), { description: description || '' }); Logger.log(`All-day event created: ${title}`); } }

Add reminders to events

function createEventWithReminders() { const calendar = CalendarApp.getDefaultCalendar(); const start = new Date('2025-06-15T10:00:00'); const end = new Date('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 before Logger.log('Event created with reminders: ' + event.getId()); }

Create recurring events

function createRecurringEvent() { const calendar = CalendarApp.getDefaultCalendar(); const start = new Date('2025-05-01T09:00:00'); const end = new Date('2025-05-01T09:30:00'); // Recurrence: every weekday for 4 weeks const recurrence = CalendarApp.newRecurrence() .addWeeklyRule() .onlyOnWeekdays([ CalendarApp.Weekday.MONDAY, CalendarApp.Weekday.TUESDAY, CalendarApp.Weekday.WEDNESDAY, CalendarApp.Weekday.THURSDAY, CalendarApp.Weekday.FRIDAY, ]) .until(new Date('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.