Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 12515)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 12518)
@@ -3282,4 +3282,34 @@
     redirect_target = '@@export'
 
+class DatacenterExportJobContainerSelectStudents(ExportJobContainerJobConfig):
+    """Page that configures a students export job in datacenter.
+
+    """
+    grok.name('exportselected')
+    grok.context(IDataCenter)
+    redirect_target = '@@export'
+    grok.template('exportselected')
+    label = _('Configure student data export')
+
+    def update(self, START=None, students=None, exporter=None):
+        self._set_exporter_values()
+        if START is None:
+            return
+        try:
+            ids = students.replace(',', ' ').split()
+        except:
+            self.flash(sys.exc_info()[1])
+            self.redirect(self.url(self.redirect_target))
+            return
+        job_id = self.context.start_export_job(
+            exporter, self.request.principal.id, selected=ids)
+        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
+        self.context.logger.info(
+            '%s - selected students exported: %s, job_id=%s' %
+            (ob_class, exporter, job_id))
+        self.flash(_('Export of selected students started.'))
+        self.redirect(self.url(self.redirect_target))
+        return
+
 class FacultiesExportJobContainerJobConfig(ExportJobContainerJobConfig):
     """Page that configures a students export job in facultiescontainer.
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/exportselected.pt
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/exportselected.pt	(revision 12518)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/exportselected.pt	(revision 12518)
@@ -0,0 +1,26 @@
+<p i18n:translate="">
+  Here you can export student data for a small subset of students by entering
+  a list of student ids. The ids must be separated by whitespaces or commas.
+  You can also copy and paste parts of Excel or Calc columns.
+</p>
+
+<form i18n:domain="waeup.kofa" method="POST">
+  <label for="mode" i18n:translate="">
+    Exporter (Data Type)
+  </label>
+  <select id="exporter" name="exporter" class="form-control half" onclick="test()">
+    <option tal:repeat="item view/exporters"
+            tal:attributes="value python:item[1]">
+      <span tal:replace="python: item[0]">Students</span>
+    </option>
+  </select>
+  <br />
+  <label for="mode" i18n:translate="">
+    Student Ids
+  </label>
+  <input name="students" type="text" class="form-control" id="students"
+  <br /><br />
+  <input type="submit" name="START"  i18n:translate=""
+    value="Create CSV file"
+    class="btn btn-primary" />
+</form>
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/export.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/export.py	(revision 12515)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/export.py	(revision 12518)
@@ -190,4 +190,18 @@
         return query.query()
 
+    def get_selected(self, site, selected):
+        """Get set of selected students.
+
+        Returns a simple empty list or a list with `Student`
+        objects.
+        """
+        students = []
+        students_container = site.get('students', {})
+        for id in selected:
+            student = students_container.get(id, None)
+            if student:
+                students.append(student)
+        return students
+
     def export(self, values, filepath=None):
         """Export `values`, an iterable, as CSV file.
@@ -217,4 +231,11 @@
         """
         data = self.get_filtered(site, **kw)
+        return self.export(self.filter_func(data, **kw), filepath=filepath)
+
+    def export_selected(self,site, filepath=None, **kw):
+        """Export data for selected set of students.
+        """
+        selected = kw.get('selected', [])
+        data = self.get_selected(site, selected)
         return self.export(self.filter_func(data, **kw), filepath=filepath)
 
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 12515)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py	(revision 12518)
@@ -872,4 +872,8 @@
         """
 
