Create ICS Calendar File in Java/Spring Boot
An ICS file is an iCalendar file having .ics extension. An ICS file contains plain text with calendar event details such as starting and ending time of events, event description, etc.
In this example, we will use iCal4j to create an ICS file in Java. iCal4j is a Java library used to read and write iCalendar data streams. The iCalendar standard provides a common data format for storing information about calendar specific events data. The iCalendar standard supports many calendaring tools, such as Outlook, Lotus Notes, Apple's iCal, and Google Calendar.
Gradle Dependency
implementation group: 'org.mnode.ical4j', name: 'ical4j', version: '4.0.0-alpha8'
Maven Dependency
Find the latest version of iCal4j library in the iCal4j Maven Repository .
Here is a snippet of Java code for creating .ics file:
/* Event start and end time in milliseconds */
Long startDateTimeInMillis = 1615956275000L;
Long endDateTimeInMillis = 1615959875000L;
java.util.Calendar calendarStartTime = new GregorianCalendar();
calendarStartTime.setTimeInMillis(startDateTimeInMillis);
// Time zone info
TimeZone tz = calendarStartTime.getTimeZone();
ZoneId zid = tz.toZoneId();
/* Generate unique identifier */
UidGenerator ug = new RandomUidGenerator();
Uid uid = ug.generateUid();
/* Create the event */
String eventSummary = "Happy New Year";
LocalDateTime start = LocalDateTime.ofInstant(calendarStartTime.toInstant(), zid);
LocalDateTime end = LocalDateTime.ofInstant(Instant.ofEpochMilli(endDateTimeInMillis), zid);
VEvent event = new VEvent(start, end, eventSummary);
event.getProperties().add(uid);
/* Create calendar */
Calendar calendar = new Calendar();
calendar.getProperties().add(new ProdId("-//Ben Fortuna//iCal4j 1.0//EN"));
calendar.getProperties().add(Version.VERSION_2_0);
calendar.getProperties().add(CalScale.GREGORIAN);
/* Add event to calendar */
calendar.getComponents().add(event);
/* Create a file */
String filePath = "mymeeting.ics";
FileOutputStream fout = null;
try {
fout = new FileOutputStream(filePath);
CalendarOutputter outputter = new CalendarOutputter();
outputter.output(calendar, fout);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ValidationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fout != null) {
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
mymeeting.ics
BEGIN:VCALENDAR
PRODID:-//Ben Fortuna//iCal4j 1.0//EN
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20210317T061623Z
DTSTART:20210317T102935
DTEND:20210317T112935
SUMMARY:Happy New Year
UID:261bcd89-30ca-4b12-b7c3-45ad90f76e09
END:VEVENT
END:VCALENDAR
Generating ICS File via Spring Boot REST API
Here is an example of a Spring Boot REST controller with an API to generate and download ICS File:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.model.component.VEvent;
import net.fortuna.ical4j.model.property.CalScale;
import net.fortuna.ical4j.model.property.ProdId;
import net.fortuna.ical4j.model.property.Uid;
import net.fortuna.ical4j.model.property.Version;
import net.fortuna.ical4j.util.RandomUidGenerator;
import net.fortuna.ical4j.util.UidGenerator;
@RestController
@RequestMapping(path = "/rest/api")
public class CalenderController {
@GetMapping(path = "/generate-calendar")
public ResponseEntity generateCalenderFile() {
/* Event start and end time in milliseconds */
Long startDateTimeInMillis = 1615956275000L;
Long endDateTimeInMillis = 1615959875000L;
java.util.Calendar calendarStartTime = new GregorianCalendar();
calendarStartTime.setTimeInMillis(startDateTimeInMillis);
// Time zone info
TimeZone tz = calendarStartTime.getTimeZone();
ZoneId zid = tz.toZoneId();
/* Generate unique identifier */
UidGenerator ug = new RandomUidGenerator();
Uid uid = ug.generateUid();
/* Create the event */
String eventSummary = "Happy New Year";
LocalDateTime start = LocalDateTime.ofInstant(calendarStartTime.toInstant(), zid);
LocalDateTime end = LocalDateTime.ofInstant(Instant.
ofEpochMilli(endDateTimeInMillis), zid);
VEvent event = new VEvent(start, end, eventSummary);
event.getProperties().add(uid);
/* Create calendar */
Calendar calendar = new Calendar();
calendar.getProperties().add(new ProdId("-//Ben Fortuna//iCal4j 1.0//EN"));
calendar.getProperties().add(Version.VERSION_2_0);
calendar.getProperties().add(CalScale.GREGORIAN);
/* Add event to calendar */
calendar.getComponents().add(event);
byte[] calendarByte = calendar.toString().getBytes();
Resource resource = new ByteArrayResource(calendarByte);
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=mycalendar.ics");
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
return ResponseEntity.ok().headers(header).contentType(MediaType.
APPLICATION_OCTET_STREAM)
.body(resource);
}
}