Autopsy  4.9.1
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;
32 import org.sleuthkit.datamodel.TskCoreException;
33 
34 class ReportExcel implements TableReportModule {
35 
36  private static final Logger logger = Logger.getLogger(ReportExcel.class.getName());
37  private static ReportExcel instance;
38  private static final int EXCEL_CELL_MAXIMUM_SIZE = 36767; //Specified at:https://poi.apache.org/apidocs/org/apache/poi/ss/SpreadsheetVersion.html
39 
40  private Workbook wb;
41  private Sheet sheet;
42  private CellStyle titleStyle;
43  private CellStyle setStyle;
44  private CellStyle elementStyle;
45  private int rowIndex = 0;
46  private int sheetColCount = 0;
47  private String reportPath;
48 
49  // Get the default instance of this report
50  public static synchronized ReportExcel getDefault() {
51  if (instance == null) {
52  instance = new ReportExcel();
53  }
54  return instance;
55  }
56 
57  // Hidden constructor
58  private ReportExcel() {
59  }
60 
67  @Override
68  public void startReport(String baseReportDir) {
69  // Set the path and save it for when the report is written to disk.
70  this.reportPath = baseReportDir + getRelativeFilePath();
71 
72  // Make a workbook.
73  wb = new XSSFWorkbook();
74 
75  // Create some cell styles.
76  // TODO: The commented out cell style settings below do not work as desired when
77  // the output file is loaded by MS Excel or OfficeLibre. The font height and weight
78  // settings only work as expected when the output file is loaded by OfficeLibre.
79  // The alignment and text wrap settings appear to have no effect.
80  titleStyle = wb.createCellStyle();
81 // titleStyle.setBorderBottom((short) 1);
82  Font titleFont = wb.createFont();
83  titleFont.setFontHeightInPoints((short) 12);
84  titleStyle.setFont(titleFont);
85  titleStyle.setAlignment(HorizontalAlignment.LEFT);
86  titleStyle.setWrapText(true);
87 
88  setStyle = wb.createCellStyle();
89  Font setFont = wb.createFont();
90  setFont.setFontHeightInPoints((short) 14);
91  setFont.setBold(true);
92  setStyle.setFont(setFont);
93  setStyle.setAlignment(HorizontalAlignment.LEFT);
94  setStyle.setWrapText(true);
95 
96  elementStyle = wb.createCellStyle();
97 // elementStyle.setF illBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
98  Font elementFont = wb.createFont();
99  elementFont.setFontHeightInPoints((short) 14);
100  elementStyle.setFont(elementFont);
101  elementStyle.setAlignment(HorizontalAlignment.LEFT);
102  elementStyle.setWrapText(true);
103 
104  writeSummaryWorksheet();
105  }
106 
110  @Override
111  public void endReport() {
112  FileOutputStream out = null;
113  try {
114  out = new FileOutputStream(reportPath);
115  wb.write(out);
116  Case.getCurrentCaseThrows().addReport(reportPath, NbBundle.getMessage(this.getClass(),
117  "ReportExcel.endReport.srcModuleName.text"), "");
118  } catch (IOException ex) {
119  logger.log(Level.SEVERE, "Failed to write Excel report.", ex); //NON-NLS
120  } catch (TskCoreException ex) {
121  String errorMessage = String.format("Error adding %s to case as a report", reportPath); //NON-NLS
122  logger.log(Level.SEVERE, errorMessage, ex);
123  } catch (NoCurrentCaseException ex) {
124  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
125  } finally {
126  if (out != null) {
127  try {
128  out.close();
129  } catch (IOException ex) {
130  }
131  }
132  }
133  }
134 
142  @Override
143  public void startDataType(String name, String description) {
144  // Create a worksheet for the data type (assumed to be an artifact type).
145  name = escapeForExcel(name);
146  sheet = wb.createSheet(name);
147  sheet.setAutobreaks(true);
148  rowIndex = 0;
149 
150  // There will be at least two columns, one each for the artifacts count and its label.
151  sheetColCount = 2;
152  }
153 
157  @Override
158  public void endDataType() {
159  // Now that the sheet is complete, size the columns to the content.
160  for (int i = 0; i < sheetColCount; ++i) {
161  sheet.autoSizeColumn(i);
162  }
163  }
164 
170  @Override
171  public void startSet(String setName) {
172  setName = escapeForExcel(setName);
173  Row row = sheet.createRow(rowIndex);
174  row.setRowStyle(setStyle);
175  row.createCell(0).setCellValue(setName);
176  ++rowIndex;
177  }
178 
182  @Override
183  public void endSet() {
184  // Add an empty row as a separator.
185  sheet.createRow(rowIndex);
186  ++rowIndex;
187  }
188 
189  @Override
190  public void addSetIndex(List<String> sets) {
191  // Ignored in Excel Report
192  }
193 
199  @Override
200  public void addSetElement(String elementName) {
201  elementName = escapeForExcel(elementName);
202  Row row = sheet.createRow(rowIndex);
203  row.setRowStyle(elementStyle);
204  row.createCell(0).setCellValue(elementName);
205  ++rowIndex;
206  }
207 
213  @Override
214  public void startTable(List<String> titles) {
215  int tableColCount = 0;
216  Row row = sheet.createRow(rowIndex);
217  row.setRowStyle(titleStyle);
218  for (int i = 0; i < titles.size(); i++) {
219  row.createCell(i).setCellValue(titles.get(i));
220  ++tableColCount;
221  }
222  ++rowIndex;
223 
224  // Keep track of the number of columns with data in them for later column auto-sizing.
225  if (tableColCount > sheetColCount) {
226  sheetColCount = tableColCount;
227  }
228  }
229 
230  @Override
231  public void endTable() {
232  // Add an empty row as a separator.
233  sheet.createRow(rowIndex);
234  ++rowIndex;
235  }
236 
242  @Override
243  @NbBundle.Messages({
244  "ReportExcel.exceptionMessage.dataTooLarge=Value is too long to fit into an Excel cell. ",
245  "ReportExcel.exceptionMessage.errorText=Error showing data into an Excel cell."
246  })
247 
248  public void addRow(List<String> rowData) {
249  Row row = sheet.createRow(rowIndex);
250  for (int i = 0; i < rowData.size(); ++i) {
251  Cell excelCell = row.createCell(i);
252  try {
253  excelCell.setCellValue(rowData.get(i));
254  } catch (Exception e) {
255  if (e instanceof java.lang.IllegalArgumentException && rowData.get(i).length() > EXCEL_CELL_MAXIMUM_SIZE) {
256  excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_dataTooLarge() + e.getMessage());
257  } else {
258  excelCell.setCellValue(Bundle.ReportExcel_exceptionMessage_errorText());
259  }
260  }
261  }
262  ++rowIndex;
263  }
264 
272  @Override
273  public String dateToString(long date) {
274  SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
275  return sdf.format(new java.util.Date(date * 1000));
276  }
277 
278  @Override
279  public String getName() {
280  return NbBundle.getMessage(this.getClass(), "ReportExcel.getName.text");
281  }
282 
283  @Override
284  public String getDescription() {
285  return NbBundle.getMessage(this.getClass(), "ReportExcel.getDesc.text");
286  }
287 
288  @Override
289  public String getRelativeFilePath() {
290  return "Excel.xlsx"; //NON-NLS
291  }
292 
301  private static String escapeForExcel(String text) {
302  return text.replaceAll("[\\/\\:\\?\\*\\\\]", "_");
303  }
304 
305  private void writeSummaryWorksheet() {
306  Case currentCase;
307  try {
308  currentCase = Case.getCurrentCaseThrows();
309  } catch (NoCurrentCaseException ex) {
310  logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS
311  return;
312  }
313  sheet = wb.createSheet(NbBundle.getMessage(this.getClass(), "ReportExcel.sheetName.text"));
314  rowIndex = 0;
315 
316  Row row = sheet.createRow(rowIndex);
317  row.setRowStyle(setStyle);
318  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.summary"));
319  ++rowIndex;
320 
321  sheet.createRow(rowIndex);
322  ++rowIndex;
323 
324  row = sheet.createRow(rowIndex);
325  row.setRowStyle(setStyle);
326  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseName"));
327  row.createCell(1).setCellValue(currentCase.getDisplayName());
328  ++rowIndex;
329 
330  row = sheet.createRow(rowIndex);
331  row.setRowStyle(setStyle);
332  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.caseNum"));
333  row.createCell(1).setCellValue(currentCase.getNumber());
334  ++rowIndex;
335 
336  row = sheet.createRow(rowIndex);
337  row.setRowStyle(setStyle);
338  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.examiner"));
339  row.createCell(1).setCellValue(currentCase.getExaminer());
340  ++rowIndex;
341 
342  row = sheet.createRow(rowIndex);
343  row.setRowStyle(setStyle);
344  row.createCell(0).setCellValue(NbBundle.getMessage(this.getClass(), "ReportExcel.cellVal.numImages"));
345  int numImages;
346  try {
347  numImages = currentCase.getDataSources().size();
348  } catch (TskCoreException ex) {
349  numImages = 0;
350  }
351  row.createCell(1).setCellValue(numImages);
352  ++rowIndex;
353 
354  sheet.autoSizeColumn(0);
355  sheet.autoSizeColumn(1);
356  }
357 }

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