diff --git a/src/main/java/org/olat/core/util/pdf/PdfDocument.java b/src/main/java/org/olat/core/util/pdf/PdfDocument.java
new file mode 100644
index 0000000000000000000000000000000000000000..16ff65731457179975e7ed70db7783836b914ce6
--- /dev/null
+++ b/src/main/java/org/olat/core/util/pdf/PdfDocument.java
@@ -0,0 +1,216 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.core.util.pdf;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.jempbox.xmp.XMPMetadata;
+import org.apache.jempbox.xmp.XMPSchemaBasic;
+import org.apache.jempbox.xmp.XMPSchemaDublinCore;
+import org.apache.jempbox.xmp.XMPSchemaPDF;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDDocumentInformation;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDMetadata;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+
+/**
+ * 
+ * Initial date: 12.02.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class PdfDocument {
+	
+	protected PDFont font = PDType1Font.HELVETICA;
+	protected float marginTopBottom = 72.0f;
+	protected float marginLeftRight = 72.0f;
+	protected float lineHeightFactory = 1.5f;
+	protected float width;
+	
+	protected PDDocument document;
+	protected PDPage currentPage;
+	protected PDPageContentStream currentContentStream;
+	
+	protected float currentY;
+	
+	public PdfDocument() throws IOException {
+		document = new PDDocument();
+	}
+
+	public void close() throws IOException {
+		document.close();
+	}
+
+	public PDPage addPage() throws IOException {
+		if(currentContentStream != null) {
+			currentContentStream.close();
+		}
+
+		PDPage page = new PDPage();
+        document.addPage(page);
+        currentPage = page;
+        currentContentStream = new PDPageContentStream(document, currentPage);
+        
+        PDRectangle mediabox = currentPage.findMediaBox();
+        width = mediabox.getWidth() - 2 * marginLeftRight;
+        currentY = mediabox.getUpperRightY() - marginTopBottom;
+        return page;
+	}
+	
+	public void closePage() throws IOException {
+		if(currentContentStream != null) {
+			currentContentStream.close();
+		}
+	}
+	
+    public void addText(String text, float fontSize)
+    throws IOException {
+        currentContentStream.beginText();
+        currentContentStream.setFont(font, fontSize);
+        currentContentStream.moveTextPositionByAmount(marginLeftRight, currentY);
+        currentContentStream.drawString(text);
+        currentContentStream.endText();
+        
+        float leading = lineHeightFactory * fontSize;
+        currentY -= leading; 
+    }
+
+    public void addParagraph(String text, float fontSize, float width)
+    throws IOException {
+    	
+        float leading = lineHeightFactory * fontSize;
+
+        List<String> lines = new ArrayList<String>();
+        int lastSpace = -1;
+        while (text.length() > 0) {
+            int spaceIndex = text.indexOf(' ', lastSpace + 1);
+            if (spaceIndex < 0) {
+                lines.add(text);
+                text = "";
+            } else {
+                String subString = text.substring(0, spaceIndex);
+                float size = fontSize * font.getStringWidth(subString) / 1000;
+                if (size > width) {
+                    if (lastSpace < 0) // So we have a word longer than the line... draw it anyways
+                        lastSpace = spaceIndex;
+                    subString = text.substring(0, lastSpace);
+                    lines.add(subString);
+                    text = text.substring(lastSpace).trim();
+                    lastSpace = -1;
+                } else {
+                    lastSpace = spaceIndex;
+                }
+            }
+        }
+
+        currentContentStream.beginText();
+        currentContentStream.setFont(font, fontSize);
+        currentContentStream.moveTextPositionByAmount(marginLeftRight, currentY);            
+        for (String line: lines) {
+        	currentContentStream.drawString(line);
+            currentContentStream.moveTextPositionByAmount(0, -leading);
+            currentY -= leading; 
+        }
+        currentContentStream.endText();
+    }
+    
+    public float getStringWidth(String string, float fontSize)
+    throws IOException {
+    	return fontSize * font.getStringWidth(string) / 1000;
+    }
+    
+    public void drawLine(float xStart, float yStart, float xEnd, float yEnd, float width) 
+    throws IOException {
+		currentContentStream.setLineWidth(width);
+		currentContentStream.drawLine(xStart, yStart, xEnd, yEnd);
+    }
+    
+    public void addMetadata(String title, String subject, String author)
+    throws IOException, TransformerException {
+        PDDocumentCatalog catalog = document.getDocumentCatalog();
+        PDDocumentInformation info = document.getDocumentInformation();
+        Calendar date = Calendar.getInstance();
+
+        info.setAuthor(author);
+        info.setCreator(author);
+        info.setCreationDate(date);
+        info.setModificationDate(date);
+        info.setTitle(title);
+        info.setSubject(subject);
+
+        XMPMetadata metadata = new XMPMetadata();
+        XMPSchemaPDF pdfSchema = metadata.addPDFSchema();
+        pdfSchema.setProducer("OpenOLAT");
+
+        XMPSchemaBasic basicSchema = metadata.addBasicSchema();
+        basicSchema.setModifyDate(date);
+        basicSchema.setCreateDate(date);
+        basicSchema.setCreatorTool("OpenOLAT");
+        basicSchema.setMetadataDate(date);
+
+        XMPSchemaDublinCore dcSchema = metadata.addDublinCoreSchema();
+        dcSchema.setTitle(title);
+        dcSchema.addCreator(author);
+        dcSchema.setDescription(subject);
+
+        PDMetadata metadataStream = new PDMetadata(document);
+        metadataStream.importXMPMetadata(metadata);
+        catalog.setMetadata(metadataStream);
+    }
+    
+    public void addPageNumbers() throws IOException {
+        float footerFontSize = 10.0f;
+    	
+    	@SuppressWarnings("unchecked")
+		List<PDPage> allPages = document.getDocumentCatalog().getAllPages();
+        int numOfPages = allPages.size();
+        for( int i=0; i<allPages.size(); i++ ) {
+            PDPage page = allPages.get( i );
+            PDRectangle pageSize = page.findMediaBox();
+            
+            String text = (i+1) + " / " + numOfPages;
+            float stringWidth = getStringWidth(text, footerFontSize);
+            // calculate to center of the page
+            float pageWidth = pageSize.getWidth();
+            double x = (pageWidth - stringWidth) / 2.0f;
+            double y = (marginTopBottom / 2.0f);
+           
+            // append the content to the existing stream
+            PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true,true);
+            contentStream.beginText();
+            // set font and font size
+            contentStream.setFont( font, footerFontSize );
+            contentStream.setTextTranslation(x, y);
+            contentStream.drawString(text);
+            contentStream.endText();
+            contentStream.close();
+        }
+    }
+}
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java
index 9af5f9f38a6e9a08640d334a69aab5663745860b..49a4f69f10dd8a07047b95af9eb1fa384bcbca78 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java
@@ -19,6 +19,7 @@
  */
 package org.olat.course.nodes.cl.ui;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -28,6 +29,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.xml.transform.TransformerException;
