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