19 package org.sleuthkit.autopsy.report;
 
   21 import java.io.FileOutputStream;
 
   22 import java.io.IOException;
 
   23 import java.text.SimpleDateFormat;
 
   24 import java.util.List;
 
   25 import java.util.logging.Level;
 
   26 import org.apache.poi.ss.usermodel.*;
 
   27 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
   28 import org.openide.util.NbBundle;
 
   29 import org.openide.util.NbBundle.Messages;
 
   35 class ReportExcel 
implements TableReportModule {
 
   37     private static final Logger logger = Logger.getLogger(ReportExcel.class.getName());
 
   38     private static ReportExcel instance;
 
   39     private static final int EXCEL_CELL_MAXIMUM_SIZE = 36767; 
 
   43     private CellStyle titleStyle;
 
   44     private CellStyle setStyle;
 
   45     private CellStyle elementStyle;
 
   46     private int rowIndex = 0;
 
   47     private int sheetColCount = 0;
 
   48     private String reportPath;
 
   51     public static synchronized ReportExcel getDefault() {
 
   52         if (instance == null) {
 
   53             instance = 
new ReportExcel();
 
   59     private ReportExcel() {
 
   69     public void startReport(String baseReportDir) {
 
   71         this.reportPath = baseReportDir + getRelativeFilePath();
 
   74         wb = 
new XSSFWorkbook();
 
   81         titleStyle = wb.createCellStyle();
 
   83         Font titleFont = wb.createFont();
 
   84         titleFont.setFontHeightInPoints((
short) 12);
 
   85         titleStyle.setFont(titleFont);
 
   86         titleStyle.setAlignment(HorizontalAlignment.LEFT);
 
   87         titleStyle.setWrapText(
true);
 
   89         setStyle = wb.createCellStyle();
 
   90         Font setFont = wb.createFont();
 
   91         setFont.setFontHeightInPoints((
short) 14);
 
   92         setFont.setBold(
true);
 
   93         setStyle.setFont(setFont);
 
   94         setStyle.setAlignment(HorizontalAlignment.LEFT);
 
   95         setStyle.setWrapText(
true);
 
   97         elementStyle = wb.createCellStyle();
 
   99         Font elementFont = wb.createFont();
 
  100         elementFont.setFontHeightInPoints((
short) 14);
 
  101         elementStyle.setFont(elementFont);
 
  102         elementStyle.setAlignment(HorizontalAlignment.LEFT);
 
  103         elementStyle.setWrapText(
true);
 
  105         writeSummaryWorksheet();
 
  112     public void endReport() {
 
  113         FileOutputStream out = null;
 
  115             out = 
new FileOutputStream(reportPath);
 
  117             Case.getCurrentCaseThrows().addReport(reportPath, NbBundle.getMessage(
this.getClass(),
 
  118                     "ReportExcel.endReport.srcModuleName.text"), 
"");
 
  119         } 
catch (IOException ex) {
 
  120             logger.log(Level.SEVERE, 
"Failed to write Excel report.", ex); 
 
  121         } 
catch (TskCoreException ex) {
 
  122             String errorMessage = String.format(
"Error adding %s to case as a report", reportPath); 
 
  123             logger.log(Level.SEVERE, errorMessage, ex);
 
  124         } 
catch (NoCurrentCaseException ex) {
 
  125             logger.log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  130                 } 
catch (IOException ex) {
 
  144     public void startDataType(String name, String description) {
 
  146         name = escapeForExcel(name);
 
  147         sheet = wb.createSheet(name);
 
  148         sheet.setAutobreaks(
true);
 
  159     public void endDataType() {
 
  161         for (
int i = 0; i < sheetColCount; ++i) {
 
  162             sheet.autoSizeColumn(i);
 
  172     public void startSet(String setName) {
 
  173         setName = escapeForExcel(setName);
 
  174         Row row = sheet.createRow(rowIndex);
 
  175         row.setRowStyle(setStyle);
 
  176         row.createCell(0).setCellValue(setName);
 
  184     public void endSet() {
 
  186         sheet.createRow(rowIndex);
 
  191     public void addSetIndex(List<String> sets) {
 
  201     public void addSetElement(String elementName) {
 
  202         elementName = escapeForExcel(elementName);
 
  203         Row row = sheet.createRow(rowIndex);
 
  204         row.setRowStyle(elementStyle);
 
  205         row.createCell(0).setCellValue(elementName);
 
  215     public void startTable(List<String> titles) {
 
  216         int tableColCount = 0;
 
  217         Row row = sheet.createRow(rowIndex);
 
  218         row.setRowStyle(titleStyle);
 
  219         for (
int i = 0; i < titles.size(); i++) {
 
  220             row.createCell(i).setCellValue(titles.get(i));
 
  226         if (tableColCount > sheetColCount) {
 
  227             sheetColCount = tableColCount;
 
  232     public void endTable() {
 
  234         sheet.createRow(rowIndex);
 
  245         "ReportExcel.exceptionMessage.dataTooLarge=Value is too long to fit into an Excel cell. ",
 
  246         "ReportExcel.exceptionMessage.errorText=Error showing data into an Excel cell." 
  249     public void addRow(List<String> rowData) {
 
  250         Row row = sheet.createRow(rowIndex);
 
  251         for (
int i = 0; i < rowData.size(); ++i) {
 
  252             Cell excelCell = row.createCell(i);
 
  254                 excelCell.setCellValue(rowData.get(i));
 
  255             } 
catch (Exception e) {
 
  256                 if (e instanceof java.lang.IllegalArgumentException && rowData.get(i).length() > EXCEL_CELL_MAXIMUM_SIZE) {
 
  257                     excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_dataTooLarge() + e.getMessage());
 
  259                     excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_errorText());
 
  274     public String dateToString(
long date) {
 
  275         SimpleDateFormat sdf = 
new java.text.SimpleDateFormat(
"yyyy/MM/dd HH:mm:ss");
 
  276         return sdf.format(
new java.util.Date(date * 1000));
 
  280     public String getName() {
 
  281         return NbBundle.getMessage(this.getClass(), 
"ReportExcel.getName.text");
 
  285     public String getDescription() {
 
  286         return NbBundle.getMessage(this.getClass(), 
"ReportExcel.getDesc.text");
 
  290     public String getRelativeFilePath() {
 
  302     private static String escapeForExcel(String text) {
 
  303         return text.replaceAll(
"[\\/\\:\\?\\*\\\\]", 
"_");
 
  307         "ReportExcel.writeSummary.sheetName=Summary",
 
  308         "ReportExcel.writeSummary.summary=Summary",
 
  309         "ReportExcel.writeSummary.caseName=Case Name:",
 
  310         "ReportExcel.writeSummary.numImages=Number of Images:",
 
  311         "ReportExcel.writeSummary.caseNum=Case Number:",
 
  312         "ReportExcel.writeSummary.caseNotes=Case Notes:",
 
  313         "ReportExcel.writeSummary.examiner=Examiner:" 
  315     private void writeSummaryWorksheet() {
 
  318             currentCase = Case.getCurrentCaseThrows();
 
  319         } 
catch (NoCurrentCaseException ex) {
 
  320             logger.log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  323         sheet = wb.createSheet(Bundle.ReportExcel_writeSummary_sheetName());
 
  326         Row row = sheet.createRow(rowIndex);
 
  327         row.setRowStyle(setStyle);
 
  328         row.createCell(0).setCellValue(Bundle.ReportExcel_writeSummary_summary());
 
  331         sheet.createRow(rowIndex);
 
  334         row = sheet.createRow(rowIndex);
 
  335         row.setRowStyle(setStyle);
 
  336         row.createCell(0).setCellValue(Bundle.ReportExcel_writeSummary_caseName());
 
  337         row.createCell(1).setCellValue(currentCase.getDisplayName());
 
  340         if (!currentCase.getNumber().isEmpty()) {
 
  341             row = sheet.createRow(rowIndex);
 
  342             row.setRowStyle(setStyle);
 
  343             row.createCell(0).setCellValue(Bundle.ReportExcel_writeSummary_caseNum());
 
  344             row.createCell(1).setCellValue(currentCase.getNumber());
 
  348         row = sheet.createRow(rowIndex);
 
  349         row.setRowStyle(setStyle);
 
  350         row.createCell(0).setCellValue(Bundle.ReportExcel_writeSummary_numImages());
 
  353             numImages = currentCase.getDataSources().size();
 
  354         } 
catch (TskCoreException ex) {
 
  357         row.createCell(1).setCellValue(numImages);
 
  360         if (!currentCase.getCaseNotes().isEmpty()) {
 
  361             row = sheet.createRow(rowIndex);
 
  362             row.setRowStyle(setStyle);
 
  363             row.createCell(0).setCellValue(Bundle.ReportExcel_writeSummary_caseNotes());
 
  364             row.createCell(1).setCellValue(currentCase.getCaseNotes());
 
  368         if (!currentCase.getExaminer().isEmpty()) {
 
  369             row = sheet.createRow(rowIndex);
 
  370             row.setRowStyle(setStyle);
 
  371             row.createCell(0).setCellValue(Bundle.ReportExcel_writeSummary_examiner());
 
  372             row.createCell(1).setCellValue(currentCase.getExaminer());
 
  376         sheet.autoSizeColumn(0);
 
  377         sheet.autoSizeColumn(1);