Autopsy  4.5.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ReportExcel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-2018 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.report;
20 
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;
31 import org.sleuthkit.datamodel.TskCoreException;
32 
33 class ReportExcel implements TableReportModule {
34 
35  private static final Logger logger = Logger.getLogger(ReportExcel.class.getName());
36  private static ReportExcel instance;
37  private static final int EXCEL_CELL_MAXIMUM_SIZE = 36767; //Specified at:https://poi.apache.org/apidocs/org/apache/poi/ss/SpreadsheetVersion.html
38 
39  private Workbook wb;
40  private Sheet sheet;
41  private CellStyle titleStyle;
42  private CellStyle setStyle;
43  private CellStyle elementStyle;
44  private int rowIndex = 0;
45  private int sheetColCount = 0;
46  private String reportPath;
47 
48  // Get the default instance of this report
49  public static synchronized ReportExcel getDefault() {
50  if (instance == null) {
51  instance = new ReportExcel();
52  }
53  return instance;
54  }
55 
56  // Hidden constructor
57  private ReportExcel() {
58  }
59 
66  @Override
67  public void startReport(String baseReportDir) {
68  // Set the path and save it for when the report is written to disk.
69  this.reportPath = baseReportDir + getRelativeFilePath();
70 
71  // Make a workbook.
72  wb = new XSSFWorkbook();
73 
74  // Create some cell styles.
75  // TODO: The commented out cell style settings below do not work as desired when
76  // the output file is loaded by MS Excel or OfficeLibre. The font height and weight
77  // settings only work as expected when the output file is loaded by OfficeLibre.
78  // The alignment and text wrap settings appear to have no effect.
79  titleStyle = wb.createCellStyle();
80 // titleStyle.setBorderBottom((short) 1);
81  Font titleFont = wb.createFont();
82  titleFont.setFontHeightInPoints((short) 12);
83  titleStyle.setFont(titleFont);
84  titleStyle.setAlignment(HorizontalAlignment.LEFT);
85  titleStyle.setWrapText(true);
86 
87  setStyle = wb.createCellStyle();
88  Font setFont = wb.createFont();
89  setFont.setFontHeightInPoints((short) 14);
90  setFont.setBold(true);
91  setStyle.setFont(setFont);
92  setStyle.setAlignment(HorizontalAlignment.LEFT);
93  setStyle.setWrapText(true);
94 
95  elementStyle = wb.createCellStyle();
96 // elementStyle.setF illBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
97  Font elementFont = wb.createFont();
98  elementFont.setFontHeightInPoints((short) 14);
99  elementStyle.setFont(elementFont);
100  elementStyle.setAlignment(HorizontalAlignment.LEFT);
101  elementStyle.setWrapText(true);
102 
103  writeSummaryWorksheet();
104  }
105 
109  @Override
110  public void endReport() {
111  FileOutputStream out = null;
112  try {
113  out = new FileOutputStream(reportPath);
114  wb.write(out);
115  Case.getCurrentCase().addReport(reportPath, NbBundle.getMessage(this.getClass(),
116  "ReportExcel.endReport.srcModuleName.text"), "");
117  } catch (IOException ex) {
118  logger.log(Level.SEVERE, "Failed to write Excel report.", ex); //NON-NLS
119  } catch (TskCoreException ex) {
120  String errorMessage = String.format("Error adding %s to case as a report", reportPath); //NON-NLS
121  logger.log(Level.SEVERE, errorMessage, ex);
122  } finally {
123  if (out != null) {
124  try {
125  out.close();
126  } catch (IOException ex) {
127  }
128  }
129  }
130  }
131 
139  @Override
140  public void startDataType(String name, String description) {
141  // Create a worksheet for the data type (assumed to be an artifact type).
142  name = escapeForExcel(name);
143  sheet = wb.createSheet(name);
144  sheet.setAutobreaks(true);
145  rowIndex = 0;
146 
147  // There will be at least two columns, one each for the artifacts count and its label.
148  sheetColCount = 2;
149  }
150 
154  @Override
155  public void endDataType() {
156  // Now that the sheet is complete, size the columns to the content.
157  for (int i = 0; i < sheetColCount; ++i) {
158  sheet.autoSizeColumn(i);
159  }
160  }
161 
167  @Override
168  public void startSet(String setName) {
169  setName = escapeForExcel(setName);
170  Row row = sheet.createRow(rowIndex);
171  row.setRowStyle(setStyle);
172  row.createCell(0).setCellValue(setName);
173  ++rowIndex;
174  }
175 
179  @Override
180  public void endSet() {
181  // Add an empty row as a separator.
182  sheet.createRow(rowIndex);
183  ++rowIndex;
184  }
185 
186  @Override
187  public void addSetIndex(List<String> sets) {
188  // Ignored in Excel Report
189  }
190 
196  @Override
197  public void addSetElement(String elementName) {
198  elementName = escapeForExcel(elementName);
199  Row row = sheet.createRow(rowIndex);
200  row.setRowStyle(elementStyle);
201  row.createCell(0).setCellValue(elementName);
202  ++rowIndex;
203  }
204 
210  @Override
211  public void startTable(List<String> titles) {
212  int tableColCount = 0;
213  Row row = sheet.createRow(rowIndex);
214  row.setRowStyle(titleStyle);
215  for (int i = 0; i < titles.size(); i++) {
216  row.createCell(i).setCellValue(titles.get(i));
217  ++tableColCount;
218  }
219  ++rowIndex;
220 
221  // Keep track of the number of columns with data in them for later column auto-sizing.
222  if (tableColCount > sheetColCount) {
223  sheetColCount = tableColCount;
224  }
225  }
226 
227  @Override
228  public void endTable() {
229  // Add an empty row as a separator.
230  sheet.createRow(rowIndex);
231  ++rowIndex;
232  }
233 
239  @Override
240  @NbBundle.Messages({
241  "ReportExcel.exceptionMessage.dataTooLarge=Value is too long to fit into an Excel cell. ",
242  "ReportExcel.exceptionMessage.errorText=Error showing data into an Excel cell."
243  })
244 
245  public void addRow(List<String> rowData) {
246  Row row = sheet.createRow(rowIndex);
247  for (int i = 0; i < rowData.size(); ++i) {
248  Cell excelCell = row.createCell(i);
249  try {
250  excelCell.setCellValue(rowData.get(i));
251  } catch (Exception e) {
252  if (e instanceof java.lang.IllegalArgumentException && rowData.get(i).length() > EXCEL_CELL_MAXIMUM_SIZE) {
253  excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_dataTooLarge() + e.getMessage());
254  } else {
255  excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_errorText());
256  }
257  }
258  }
259  ++rowIndex;
260  }
261 
269  @Override
270  public String dateToString(long date) {
271  SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
272  return sdf.format(new java.util.Date(date * 1000));
273  }
274 
275  @Override
276  public String getName() {
277  return NbBundle.getMessage(this.getClass(), "ReportExcel.getName.text");
278  }
279 
280  @Override
281  public String getDescription() {
282  return NbBundle.getMessage(this.getClass(), "ReportExcel.getDesc.text");
283  }
284 
285  @Override
286  public String getRelativeFilePath() {
287  return "Excel.xlsx"; //NON-NLS
288  }
289 
298  private static String escapeForExcel(String text) {
299  return text.replaceAll("[\\/\\:\\?\\*\\\\]", "_");
300  }
301 
302  private void writeSummaryWorksheet() {
303  sheet = wb.createSheet(NbBundle.getMessage(this.getClass(), "ReportExcel.sheetName.text"));
304  rowIndex = 0;
305 
306  Row row = sheet.createRow(rowIndex);
307  row.setRowStyle(setStyle);
308  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.summary"));
309  ++rowIndex;
310 
311  sheet.createRow(rowIndex);
312  ++rowIndex;
313 
314  Case currentCase = Case.getCurrentCase();
315 
316  row = sheet.createRow(rowIndex);
317  row.setRowStyle(setStyle);
318  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseName"));
319  row.createCell(1).setCellValue(currentCase.getDisplayName());
320  ++rowIndex;
321 
322  row = sheet.createRow(rowIndex);
323  row.setRowStyle(setStyle);
324  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseNum"));
325  row.createCell(1).setCellValue(currentCase.getNumber());
326  ++rowIndex;
327 
328  row = sheet.createRow(rowIndex);
329  row.setRowStyle(setStyle);
330  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.examiner"));
331  row.createCell(1).setCellValue(currentCase.getExaminer());
332  ++rowIndex;
333 
334  row = sheet.createRow(rowIndex);
335  row.setRowStyle(setStyle);
336  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.numImages"));
337  int numImages;
338  try {
339  numImages = currentCase.getDataSources().size();
340  } catch (TskCoreException ex) {
341  numImages = 0;
342  }
343  row.createCell(1).setCellValue(numImages);
344  ++rowIndex;
345 
346  sheet.autoSizeColumn(0);
347  sheet.autoSizeColumn(1);
348  }
349 }

Copyright © 2012-2016 Basis Technology. Generated on: Tue Feb 20 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.