+
+import org.apache.pdfbox.exceptions.COSVisitorException;
 import org.olat.NewControllerFactory;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.BaseSecurityModule;
@@ -38,6 +42,7 @@ import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
 import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
@@ -49,6 +54,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionE
 import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiColumnModel;
 import org.olat.core.gui.components.form.flexible.impl.elements.table.TextFlexiCellRenderer;
+import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.ControllerEventListener;
 import org.olat.core.gui.control.Event;
@@ -94,9 +100,11 @@ public class CheckListAssessmentController extends FormBasicController implement
 	private final UserCourseEnvironment userCourseEnv;
 	private final boolean isAdministrativeUser;
 	
+	private FormLink pdfExport;
 	private CheckboxAssessmentDataModel model;
 	private FlexiTableElement table;
 	private final List<UserPropertyHandler> userPropertyHandlers;
+	private final CheckboxList checkboxList;
 	
 	private CloseableModalController cmc;
 	private AssessedIdentityOverviewController editCtrl;
@@ -130,6 +138,7 @@ public class CheckListAssessmentController extends FormBasicController implement
 		this.courseNode = courseNode;
 		this.userCourseEnv = userCourseEnv;
 		config = courseNode.getModuleConfiguration();
+		checkboxList = (CheckboxList)config.get(CheckListCourseNode.CONFIG_KEY_CHECKBOX);
 		Roles roles = ureq.getUserSession().getRoles();
 		isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles);
 		userPropertyHandlers = userManager.getUserPropertyHandlersFor(USER_PROPS_ID, isAdministrativeUser);
@@ -179,10 +188,9 @@ public class CheckListAssessmentController extends FormBasicController implement
 			}
 		}
 		
-		CheckboxList list = (CheckboxList)config.get(CheckListCourseNode.CONFIG_KEY_CHECKBOX);
-		List<Checkbox> checkboxList = list.getList();
+		List<Checkbox> boxList = checkboxList.getList();
 		int j = 0;
