diff --git a/.gitignore b/.gitignore
index 5f846bdc44dc42490d2b3c88d19b3dc0f50533e3..9eca034d61d74660f3cb2fe12292148b84f5e15c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,10 @@ smash/~/
 
 # Disable python bytecode
 *.pyc
+#vim swap files
+*.swp
+#vim backup files
+*~
 
 # Disable local developer settings
 local_settings.py
diff --git a/requirements.txt b/requirements.txt
index fa5a7c14be038ab020a18cf2c7e4201737d76b11..67644e195dd3578eaeba9c357afff56d394170f0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,4 +8,8 @@ python-docx==0.8.6
 django-cleanup==0.4.2
 django_cron==0.5.0
 django-two-factor-auth==1.6.1
-nexmo
\ No newline at end of file
+nexmo
+django-excel==0.0.9
+pyexcel-xls==0.5.0
+pyexcel==0.5.3
+
diff --git a/smash/web/static/css/export.css b/smash/web/static/css/export.css
new file mode 100644
index 0000000000000000000000000000000000000000..ffab23233d813aab070b92753890709a998839ed
--- /dev/null
+++ b/smash/web/static/css/export.css
@@ -0,0 +1,9 @@
+.cell {
+    display: table-cell;
+    border-bottom: 1px solid black;
+    border: 1px solid #BBBBBB;
+    padding:4px;
+    text-align: center;
+    vertical-align: middle;
+
+}
diff --git a/smash/web/templates/export/index.html b/smash/web/templates/export/index.html
index 8c0501149511bc3e7704588e508de4128629503f..a4e8aef298bbe802d4997a9f54f325ca03b8d0c5 100644
--- a/smash/web/templates/export/index.html
+++ b/smash/web/templates/export/index.html
@@ -3,6 +3,7 @@
 
 {% block styles %}
     {{ block.super }}
+    <link rel="stylesheet" href="{% static 'css/export.css' %}">
 {% endblock styles %}
 
 {% block ui_active_tab %}'export'{% endblock ui_active_tab %}
@@ -18,15 +19,21 @@
 {% block maincontent %}
 
     <div>
-        <a href="{% url 'web.views.export_to_csv' 'subjects' %}" class="btn btn-app">
-            <i class="fa fa-download"></i>
-            Subjects
-        </a>
-        <br/>
-        <a href="{% url 'web.views.export_to_csv' 'appointments' %}" class="btn btn-app">
-            <i class="fa fa-download"></i>
-            Appointments
-        </a>
+        <h3>Subjects</h3>
+        <ul>
+            <li><a href="{% url 'web.views.export_to_excel' 'subjects' %}"><i class="fa fa-file-excel-o"></i> XLS -
+                Excel</a>
+            </li>
+            <li><a href="{% url 'web.views.export_to_excel' 'appointments' %}"><i class="fa fa-file-text-o"></i> CSV -
+                Text based</a></li>
+        </ul>
+        <h3>Appointments</h3>
+        <ul>
+            <li><a href="{% url 'web.views.export_to_csv' 'subjects' %}"><i class="fa fa-file-excel-o"></i> XLS -
+                Excel</a></li>
+            <li><a href="{% url 'web.views.export_to_csv' 'appointments' %}"><i class="fa fa-file-text-o"></i> CSV -
+                Text based</a></li>
+        </ul>
     </div>
 
     <div class="box-body">
diff --git a/smash/web/templates/visits/add.html b/smash/web/templates/visits/add.html
index 9e03dbec7d16943bfdcbca5cb129b6f1f25d76d4..749641be57b7d9c1e4160a5d7457fff0cbfa5fed 100644
--- a/smash/web/templates/visits/add.html
+++ b/smash/web/templates/visits/add.html
@@ -25,12 +25,6 @@
         <a href="{% url 'web.views.visits' %}" class="btn btn-block btn-default">Cancel</a>
     </div>
 
-    {% comment %}
-    <div class="box-header with-border">
-        <h3 class="box-title">Details of a visit</h3>
-    </div>
-    {% endcomment %}
-
     <form method="post" action="" class="form-horizontal">
         {% csrf_token %}
 
diff --git a/smash/web/tests/test_view_export.py b/smash/web/tests/test_view_export.py
index 1fc16657a5eb6e098f98869f2ca881c9e2d6ac14..f15c2cf439a9012999ff91ef88a9fc1e928a0679 100644
--- a/smash/web/tests/test_view_export.py
+++ b/smash/web/tests/test_view_export.py
@@ -6,12 +6,22 @@ from . import LoggedInTestCase
 
 
 class TestExportView(LoggedInTestCase):
