How to use Python to create an iCalendar file from a Word table

One of the great things with programming is that you can automate things that is boring. As a student I often get schedules in the form of Word documents. I prefer to have all my activities in a calendar and used to manually put every time in a course into my calendar. Today I got a new schedule and thought: I could probably do this using Python.

After some searching around on the Internet I found the Python packages python-docx and iCalendar. In this post I will show you how to use these to packages to create an iCalender file that can be loaded in to a lot of available calendars.

Installing python-docx & iCalendar

Both Python packages can be installed using pip:

pip install python-docx icalendar

In the example code I used a table from a Word document containing 4 columns. It is a pretty simple example but in the first column store the date, the second the time, third the room (location), and the last the activity of the event (e.g., lecture).

Schedule

Extracting a table from  a Word Document

In the first code chunk, below, we start by importing the needed modules. Apart from using Document from python-docx, Calendar and Event from iCalendar, we are going to use datetime from datetime. Datetime is used to store the date in a format that icalendar “likes”.

from datetime import datetime
from docx import Document
from icalendar import Calendar, Event

document = Document('course_schedule.docx')
table = document.tables[0]

data = []
keys = {}

for i, row in enumerate(table.rows):
    text = (cell.text for cell in row.cells)

    if i == 0:
        keys = tuple(text)
        continue

    row_data = dict(zip(keys, text))

In the next chunk of code (in the same loop as above) we split the date and time. We do this since due to the formatting of the date and time in the example (“5/4” and “9-12). As previously mentioned the date need to be formatted in a certain way (e.g., using Pythons datetime). In the table from the Word document, some of the events are deadlines and, thus, have no set time. Therefore, we need to see if we have a time to use. If not, we set the time to 17:00-17:01. There is probably a better way to do this but this will do for now. The last line adds each event (as a Python dictionary) to our list containing all data.

e_date = row_data['Date'].split('/')
    e_time = row_data['Time'].split('-')

    if len(e_time) > 1:

        row_data[u'dtstart'] = datetime(2017, int(e_date[1]), int(e_date[0]),
                                       int(e_time[0]), 0, 0)
        row_data[u'dtend'] = datetime(2017, int(e_date[1]), int(e_date[0]),
                                     int(e_time[1]), 0, 0)

    else:
        row_data[u'dtstart'] = datetime(2017, int(e_date[1]), int(e_date[0]),
                                        17,1, 0)
        row_data[u'dtend'] = datetime(2017, int(e_date[1]), int(e_date[0]),
                                      17 ,0,0)

    data.append(row_data)

Creating the iCalendar file

Now that we have a list of dictionaries containing our lectures/seminars (one for each dictionary) we can use iCalendar to create the calendar. First we create the calendar object and the continue with looping through our list of dictionaries. In the loop we create an event and add the information. In the example here we use the activity as both summary and description but we could have had a summary of the activity and a more detailed description if we’d liked.

The crucial parts, may be, are the ‘dtstart’ and ‘dtend’. This is the starting time and ending time of the event (e.g., a lecture). We continue to add the location (e.g., the room of the event) and add the event to our calender. Finally, we create a file (‘schedule.ics’), write the calender to the file, and close the file.

cal = Calendar()

for row in data:
    event = Event()
        
    event.add('summary', row['Activity'])
    event.add('dtstart', row['dtstart'])
    event.add('dtend', row['dtend'])
    event.add('description', row['Activity'])
    event.add('location', row['Room'])
    cal.add_component(event)

f = open('course_schedule.ics', 'wb')
f.write(cal.to_ical())
f.close()

Now we have our iCalendar file (course_schedule.ics) and can load it into our calender software. I typically use Lightning (a calendar addon for Thunderbird). To open the iCalendar file we created using Python go to File, Open, and Calendar File. Finally select the your iCalendar file:

Loading iCalendar file created from Word table into LightningAfter you done that your new schedule should be loaded into Lightning. Your schedule will be loaded as a separate calendar. As you can see in the image below your lecture and computer labs will show up.

In this post, we learned how to use Python (python-docx) to extract a schedule from a table in a Word Document (.docx). We used the data to create an iCalendar file that we can load into many Calendar applications (e.g., Google, Lightning).

The post How to use Python to create an iCalendar file from a Word table appeared first on Erik Marsja.