-		for(Checkbox box:checkboxList) {
+		for(Checkbox box:boxList) {
 			int colIndex = CheckboxAssessmentDataModel.CHECKBOX_OFFSET + j++;
 			String colName = "checkbox_" + colIndex;
 			DefaultFlexiColumnModel column = new DefaultFlexiColumnModel(true, colName, colIndex, true, colName);
@@ -215,6 +223,8 @@ public class CheckListAssessmentController extends FormBasicController implement
 		table = uifactory.addTableElement(ureq, getWindowControl(), "checkbox-list", model, getTranslator(), formLayout);
 		table.setFilterKeysAndValues("participants", keys, values);
 		table.setExportEnabled(true);
+		
+		pdfExport = uifactory.addFormLink("pdf.export", formLayout, Link.BUTTON);
 	}
 	
 	private List<AssessmentDataView> loadDatas() {
@@ -303,6 +313,8 @@ public class CheckListAssessmentController extends FormBasicController implement
 					doOpenIdentity(ureq, row);
 				}
 			}
+		} else if(pdfExport == source) {
+			doExportPDF(ureq);
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
@@ -330,6 +342,21 @@ public class CheckListAssessmentController extends FormBasicController implement
 		//
 	}
 	
+	private void doExportPDF(UserRequest ureq) {
+		try {
+			String name = courseNode.getShortTitle();
+			CheckboxPDFExport pdfExport = new CheckboxPDFExport(name, getTranslator(), userPropertyHandlers);
+			pdfExport.setAuthor(userManager.getUserDisplayName(getIdentity()));
+			pdfExport.setTitle(courseNode.getShortTitle());
+			pdfExport.setSubject(courseNode.getLongTitle());
+			pdfExport.setObjectives(courseNode.getLearningObjectives());
+			pdfExport.create(checkboxList, model);
+			ureq.getDispatchResult().setResultingMediaResource(pdfExport);
+		} catch (IOException | COSVisitorException | TransformerException e) {
+			logError("", e);
+		}
+	}
+	
 	private void doOpenIdentity(UserRequest ureq, AssessmentDataView row) {
 		String businessPath = "[Identity:" + row.getIdentityKey() + "]";
 		NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java
index 7dc3722dc8faf8fbf56e8e7bedc1f0d84678d5f2..b48c7e17a68d890e391f03a04360dfde53b9a35d 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java
@@ -55,6 +55,13 @@ public class CheckboxAssessmentDataModel extends DefaultFlexiTableDataModel<Asse
 		super(datas, columnModel);
 		backupRows = datas;
 	}