+    def get_selected(site, selected):
+        """Get set of selected students.
+        """
+
     def export_student(student, filepath=None):
         """Export data for a given student.
@@ -877,4 +881,8 @@
 
     def export_filtered(site, filepath=None, **kw):
-        """Export filtered set of students.
-        """
+        """Export data for filtered set of students.
+        """
+
+    def export_selected(site, filepath=None, **kw):
+        """Export data for selected set of students.
+        """
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 12515)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 12518)
@@ -3313,4 +3313,30 @@
             )
 
+    def test_datacenter_export_selected(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open('http://localhost/app/datacenter/@@exportselected')
+        self.browser.getControl(name="exporter").value = ['students']
+        self.browser.getControl(name="students").value = 'K1000000'
+        self.browser.getControl("Create CSV file").click()
+        # When the job is finished and we reload the page...
+        job_id = self.wait_for_export_job_completed()
+        # ... the csv file can be downloaded ...
+        self.browser.open('http://localhost/app/datacenter/@@export')
+        self.browser.getLink("Download").click()
+        self.assertEqual(self.browser.headers['content-type'],
+            'text/csv; charset=UTF-8')
+        self.assertTrue(
+            'filename="WAeUP.Kofa_students_%s.csv' % job_id in
+            self.browser.headers['content-disposition'])
+        self.assertTrue(
+            'adm_code,clearance_locked,clr_code,date_of_birth,email,employer,'
+            'firstname,lastname,matric_number,middlename,nationality,'
+            'officer_comment,perm_address,personal_updated,phone,reg_number,'
+            'sex,student_id,suspended,suspended_comment,transcript_comment,'
+            'password,state,history,certcode,is_postgrad,current_level,'
+            'current_session\r\n'
+            ',1,,1981-02-04#,aa@aa.ng,,Anna,Tester,234,,,,,,'
+            '1234#,123,m,K1000000,0,,,{SSHA}' in self.browser.contents)
+
     def test_payment_dates(self):
         self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 12515)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 12518)
@@ -262,4 +262,20 @@
         return
 
+    def test_export_selected(self):
+        # we can export a filtered set of students (filtered by session/level)
+        self.setup_student(self.student)
+        self.app['students'].addStudent(self.student)
+        notify(grok.ObjectModifiedEvent(self.student))
+        exporter = StudentExporter()
+        exporter.export_selected(
+            self.app, self.outfile, selected=['A111111'])
+        result1 = open(self.outfile, 'rb').read()
+        exporter.export_selected(
+            self.app, self.outfile, selected=[])
+        result2 = open(self.outfile, 'rb').read()
+        self.assertTrue(self.std_csv_entry in result1)
+        self.assertFalse(self.std_csv_entry in result2)
+        return
+
     def test_export_filtered_by_dept(self):
         # we can export a set of students filtered by department
@@ -405,4 +421,21 @@
         return
 
+    def test_export_selected(self):
+        # we can export a filtered set of students (filtered by session/level)
+        self.setup_student(self.student)
+        self.app['students'].addStudent(self.student)
+        notify(grok.ObjectModifiedEvent(self.student))
+        exporter = StudentStudyCourseExporter()
+        exporter.export_selected(
+            self.app, self.outfile, selected=['A111111'])
+        result = open(self.outfile, 'rb').read()
+        self.assertEqual(
+            result,
+            'certificate,current_level,current_session,current_verdict,'
+            'entry_mode,entry_session,previous_verdict,student_id\r\n'
+
+            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
+            )
+        return
 
 
@@ -502,4 +535,23 @@
         exporter.export_filtered(
             self.student, self.outfile)
+        result = open(self.outfile, 'rb').read()
+        self.assertEqual(
+            result,
+            'gpa,level,level_session,level_verdict,total_credits,'
+            'validated_by,validation_date,'
+            'student_id,number_of_tickets,certcode\r\n'
+            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
+            )
+        return
+
+    def test_export_selected(self):
+        # we can export studylevels of a filtered set of students
+        self.setup_student(self.student)
+        self.app['students'].addStudent(self.student)
+        notify(grok.ObjectModifiedEvent(self.student))
+
+        exporter = StudentStudyLevelExporter()
+        exporter.export_selected(
+            self.app, self.outfile, selected=['A111111'])
         result = open(self.outfile, 'rb').read()
         self.assertEqual(