-    def test_export_subjects(self):
+    def test_export_subjects_to_csv(self):
         create_subject()
         response = self.client.get(reverse('web.views.export_to_csv', kwargs={'data_type': "subjects"}))
         self.assertEqual(response.status_code, 200)
 
-    def test_export_appointments(self):
+    def test_export_appointments_to_csv(self):
         create_appointment()
         response = self.client.get(reverse('web.views.export_to_csv', kwargs={'data_type': "appointments"}))
         self.assertEqual(response.status_code, 200)
+
+    def test_export_subjects_to_excel(self):
+        create_subject()
+        response = self.client.get(reverse('web.views.export_to_excel', kwargs={'data_type': "subjects"}))
+        self.assertEqual(response.status_code, 200)
+
+    def test_export_appointments_to_excel(self):
+        create_appointment()
+        response = self.client.get(reverse('web.views.export_to_excel', kwargs={'data_type': "appointments"}))
+        self.assertEqual(response.status_code, 200)
diff --git a/smash/web/urls.py b/smash/web/urls.py
index c19857fc45b4fee3f2623fa800390c1d204c1025..a2e1a0191019f89ae7f1db70d641c63c9e2fe171 100644
--- a/smash/web/urls.py
+++ b/smash/web/urls.py
@@ -160,7 +160,8 @@ urlpatterns = [
     ####################
 
     url(r'^export$', views.export.export, name='web.views.export'),
-    url(r'^export/(?P<data_type>[A-z]+)$', views.export.export_to_csv, name='web.views.export_to_csv'),
+    url(r'^export/csv/(?P<data_type>[A-z]+)$', views.export.export_to_csv, name='web.views.export_to_csv'),
+    url(r'^export/xls/(?P<data_type>[A-z]+)$', views.export.export_to_excel, name='web.views.export_to_excel'),
 
     ####################
     #       CONFIGURATION     #
diff --git a/smash/web/views/export.py b/smash/web/views/export.py
index e5a250536e5d39f6e5c38ddc77623011de253d53..359386c2552b4bd0c7e8afd46bb2353beba5917e 100644
--- a/smash/web/views/export.py
+++ b/smash/web/views/export.py
@@ -1,6 +1,7 @@
 # coding=utf-8
 import csv
 
+import django_excel as excel
 from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse
 
@@ -24,7 +25,23 @@ def export_to_csv(request, data_type="subjects"):
         return e500_error(request)
     writer = csv.writer(response, quotechar=str(u'"'), quoting=csv.QUOTE_ALL)
     for row in data:
-        writer.writerow(row)
+        writer.writerow([s.encode("utf-8") for s in row])
+
+    return response
+
+
+@login_required
+def export_to_excel(request, data_type="subjects"):
+    filename = data_type + '-' + get_today_midnight_date().strftime("%Y-%m-%d") + ".xls"
+    if data_type == "subjects":
+        data = get_subjects_as_array()
+    elif data_type == "appointments":
+        data = get_appointments_as_array()
+    else:
+        return e500_error(request)
+
+    response = excel.make_response_from_array(data, 'xls', file_name=filename)
+    response['Content-Disposition'] = 'attachment; filename="' + filename + '"'
 
     return response
 
@@ -46,8 +63,11 @@ def get_subjects_as_array():
     for subject in subjects:
         row = []
         for field in subject_fields:
-            row.append(getattr(subject, field.name))
-        result.append([unicode(s).replace("\n", ";").replace("\r", ";").encode("utf-8") for s in row])
+            cell = getattr(subject, field.name)
+            if cell is None:
+                cell = ""
+            row.append(cell)
+        result.append([unicode(s).replace("\n", ";").replace("\r", ";") for s in row])
     return result
 
 
@@ -69,15 +89,18 @@ def get_appointments_as_array():
     appointments = Appointment.objects.order_by('-datetime_when')
 
     for appointment in appointments:
-        row = [appointment.visit.subject.nd_number, appointment.visit.subject.last_name,
-               appointment.visit.subject.first_name, appointment.visit.follow_up_title()]
+        if appointment.visit is not None:
+            row = [appointment.visit.subject.nd_number, appointment.visit.subject.last_name,
+                   appointment.visit.subject.first_name, appointment.visit.follow_up_title()]
+        else:
+            row = ["---", "---", "---", "---"]
         for field in appointments_fields:
             row.append(getattr(appointment, field.name))
         type_string = ""
         for appointment_type in appointment.appointment_types.all():
             type_string += appointment_type.code + ","
         row.append(type_string)
-        result.append([unicode(s).replace("\n", ";").replace("\r", ";").encode("utf-8") for s in row])
+        result.append([unicode(s).replace("\n", ";").replace("\r", ";") for s in row])
     return result