+	
+	/**
+	 * @return The list of rows, not filtered
+	 */
+	public List<AssessmentDataView> getBackedUpRows() {
+		return backupRows;
+	}
 
 	@Override
 	public DefaultFlexiTableDataModel<AssessmentDataView> createCopyWithEmptyList() {
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java
new file mode 100644
index 0000000000000000000000000000000000000000..b69471fe365c3005232b74da1d01ddf631c7b81b
--- /dev/null
+++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxPDFExport.java
@@ -0,0 +1,333 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.course.nodes.cl.ui;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.transform.TransformerException;
+
+import org.apache.pdfbox.exceptions.COSVisitorException;
+import org.olat.core.gui.media.MediaResource;
+import org.olat.core.gui.translator.Translator;
+import org.olat.core.id.UserConstants;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.pdf.PdfDocument;
+import org.olat.course.nodes.cl.model.AssessmentDataView;
+import org.olat.course.nodes.cl.model.Checkbox;
+import org.olat.course.nodes.cl.model.CheckboxList;
+import org.olat.user.propertyhandlers.UserPropertyHandler;
+
+/**
+ * 
+ * Initial date: 12.02.2014<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class CheckboxPDFExport extends PdfDocument implements MediaResource {
+	
+	private static final OLog log = Tracing.createLoggerFor(CheckboxPDFExport.class);
+	
+	private final String filename;
+	private String title;
+	private String subject;
+	private String objectives;
+	private String author;
+	private final Translator translator;
+	private int firstNameIndex;
+	private int lastNameIndex;
+	
+	public CheckboxPDFExport(String filename, Translator translator, List<UserPropertyHandler> userPropertyHandlers)
+			throws IOException {
+		super();
+		this.filename = filename;
+		this.translator = translator;
+		
+		int i=0;
+		for(UserPropertyHandler userPropertyHandler:userPropertyHandlers) {
+			if(UserConstants.LASTNAME.equals(userPropertyHandler.getName())) {
+				lastNameIndex = i;
+			}
+			i++;
+		}
+		
+		int j=0;
+		for(UserPropertyHandler userPropertyHandler:userPropertyHandlers) {
+			if(UserConstants.FIRSTNAME.equals(userPropertyHandler.getName())) {
+				firstNameIndex = j;
+			}
+			j++;
+		}
+	}
+	
+    public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public String getSubject() {
+		return subject;
+	}
+
+	public void setSubject(String subject) {
+		this.subject = subject;
+	}
+
+	public String getAuthor() {
+		return author;
+	}
+
+	public void setAuthor(String author) {
+		this.author = author;
+	}
+
+	public String getObjectives() {
+		return objectives;
+	}
+
+	public void setObjectives(String objectives) {
+		this.objectives = objectives;
+	}
+
+	@Override
+	public String getContentType() {
+		return "application/pdf";
+	}
+
+	@Override
+	public Long getSize() {
+		return null;
+	}
+
+	@Override
+	public InputStream getInputStream() {
+		return null;
+	}
+
+	@Override
+	public Long getLastModified() {
+		return null;
+	}
+
+	@Override
+	public void prepare(HttpServletResponse hres) {
+		try {
+			hres.setHeader("Content-Disposition","attachment; filename*=UTF-8''" + StringHelper.urlEncodeUTF8(filename));			
+			hres.setHeader("Content-Description",StringHelper.urlEncodeUTF8(filename));
+			document.save(hres.getOutputStream());
+		} catch (COSVisitorException | IOException e) {
+			log.error("", e);
+		}
+	}
+
+	@Override
+	public void release() {
+		try {
+			close();
+		} catch (IOException e) {
+			log.error("", e);
+		}
+	}
+
+	public void create(CheckboxList checkboxList, CheckboxAssessmentDataModel dataModel)
+    throws IOException, COSVisitorException, TransformerException {
+    	addPage();
+    	addMetadata(title, subject, author);
+    	if(StringHelper.containsNonWhitespace(objectives)) {
+    		addParagraph(objectives, 10, width);
+    	}
+    	
+    	float maxSize = 0.0f;
+    	float fontSize = 10.0f;
+    	for(Checkbox box:checkboxList.getList()) {
+    		maxSize = Math.max(maxSize, getStringWidth(box.getTitle(), fontSize));
+    	}
+    	
+    	String[] headers = getHeaders(checkboxList);
+    	String[][] content = getRows(checkboxList, dataModel);
+    	int numOfRows = content.length;
+    	for(int offset=0; offset<numOfRows; ) {
+    		offset += drawTable(headers, content, offset, maxSize, fontSize, 5);
+    		closePage();
+        	if(offset<numOfRows) {
+        		addPage();
+        	}
+    	}
+    	
+    	addPageNumbers(); 
+    }
+	
+	private String[][] getRows(CheckboxList checkboxList, CheckboxAssessmentDataModel dataModel) {
+		List<AssessmentDataView> rows = dataModel.getBackedUpRows();
+		int numOfRows = rows.size();
+		List<Checkbox> boxList = checkboxList.getList();
+    	int numOfCheckbox = boxList.size();
+    	
+    	String[][] content = new String[numOfRows][];
+    	for(int i=0; i<numOfRows; i++) {
+    		AssessmentDataView row = rows.get(i);
+    		content[i] = new String[numOfCheckbox + 2];
+        	content[i][0] = getName(row);
+        	for(int j=0; j<numOfCheckbox; j++) {
+        		Boolean[] checked = row.getChecked();
+        		if(checked != null && j >= 0 && j < checked.length) {
+    				Boolean check = checked[j];
+    				if(check != null && check.booleanValue()) {
+    					content[i][j+1] = "x";
+    				}
+    			}
+
+        	}
+    	}
+    	
+    	return content;
+	}
+	
+	private String getName(AssessmentDataView view) {
+		StringBuilder sb = new StringBuilder();
+		sb.append(view.getIdentityProp(lastNameIndex))
+		  .append(", ")
+		  .append(view.getIdentityProp(firstNameIndex));
+		return sb.toString();
+	}
+	
+	private String[] getHeaders(CheckboxList checkboxList) {
+    	int numOfCheckbox = checkboxList.getList().size();
+		String[] headers = new String[numOfCheckbox + 2];
+    	headers[0] = translator.translate("participants");
+    	int pos = 1;
+    	for(Checkbox box:checkboxList.getList()) {
+    		headers[pos++] = box.getTitle();
+    	}
+    	headers[numOfCheckbox + 1] = translator.translate("signature");
+    	return headers;
+	}
+    
+	public int drawTable(String[] headers, String[][] content, int offset, float maxHeaderSize, float fontSize, float margin)
+	throws IOException {
+	
+		float tableWidth = width;
+		int cols = content[0].length;
+		
+		
+		float headerHeight = maxHeaderSize + (2*margin);
+		
+		float rowHeight = (lineHeightFactory * fontSize) + (2 * margin);
+		
+		float availableHeight = currentY - marginTopBottom - headerHeight;
+		float numOfAvailableRows = availableHeight / rowHeight;
+		int possibleRows = Math.round(numOfAvailableRows);
+		int end = Math.min(offset + possibleRows, content.length);
+		int rows = end - offset;
+		
+		float tableHeight = (rowHeight * rows) + headerHeight;
+		float colWidth = (tableWidth - 200) / (float) (cols - 2.0f);
+		float cellMargin = 5f;
+
+		// draw the rows
+		float y = currentY;
+		float nexty = currentY;
+		drawLine(marginLeftRight, nexty, marginLeftRight + tableWidth, nexty, 0.5f);
+		nexty -= headerHeight;
+		for (int i = 0; i <= rows; i++) {
+			drawLine(marginLeftRight, nexty, marginLeftRight + tableWidth, nexty, 0.5f);
+			nexty -= rowHeight;
+		}
+
+		// draw the columns
+		float nextx = marginLeftRight;
+		drawLine(nextx, y, nextx, y - tableHeight, 0.5f);
+		nextx += 100;
+		for (int i=1; i<=cols-2; i++) {
+			drawLine(nextx, y, nextx, y - tableHeight, 0.5f);
+			nextx += colWidth;
+		}
+		drawLine(nextx, y, nextx, y - tableHeight, 0.5f);
+		nextx += 100;
+		drawLine(nextx, y, nextx, y - tableHeight, 0.5f);
+		
+
+		// now add the text
+		currentContentStream.setFont(font, fontSize);
+		
+		// draw the headers
+		float textx = marginLeftRight + cellMargin;
+		float texty = currentY;
+		for (int h=0; h<cols; h++) {
+			String text = headers[h];
+			if(text == null) {
+				text = "";
+			}
+			currentContentStream.beginText();
+			if (h == 0 || h == (cols-1)) {
+				currentContentStream.moveTextPositionByAmount(textx, texty - headerHeight + margin);
+				currentContentStream.drawString(text);
+				textx += 100;
+			} else {
+				currentContentStream.setTextRotation(3 * (Math.PI / 2), textx + margin, texty - margin);
+				currentContentStream.drawString(text);
+				textx += colWidth;
+			}
+			currentContentStream.endText();
+			
+		}
+
+		currentY -= headerHeight;
+
+
+		textx = marginLeftRight + cellMargin;
+		texty = currentY - 15;
+		for (int i=offset; i<end; i++) {
+			if(i==200) {
+				System.out.println();
+			}
+			
+			String[] rowContent = content[i];
+			if(rowContent == null) continue;
+			
+			for (int j = 0; j < cols; j++) {
+				String text = rowContent[j];
+				if(text != null) {
+					if("x".equals(text)) {
+						text = "x";
+					} 
+					currentContentStream.beginText();
+					currentContentStream.moveTextPositionByAmount(textx, texty);
+					currentContentStream.drawString(text);
+					currentContentStream.endText();
+				}
+				textx += (j==0 ? 100 : colWidth);
+			}
+			texty -= rowHeight;
+			textx = marginLeftRight + cellMargin;
+		}
+		
+		return rows;
+	}
+    
+
+}
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_content/assessment_list.html b/src/main/java/org/olat/course/nodes/cl/ui/_content/assessment_list.html
index 55a8a5fcd35c389f81665f99fd307b80e2b6e502..5231a88f656c2f813830eac1a2243093cfe8b32d 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_content/assessment_list.html
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_content/assessment_list.html
@@ -6,4 +6,10 @@
 		<p>$r.translate("run.due.date",$r.formatDateAndTime($dueDate))</p>
 	#end
 	$r.render("checkbox-list")
+	
+	<div class="b_clearfix o_qpool_button_bar_box">
+		<div class="o_qpool_button_bar">
+			$r.render("pdf.export")
+		</div>
+	</div>
 </div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties
index d0b1090d22b54fe7b2781171fc8dc7d1face3e57..d8d6755e8cd54a51cc31a0818cd2911e4d0d95ab 100644
--- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_de.properties
@@ -49,10 +49,12 @@ label.presented=Vorgef
 label.controlled=Kontrolliert
 label.present=Anwesend
 points=Punkte
+pdf.export=PDF generieren
 award.point.on=Punkte vergeben bei Auswahl
 description=Beschreibung
 participants=Mitglieder
 file=Datei
+signature=Unterschrift
 run.run=Persönliche Checkliste
 run.coach=Checklisten Verwaltung
 run.mark=Markierung