/******************************************************************************* * Copyright 2013 * Ubiquitous Knowledge Processing (UKP) Lab * Technische Universität Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.tudarmstadt.ukp.csniper.webapp.statistics.page.export; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.PrintSetup; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import de.tudarmstadt.ukp.csniper.webapp.evaluation.EvaluationRepository; import de.tudarmstadt.ukp.csniper.webapp.evaluation.model.AdditionalColumn; import de.tudarmstadt.ukp.csniper.webapp.evaluation.model.ItemContext; import de.tudarmstadt.ukp.csniper.webapp.project.model.AnnotationType; import de.tudarmstadt.ukp.csniper.webapp.search.ContextProvider; import de.tudarmstadt.ukp.csniper.webapp.statistics.SortableAggregatedEvaluationResultDataProvider.ResultFilter; import de.tudarmstadt.ukp.csniper.webapp.statistics.model.AggregatedEvaluationResult; import de.tudarmstadt.ukp.csniper.webapp.statistics.page.StatisticsPage.ExportModel; import de.tudarmstadt.ukp.csniper.webapp.statistics.page.StatisticsPage.StatisticsFormModel; import de.tudarmstadt.ukp.csniper.webapp.support.task.Task; public class ExportExcelTask extends Task implements ExportTask { private EvaluationRepository repository; private ContextProvider contextProvider; private StatisticsFormModel formModel; private ExportModel exportModel; private File outputFile; public ExportExcelTask(StatisticsFormModel aFormModel, ExportModel aExportModel, EvaluationRepository aRepository, ContextProvider aContextProvider) { formModel = aFormModel; exportModel = aExportModel; contextProvider = aContextProvider; repository = aRepository; } @Override public File getOutputFile() { return outputFile; } @Override public String getFilename() { String innerSeparator = "-"; String outerSeparator = "_"; DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); StringBuilder sb = new StringBuilder(); sb.append("csniper"); sb.append(outerSeparator); sb.append(dateFormat.format(new Date())); sb.append(outerSeparator); sb.append(StringUtils.join(formModel.getCollections(), innerSeparator)); sb.append(outerSeparator); for (Iterator<AnnotationType> it = formModel.getTypes().iterator(); it.hasNext();) { sb.append(it.next().getName()); if (it.hasNext()) { sb.append(innerSeparator); } } sb.append(outerSeparator); sb.append(StringUtils.join(formModel.getUsers(), innerSeparator)); sb.append(".xls"); return sb.toString(); } @Override public void clean() { if (outputFile != null) { FileUtils.deleteQuietly(outputFile); outputFile = null; } } @Override protected void run() { Workbook wb = new HSSFWorkbook(); Sheet sheet = wb.createSheet("Summary"); PrintSetup printSetup = sheet.getPrintSetup(); printSetup.setLandscape(true); sheet.setFitToPage(true); sheet.setHorizontallyCenter(true); contextProvider.setOutputPos(exportModel.includePos); outputFile = null; OutputStream os = null; try { List<AggregatedEvaluationResult> results = repository.listAggregatedResults( formModel.getCollections(), formModel.getTypes(), formModel.getUsers(), formModel.getUserThreshold(), formModel.getConfidenceThreshold()); List<AdditionalColumn> ac = exportModel.additionalColumns; Collections.sort(results, new Comparator<AggregatedEvaluationResult>() { @Override public int compare(AggregatedEvaluationResult aO1, AggregatedEvaluationResult aO2) { String id1 = aO1.getItem().getCollectionId() + "|" + aO1.getItem().getDocumentId(); String id2 = aO2.getItem().getCollectionId() + "|" + aO2.getItem().getDocumentId(); return id1.compareTo(id2); } }); // Write header row List<String> colIds = new ArrayList<String>(Arrays.asList("User", "Collection", "Document", "Begin", "End", "Left", "Unit", "Right", "Type", "Class", "Confidence", "Correct", "Wrong")); for (int i = 0; i < ac.size(); i++) { colIds.add(ac.get(i).getName()); } Row headerRow = sheet.createRow(0); for (int i = 0; i < colIds.size(); i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(colIds.get(i)); } // Write rest setTotal(results.size()); int rowNum = 1; for (AggregatedEvaluationResult aer : results) { ResultFilter classification = aer.getClassification(); if (formModel.getFilters().contains(classification)) { ItemContext context = contextProvider.getContext(aer.getItem(), exportModel.contextSize, exportModel.contextSize); // only differentiate between users if additional columns are being exported Set<String> users; if (ac.isEmpty()) { users = new HashSet<String>(Arrays.asList("")); } else { users = aer.getUsers(false); } // output the AggregatedEvaluationResult for every user (because the additional // columns entries might differ) for (String user : users) { Row row = sheet.createRow(rowNum); row.createCell(0).setCellValue(user); row.createCell(1).setCellValue(aer.getItem().getCollectionId()); row.createCell(2).setCellValue(aer.getItem().getDocumentId()); row.createCell(3).setCellValue(aer.getItem().getBeginOffset()); row.createCell(4).setCellValue(aer.getItem().getEndOffset()); row.createCell(5).setCellValue(context.getLeft()); row.createCell(6).setCellValue(context.getUnit()); row.createCell(7).setCellValue(context.getRight()); row.createCell(8).setCellValue(aer.getItem().getType()); row.createCell(9).setCellValue(classification.toString()); row.createCell(10).setCellValue(aer.getConfidence()); row.createCell(11).setCellValue(aer.getCorrect()); row.createCell(12).setCellValue(aer.getWrong()); for (int i = 0; i < ac.size(); i++) { String cellValue = repository .getEvaluationResult(aer.getItem().getId(), user) .getAdditionalColumns().get(ac.get(i)); if (cellValue == null) { cellValue = ""; } row.createCell(colIds.size() - ac.size() + i).setCellValue(cellValue); } rowNum++; } } // Make sure we do not get to 100% before we did the classification, because // otherwise ProgressBar.onFinish() will trigger!!! increment(); if (isCancelled()) { break; } } outputFile = File.createTempFile("date", ".csv"); os = new FileOutputStream(outputFile); wb.write(os); } catch (IOException e) { e.printStackTrace(); error("Export failed: " + ExceptionUtils.getRootCauseMessage(e)); cancel(); } finally { IOUtils.closeQuietly(os); if (isCancelled()) { clean(); } } } }