mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 19:14:55 +00:00
beginnings of excel export
This commit is contained in:
parent
882c0a0635
commit
fd0838f4b4
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
* Basic interface for a cell model.
|
||||
*/
|
||||
public interface CellModel {
|
||||
|
||||
/**
|
||||
* Describes the horizontal alignment.
|
||||
*/
|
||||
public enum HorizontalAlign {
|
||||
LEFT(JLabel.LEFT),
|
||||
CENTER(JLabel.CENTER),
|
||||
RIGHT(JLabel.RIGHT);
|
||||
|
||||
private final int jlabelAlignment;
|
||||
|
||||
/**
|
||||
* Constructor for a HorizontalAlign enum.
|
||||
*
|
||||
* @param jlabelAlignment The corresponding JLabel horizontal alignment
|
||||
* number.
|
||||
*/
|
||||
HorizontalAlign(int jlabelAlignment) {
|
||||
this.jlabelAlignment = jlabelAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The corresponding JLabel horizontal alignment (i.e.
|
||||
* JLabel.LEFT).
|
||||
*/
|
||||
int getJLabelAlignment() {
|
||||
return this.jlabelAlignment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The root data object.
|
||||
*/
|
||||
Object getData();
|
||||
|
||||
/**
|
||||
* @return The text to be shown in the cell.
|
||||
*/
|
||||
default String getText() {
|
||||
Object data = getData();
|
||||
return (data == null) ? null : data.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The tooltip (if any) to be displayed in the cell.
|
||||
*/
|
||||
String getTooltip();
|
||||
|
||||
/**
|
||||
* @return The horizontal alignment for the text in the cell.
|
||||
*/
|
||||
HorizontalAlign getHorizontalAlignment();
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
*/
|
||||
/**
|
||||
* Describes aspects of a column which can be used with getTableModel or
|
||||
* getJTablePanel. 'T' represents the object that will represent rows in the
|
||||
* table.
|
||||
*/
|
||||
public class ColumnModel<T, C extends CellModel> {
|
||||
|
||||
private final String headerTitle;
|
||||
private final Function<T, ? extends C> cellRenderer;
|
||||
private final Integer width;
|
||||
|
||||
/**
|
||||
* Constructor for a DataResultColumnModel.
|
||||
*
|
||||
* @param headerTitle The title for the column.
|
||||
* @param cellRenderer The method that generates a CellModel for the column
|
||||
* based on the data.
|
||||
*/
|
||||
public ColumnModel(String headerTitle, Function<T, ? extends C> cellRenderer) {
|
||||
this(headerTitle, cellRenderer, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a DataResultColumnModel.
|
||||
*
|
||||
* @param headerTitle The title for the column.
|
||||
* @param cellRenderer The method that generates a CellModel for the column
|
||||
* based on the data.
|
||||
* @param width The preferred width of the column.
|
||||
*/
|
||||
public ColumnModel(String headerTitle, Function<T, ? extends C> cellRenderer, Integer width) {
|
||||
this.headerTitle = headerTitle;
|
||||
this.cellRenderer = cellRenderer;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The title for the column.
|
||||
*/
|
||||
public String getHeaderTitle() {
|
||||
return headerTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The method that generates a CellModel for the column based on the
|
||||
* data.
|
||||
*/
|
||||
public Function<T, ? extends C> getCellRenderer() {
|
||||
return cellRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The preferred width of the column (can be null).
|
||||
*/
|
||||
public Integer getWidth() {
|
||||
return width;
|
||||
}
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import java.awt.Insets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
*/
|
||||
/**
|
||||
* The default cell model.
|
||||
*/
|
||||
public class DefaultCellModel<T> implements GuiCellModel, ExcelCellModel {
|
||||
private final T data;
|
||||
private final Function<T, String> stringConverter;
|
||||
String tooltip;
|
||||
CellModel.HorizontalAlign horizontalAlignment;
|
||||
Insets insets;
|
||||
List<MenuItem> popupMenu;
|
||||
Supplier<List<MenuItem>> menuItemSupplier;
|
||||
private final String excelFormatString;
|
||||
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param text The text to be displayed in the cell.
|
||||
*/
|
||||
public DefaultCellModel(T data) {
|
||||
this(data, null, null);
|
||||
}
|
||||
|
||||
public DefaultCellModel(T data, Function<T, String> stringConverter, String excelFormatString) {
|
||||
this.data = data;
|
||||
this.stringConverter = stringConverter;
|
||||
this.excelFormatString = excelFormatString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public T getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExcelFormatString() {
|
||||
return this.excelFormatString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
if (this.stringConverter == null) {
|
||||
return this.data == null ? "" : this.data.toString();
|
||||
} else {
|
||||
return this.stringConverter.apply(this.data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip() {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tooltip for this cell model.
|
||||
*
|
||||
* @param tooltip The tooltip for the cell model.
|
||||
*
|
||||
* @return As a utility, returns this.
|
||||
*/
|
||||
public DefaultCellModel setTooltip(String tooltip) {
|
||||
this.tooltip = tooltip;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HorizontalAlign getHorizontalAlignment() {
|
||||
return horizontalAlignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the horizontal alignment for this cell model.
|
||||
*
|
||||
* @param alignment The horizontal alignment for the cell model.
|
||||
*
|
||||
* @return As a utility, returns this.
|
||||
*/
|
||||
public DefaultCellModel setHorizontalAlignment(CellModel.HorizontalAlign alignment) {
|
||||
this.horizontalAlignment = alignment;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getInsets() {
|
||||
return insets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the insets for the text within the cell
|
||||
*
|
||||
* @param insets The insets.
|
||||
*
|
||||
* @return As a utility, returns this.
|
||||
*/
|
||||
public DefaultCellModel setInsets(Insets insets) {
|
||||
this.insets = insets;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuItem> getPopupMenu() {
|
||||
if (popupMenu != null) {
|
||||
return Collections.unmodifiableList(popupMenu);
|
||||
}
|
||||
|
||||
if (menuItemSupplier != null) {
|
||||
return this.menuItemSupplier.get();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a function to lazy load the popup menu items.
|
||||
*
|
||||
* @param menuItemSupplier The lazy load function for popup items.
|
||||
* @return
|
||||
*/
|
||||
public DefaultCellModel setPopupMenuRetriever(Supplier<List<MenuItem>> menuItemSupplier) {
|
||||
this.menuItemSupplier = menuItemSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of items for a popup menu
|
||||
*
|
||||
* @param popupMenu
|
||||
* @return As a utility, returns this.
|
||||
*/
|
||||
public DefaultCellModel setPopupMenu(List<MenuItem> popupMenu) {
|
||||
this.popupMenu = popupMenu == null ? null : new ArrayList<>(popupMenu);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getText();
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
/**
|
||||
* Basic interface for a cell model.
|
||||
*/
|
||||
public interface ExcelCellModel extends CellModel {
|
||||
|
||||
/**
|
||||
* @return The format string to be used with Apache POI during excel export
|
||||
* or null if none necessary.
|
||||
*/
|
||||
String getExcelFormatString();
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
*/
|
||||
public class ExcelExport {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExcelExport.class.getName());
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// Create a Workbook
|
||||
Workbook workbook = new XSSFWorkbook(); // new HSSFWorkbook() for generating `.xls` file
|
||||
|
||||
// Create a Font for styling header cells
|
||||
Font headerFont = workbook.createFont();
|
||||
headerFont.setBold(true);
|
||||
//headerFont.setFontHeightInPoints((short) 14);
|
||||
|
||||
// Create a CellStyle with the font
|
||||
CellStyle headerCellStyle = workbook.createCellStyle();
|
||||
headerCellStyle.setFont(headerFont);
|
||||
|
||||
createSheet(workbook, headerCellStyle, GeolocationDTO.TEMPLATE_1, dtos1);
|
||||
createSheet(workbook, headerCellStyle, GeolocationDTO.TEMPLATE_2, dtos2);
|
||||
|
||||
// Write the output to a file
|
||||
FileOutputStream fileOut = new FileOutputStream("C:\\Users\\gregd\\Desktop\\datasourcesummary-export.xlsx");
|
||||
workbook.write(fileOut);
|
||||
fileOut.close();
|
||||
|
||||
// Closing the workbook
|
||||
workbook.close();
|
||||
}
|
||||
|
||||
public static <T, C extends ExcelCellModel> Sheet createSheet(
|
||||
Workbook workbook, CellStyle headerCellStyle, TableTemplate<T, C> tableTemplate, List<T> data)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
if (workbook == null || tableTemplate == null) {
|
||||
throw new IllegalArgumentException("workbook and tableTemplate parameters cannot be null");
|
||||
}
|
||||
|
||||
List<ColumnModel<T, C>> columns = tableTemplate.getColumns() != null
|
||||
? tableTemplate.getColumns()
|
||||
: Collections.emptyList();
|
||||
|
||||
List<T> safeData = data == null ? Collections.emptyList() : data;
|
||||
|
||||
Sheet sheet = workbook.createSheet(tableTemplate.getTabName());
|
||||
|
||||
// Create a header row
|
||||
Row headerRow = sheet.createRow(0);
|
||||
|
||||
// Create header cells
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
Cell cell = headerRow.createCell(i);
|
||||
cell.setCellValue(columns.get(i).getHeaderTitle());
|
||||
cell.setCellStyle(headerCellStyle);
|
||||
}
|
||||
|
||||
// freeze header row
|
||||
sheet.createFreezePane(0, 1);
|
||||
|
||||
// Create Cell Style for each column (if one is needed)
|
||||
Map<String, CellStyle> cellStyles = new HashMap<>();
|
||||
|
||||
for (int rowNum = 0; rowNum < safeData.size(); rowNum++) {
|
||||
T rowData = safeData.get(rowNum);
|
||||
Row row = sheet.createRow(rowNum + 1);
|
||||
|
||||
for (int colNum = 0; colNum < columns.size(); colNum++) {
|
||||
ColumnModel<T, ? extends ExcelCellModel> colModel = columns.get(colNum);
|
||||
ExcelCellModel cellModel = colModel.getCellRenderer().apply(rowData);
|
||||
String formatString = cellModel.getExcelFormatString();
|
||||
|
||||
Optional<CellStyle> cellStyle = (formatString == null)
|
||||
? Optional.empty()
|
||||
: Optional.of(cellStyles.computeIfAbsent(formatString, (k) -> getCellStyles(workbook, formatString)));
|
||||
|
||||
createCell(row, colNum, cellModel, cellStyle);
|
||||
}
|
||||
}
|
||||
|
||||
// Resize all columns to fit the content size
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
sheet.autoSizeColumn(i);
|
||||
}
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
private static Cell createCell(Row row, int colNum, ExcelCellModel cellModel, Optional<CellStyle> cellStyle) {
|
||||
Object cellData = cellModel.getData();
|
||||
|
||||
Cell cell = row.createCell(colNum);
|
||||
if (cellData instanceof Calendar) {
|
||||
cell.setCellValue((Calendar) cellData);
|
||||
} else if (cellData instanceof Date) {
|
||||
cell.setCellValue((Date) cellData);
|
||||
} else if (cellData instanceof Double) {
|
||||
cell.setCellValue((Double) cellData);
|
||||
} else if (cellData instanceof LocalDate) {
|
||||
cell.setCellValue((LocalDate) cellData);
|
||||
} else if (cellData instanceof LocalDateTime) {
|
||||
cell.setCellValue((LocalDateTime) cellData);
|
||||
} else if (cellData instanceof String) {
|
||||
cell.setCellValue((String) cellData);
|
||||
} else if (cellData instanceof Short) {
|
||||
cell.setCellValue((Short) cellData);
|
||||
} else if (cellData instanceof Integer) {
|
||||
cell.setCellValue((Integer) cellData);
|
||||
} else if (cellData instanceof Long) {
|
||||
cell.setCellValue((Long) cellData);
|
||||
} else if (cellData instanceof Float) {
|
||||
cell.setCellValue((Float) cellData);
|
||||
} else {
|
||||
cell.setCellValue(cellModel.getText());
|
||||
}
|
||||
|
||||
cellStyle.ifPresent((cs) -> cell.setCellStyle(cs));
|
||||
return cell;
|
||||
}
|
||||
|
||||
private static <T> CellStyle getCellStyles(Workbook workbook, String formatString) {
|
||||
CellStyle cellStyle = workbook.createCellStyle();
|
||||
cellStyle.setDataFormat(workbook.getCreationHelper().createDataFormat().getFormat(formatString));
|
||||
return cellStyle;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import java.awt.Insets;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Basic interface for a cell model.
|
||||
*/
|
||||
public interface GuiCellModel extends CellModel {
|
||||
|
||||
/**
|
||||
* A menu item to be used within a popup menu.
|
||||
*/
|
||||
public interface MenuItem {
|
||||
|
||||
/**
|
||||
* @return The title for that popup menu item.
|
||||
*/
|
||||
String getTitle();
|
||||
|
||||
/**
|
||||
* @return The action if that popup menu item is clicked.
|
||||
*/
|
||||
Runnable getAction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of a menu item.
|
||||
*/
|
||||
public static class DefaultMenuItem implements MenuItem {
|
||||
|
||||
private final String title;
|
||||
private final Runnable action;
|
||||
|
||||
/**
|
||||
* Main constructor.
|
||||
*
|
||||
* @param title The title for the menu item.
|
||||
* @param action The action should the menu item be clicked.
|
||||
*/
|
||||
public DefaultMenuItem(String title, Runnable action) {
|
||||
this.title = title;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Runnable getAction() {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The insets for the cell text.
|
||||
*/
|
||||
Insets getInsets();
|
||||
|
||||
/**
|
||||
* @return The popup menu associated with this cell or null if no popup menu
|
||||
* should be shown for this cell.
|
||||
*/
|
||||
List<MenuItem> getPopupMenu();
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author gregd
|
||||
*/
|
||||
public class TableTemplate<T, C extends CellModel> {
|
||||
|
||||
private final List<ColumnModel<T, C>> columns;
|
||||
private final String tabName;
|
||||
|
||||
public TableTemplate(List<ColumnModel<T, C>> columns, String tabName) {
|
||||
this.columns = columns;
|
||||
this.tabName = tabName;
|
||||
}
|
||||
|
||||
public List<ColumnModel<T, C>> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public String getTabName() {
|
||||
return tabName;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user