diff --git a/src/main/java/io/github/millij/poi/ss/model/annotations/SheetColumn.java b/src/main/java/io/github/millij/poi/ss/model/annotations/SheetColumn.java
index e014a65..10d8562 100644
--- a/src/main/java/io/github/millij/poi/ss/model/annotations/SheetColumn.java
+++ b/src/main/java/io/github/millij/poi/ss/model/annotations/SheetColumn.java
@@ -26,6 +26,8 @@
*/
String value() default "";
+ String format() default "dd/MM/yyyy";
+
/**
* Setting this to false
will enable the null check on the Column values, to ensure
* non-null values for the field.
diff --git a/src/main/java/io/github/millij/poi/ss/reader/AbstractSpreadsheetReader.java b/src/main/java/io/github/millij/poi/ss/reader/AbstractSpreadsheetReader.java
index 7578272..887c895 100644
--- a/src/main/java/io/github/millij/poi/ss/reader/AbstractSpreadsheetReader.java
+++ b/src/main/java/io/github/millij/poi/ss/reader/AbstractSpreadsheetReader.java
@@ -2,14 +2,19 @@
import io.github.millij.poi.SpreadsheetReadException;
import io.github.millij.poi.ss.handler.RowListener;
+import io.github.millij.poi.ss.model.annotations.SheetColumn;
+import io.github.millij.poi.util.Beans;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -130,6 +135,44 @@ public void row(int rowNum, T rowObj) {
return sheetBeans;
}
+
+ public static String getReturnType(Class> beanClz, String header) {
+
+
+ String headerType = null;
+ // Fields
+ Field[] fields = beanClz.getDeclaredFields();
+ for (Field f : fields) {
+ if (!f.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+ String fieldName = f.getName();
+ SheetColumn ec = f.getDeclaredAnnotation(SheetColumn.class);
+ if (header.equals(fieldName) || header.equals(ec.value())) {
+ headerType = f.getType().getName();
+ }
+ continue;
+ }
+
+ // Methods
+ Method[] methods = beanClz.getDeclaredMethods();
+ for (Method m : methods) {
+ if (!m.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+ String fieldName = Beans.getFieldName(m);
+ SheetColumn ec = m.getDeclaredAnnotation(SheetColumn.class);
+ if (header.equals(fieldName) || header.equals(ec.value())) {
+ headerType = m.getReturnType().getName();
+ }
+ continue;
+ }
+ if (StringUtils.isBlank(headerType)) {
+ LOGGER.info("Failed to get the return type of the given Header '{}'", header);
+ }
+ return headerType;
+
+ }
}
diff --git a/src/main/java/io/github/millij/poi/ss/reader/SpreadsheetReader.java b/src/main/java/io/github/millij/poi/ss/reader/SpreadsheetReader.java
index 7761f3f..af60120 100644
--- a/src/main/java/io/github/millij/poi/ss/reader/SpreadsheetReader.java
+++ b/src/main/java/io/github/millij/poi/ss/reader/SpreadsheetReader.java
@@ -16,6 +16,7 @@
public interface SpreadsheetReader {
+ public static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy";
// Read with Custom RowListener
/**
diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java
index 5ed2aa8..207344f 100644
--- a/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java
+++ b/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java
@@ -1,15 +1,25 @@
package io.github.millij.poi.ss.reader;
import static io.github.millij.poi.util.Beans.isInstantiableType;
+
import io.github.millij.poi.SpreadsheetReadException;
import io.github.millij.poi.ss.handler.RowListener;
+import io.github.millij.poi.ss.writer.SpreadsheetWriter;
import io.github.millij.poi.util.Spreadsheet;
import java.io.InputStream;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
@@ -69,7 +79,7 @@ public void read(Class beanClz, InputStream is, RowListener listener)
LOGGER.error(errMsg, ex);
throw new SpreadsheetReadException(errMsg, ex);
}
-
+
}
@Override
@@ -81,7 +91,7 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener<
}
try {
- HSSFWorkbook wb = new HSSFWorkbook(is);
+ final HSSFWorkbook wb = new HSSFWorkbook(is);
final HSSFSheet sheet = wb.getSheetAt(sheetNo);
// Process Sheet
@@ -99,14 +109,14 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener<
// Sheet Process
-
+
protected void processSheet(Class beanClz, HSSFSheet sheet, int headerRowNo, RowListener eventHandler) {
// Header column - name mapping
- HSSFRow headerRow = sheet.getRow(headerRowNo);
- Map headerMap = this.extractCellHeaderMap(headerRow);
-
+ final HSSFRow headerRow = sheet.getRow(headerRowNo);
+ final Map headerMap = this.extractCellHeaderMap(headerRow);
+
// Bean Properties - column name mapping
- Map cellPropMapping = Spreadsheet.getColumnToPropertyMap(beanClz);
+ final Map cellPropMapping = Spreadsheet.getColumnToPropertyMap(beanClz);
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
@@ -117,7 +127,7 @@ protected void processSheet(Class beanClz, HSSFSheet sheet, int headerRow
continue; // Skip Header row
}
- Map rowDataMap = this.extractRowDataAsMap(row, headerMap);
+ final Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap);
if (rowDataMap == null || rowDataMap.isEmpty()) {
continue;
}
@@ -144,7 +154,7 @@ private Map extractCellHeaderMap(HSSFRow headerRow) {
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
- int cellCol = cell.getColumnIndex();
+ final int cellCol = cell.getColumnIndex();
// Process cell value
switch (cell.getCellTypeEnum()) {
@@ -169,7 +179,8 @@ private Map extractCellHeaderMap(HSSFRow headerRow) {
return cellHeaderMap;
}
- private Map extractRowDataAsMap(HSSFRow row, Map columnHeaderMap) {
+ private Map extractRowDataAsMap(Class beanClz, HSSFRow row,
+ Map columnHeaderMap) {
// Sanity checks
if (row == null) {
return new HashMap();
@@ -181,8 +192,8 @@ private Map extractRowDataAsMap(HSSFRow row, Map extractRowDataAsMap(HSSFRow row, Map extractRowDataAsMap(HSSFRow row, Map void read(Class beanClz, InputStream is, RowListener listener)
- throws SpreadsheetReadException {
+ public void read(Class beanClz, InputStream is, RowListener listener) throws SpreadsheetReadException {
// Sanity checks
if (!isInstantiableType(beanClz)) {
throw new IllegalArgumentException("XlsxReader :: Invalid bean type passed !");
}
try {
- final OPCPackage opcPkg = OPCPackage.open(is);
+ final XSSFWorkbook wb = new XSSFWorkbook(is);
+ final int sheetCount = wb.getNumberOfSheets();
+ LOGGER.debug("Total no. of sheets found in HSSFWorkbook : #{}", sheetCount);
- // XSSF Reader
- XSSFReader xssfReader = new XSSFReader(opcPkg);
-
- // Content Handler
- StylesTable styles = xssfReader.getStylesTable();
- ReadOnlySharedStringsTable ssTable = new ReadOnlySharedStringsTable(opcPkg);
- SheetContentsHandler sheetHandler = new RowContentsHandler(beanClz, listener, 0);
-
- ContentHandler handler = new XSSFSheetXMLHandler(styles, ssTable, sheetHandler, true);
+ // Iterate over sheets
+ for (int i = 0; i < sheetCount; i++) {
+ final XSSFSheet sheet = wb.getSheetAt(i);
+ LOGGER.debug("Processing HSSFSheet at No. : {}", i);
- // XML Reader
- XMLReader xmlParser = SAXHelper.newXMLReader();
- xmlParser.setContentHandler(handler);
+ // Process Sheet
+ this.processSheet(beanClz, sheet, 0, listener);
+ }
- // Iterate over sheets
- XSSFReader.SheetIterator worksheets = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
- for (int i = 0; worksheets.hasNext(); i++) {
- InputStream sheetInpStream = worksheets.next();
+ // Close workbook
+ wb.close();
- String sheetName = worksheets.getSheetName();
- // Parse sheet
- xmlParser.parse(new InputSource(sheetInpStream));
- sheetInpStream.close();
- }
} catch (Exception ex) {
String errMsg = String.format("Error reading sheet data, to Bean %s : %s", beanClz, ex.getMessage());
LOGGER.error(errMsg, ex);
@@ -87,7 +81,6 @@ public void read(Class beanClz, InputStream is, RowListener listener)
}
}
-
@Override
public void read(Class beanClz, InputStream is, int sheetNo, RowListener listener)
throws SpreadsheetReadException {
@@ -97,36 +90,14 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener<
}
try {
- final OPCPackage opcPkg = OPCPackage.open(is);
-
- // XSSF Reader
- XSSFReader xssfReader = new XSSFReader(opcPkg);
-
- // Content Handler
- StylesTable styles = xssfReader.getStylesTable();
- ReadOnlySharedStringsTable ssTable = new ReadOnlySharedStringsTable(opcPkg);
- SheetContentsHandler sheetHandler = new RowContentsHandler(beanClz, listener, 0);
+ final XSSFWorkbook wb = new XSSFWorkbook(is);
+ final XSSFSheet sheet = wb.getSheetAt(sheetNo);
- ContentHandler handler = new XSSFSheetXMLHandler(styles, ssTable, sheetHandler, true);
+ // Process Sheet
+ this.processSheet(beanClz, sheet, 0, listener);
- // XML Reader
- XMLReader xmlParser = SAXHelper.newXMLReader();
- xmlParser.setContentHandler(handler);
-
- // Iterate over sheets
- XSSFReader.SheetIterator worksheets = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
- for (int i = 0; worksheets.hasNext(); i++) {
- InputStream sheetInpStream = worksheets.next();
- if (i != sheetNo) {
- continue;
- }
-
- String sheetName = worksheets.getSheetName();
-
- // Parse Sheet
- xmlParser.parse(new InputSource(sheetInpStream));
- sheetInpStream.close();
- }
+ // Close workbook
+ wb.close();
} catch (Exception ex) {
String errMsg = String.format("Error reading sheet %d, to Bean %s : %s", sheetNo, beanClz, ex.getMessage());
@@ -135,6 +106,138 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener<
}
}
+ // Process Sheet
+ protected void processSheet(Class beanClz, XSSFSheet sheet, int headerRowNo, RowListener eventHandler) {
+ // Header column - name mapping
+ XSSFRow headerRow = sheet.getRow(headerRowNo);
+ final Map headerMap = this.extractCellHeaderMap(headerRow);
+
+ // Bean Properties - column name mapping
+ final Map cellPropMapping = Spreadsheet.getColumnToPropertyMap(beanClz);
+
+ Iterator rows = sheet.rowIterator();
+ while (rows.hasNext()) {
+ // Process Row Data
+ XSSFRow row = (XSSFRow) rows.next();
+ final int rowNum = row.getRowNum();
+ if (rowNum == 0) {
+ continue; // Skip Header row
+ }
+
+ final Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap);
+ if (rowDataMap == null || rowDataMap.isEmpty()) {
+ continue;
+ }
+
+ // Row data as Bean
+ T rowBean = Spreadsheet.rowAsBean(beanClz, cellPropMapping, rowDataMap);
+ eventHandler.row(rowNum, rowBean);
+ }
+ }
+
+
+ // Private Methods
+
+ private Map extractCellHeaderMap(XSSFRow headerRow) {
+ // Sanity checks
+ if (headerRow == null) {
+ return new HashMap();
+ }
+
+ final Map cellHeaderMap = new HashMap();
+
+ Iterator cells = headerRow.cellIterator();
+ while (cells.hasNext()) {
+ XSSFCell cell = (XSSFCell) cells.next();
+
+ final int cellCol = cell.getColumnIndex();
+
+ // Process cell value
+ switch (cell.getCellTypeEnum()) {
+ case STRING:
+ cellHeaderMap.put(cellCol, cell.getStringCellValue());
+ break;
+ case NUMERIC:
+
+ cellHeaderMap.put(cellCol, String.valueOf(cell.getNumericCellValue()));
+ break;
+
+ case BOOLEAN:
+ cellHeaderMap.put(cellCol, String.valueOf(cell.getBooleanCellValue()));
+ break;
+ case FORMULA:
+ case BLANK:
+ case ERROR:
+ break;
+ default:
+ break;
+ }
+ }
+
+ return cellHeaderMap;
+ }
+
+
+ private Map extractRowDataAsMap(Class> beanClz, XSSFRow row,
+ Map columnHeaderMap) {
+ // Sanity checks
+ if (row == null) {
+ return new HashMap();
+ }
+
+ final Map rowDataMap = new HashMap();
+
+ Iterator cells = row.cellIterator();
+ while (cells.hasNext()) {
+ XSSFCell cell = (XSSFCell) cells.next();
+
+ final int cellCol = cell.getColumnIndex();
+ final String cellColName = columnHeaderMap.get(cellCol);
+
+ // Process cell value
+ switch (cell.getCellTypeEnum()) {
+ case STRING:
+ rowDataMap.put(cellColName, cell.getStringCellValue());
+ break;
+ case NUMERIC:
+ if (DateUtil.isCellDateFormatted(cell)) {
+
+ // Checking Date or LocalDate
+
+ String headerType = AbstractSpreadsheetReader.getReturnType(beanClz, cellColName);
+ if (headerType.equals(Date.class.getName())) {
+ final Date date = cell.getDateCellValue();
+ rowDataMap.put(cellColName, date);
+ break;
+ }
+ if (headerType.equals(LocalDate.class.getName())) {
+
+ final Date ldate = cell.getDateCellValue();
+
+ // Convert Date to LocalDate
+ final Instant instant = ldate.toInstant();
+ final ZoneId zoneId = ZoneId.systemDefault();
+ final ZonedDateTime zonedDateTime = instant.atZone(zoneId);
+ final LocalDate localDate = zonedDateTime.toLocalDate();
+
+ rowDataMap.put(cellColName, localDate);
+ break;
+ }
+ }
+ case BOOLEAN:
+ rowDataMap.put(cellColName, cell.getBooleanCellValue());
+ break;
+ case FORMULA:
+ case BLANK:
+ case ERROR:
+ break;
+ default:
+ break;
+ }
+ }
+
+ return rowDataMap;
+ }
}
diff --git a/src/main/java/io/github/millij/poi/ss/writer/SpreadsheetWriter.java b/src/main/java/io/github/millij/poi/ss/writer/SpreadsheetWriter.java
index ddbdfa4..538e95e 100644
--- a/src/main/java/io/github/millij/poi/ss/writer/SpreadsheetWriter.java
+++ b/src/main/java/io/github/millij/poi/ss/writer/SpreadsheetWriter.java
@@ -1,21 +1,28 @@
package io.github.millij.poi.ss.writer;
-import io.github.millij.poi.ss.model.annotations.Sheet;
-import io.github.millij.poi.util.Spreadsheet;
-
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
@@ -23,16 +30,24 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.github.millij.poi.ss.model.annotations.Sheet;
+import io.github.millij.poi.ss.model.annotations.SheetColumn;
+import io.github.millij.poi.util.Beans;
+import io.github.millij.poi.util.Spreadsheet;
+
@Deprecated
public class SpreadsheetWriter {
private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class);
+ // Default Formats
+ private static final String DATE_DEFAULT_FORMAT = "EEE MMM dd HH:mm:ss zzz yyyy";
+ private static final String LOCAL_DATE_DEFAULT_FORMAT = "yyyy-MM-dd";
+
private final XSSFWorkbook workbook;
private final OutputStream outputStrem;
-
// Constructors
// ------------------------------------------------------------------------
@@ -51,13 +66,11 @@ public SpreadsheetWriter(OutputStream outputStream) {
this.outputStrem = outputStream;
}
-
// Methods
// ------------------------------------------------------------------------
-
// Sheet :: Add
-
+
public void addSheet(Class beanType, List rowObjects) {
// Sheet Headers
List headers = Spreadsheet.getColumnNames(beanType);
@@ -80,8 +93,7 @@ public void addSheet(Class beanType, List rowObjects, String sheetN
this.addSheet(beanType, rowObjects, headers, sheetName);
}
- public void addSheet(Class beanType, List rowObjects, List headers,
- String sheetName) {
+ public void addSheet(Class beanType, List rowObjects, List headers, String sheetName) {
// Sanity checks
if (beanType == null) {
throw new IllegalArgumentException("GenericExcelWriter :: ExcelBean type should not be null");
@@ -99,6 +111,8 @@ public void addSheet(Class beanType, List rowObjects, List
try {
XSSFSheet exSheet = workbook.getSheet(sheetName);
+ final CellStyle cellStyle = workbook.createCellStyle();
+ final CreationHelper createHelper = workbook.getCreationHelper();
if (exSheet != null) {
String errMsg = String.format("A Sheet with the passed name already exists : %s", sheetName);
throw new IllegalArgumentException(errMsg);
@@ -108,20 +122,59 @@ public void addSheet(Class beanType, List rowObjects, List
LOGGER.debug("Added new Sheet[name] to the workbook : {}", sheet.getSheetName());
// Header
- XSSFRow headerRow = sheet.createRow(0);
+ final XSSFRow headerRow = sheet.createRow(0);
for (int i = 0; i < headers.size(); i++) {
XSSFCell cell = headerRow.createCell(i);
cell.setCellValue(headers.get(i));
}
// Data Rows
- Map> rowsData = this.prepareSheetRowsData(headers, rowObjects);
+ final Map> rowsData = prepareSheetRowsData(headers, rowObjects);
+
+ final Map dateFormatsMap = getFormats(beanType);
+
for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) {
final XSSFRow row = sheet.createRow(rowNum);
int cellNo = 0;
for (String key : rowsData.keySet()) {
- Cell cell = row.createCell(cellNo);
+ final Cell cell = row.createCell(cellNo);
+
+ final String keyFormat = dateFormatsMap.get(key);
+ if (keyFormat != null) {
+
+ final String value = rowsData.get(key).get(i);
+ Date date;
+
+ try {
+ // Date Check
+ final SimpleDateFormat formatter = new SimpleDateFormat(DATE_DEFAULT_FORMAT);
+ date = formatter.parse(value);
+
+ } catch (ParseException e) {
+
+ try {
+ // LocalDate Check
+ final SimpleDateFormat formatter = new SimpleDateFormat(LOCAL_DATE_DEFAULT_FORMAT);
+ date = formatter.parse(value);
+ } catch (ParseException ex) {
+ cell.setCellValue(value);
+ cellNo++;
+ continue;
+ }
+ }
+
+ if (Objects.isNull(date)) {
+ continue;
+ }
+
+ cellStyle.setDataFormat(createHelper.createDataFormat().getFormat(keyFormat));
+ cell.setCellStyle(cellStyle);
+
+ cell.setCellValue(date);
+ cellNo++;
+ continue;
+ }
String value = rowsData.get(key).get(i);
cell.setCellValue(value);
cellNo++;
@@ -134,11 +187,8 @@ public void addSheet(Class beanType, List rowObjects, List
}
}
-
// Sheet :: Append to existing
-
-
// Write
public void write() throws IOException {
@@ -146,18 +196,17 @@ public void write() throws IOException {
workbook.close();
}
-
// Private Methods
// ------------------------------------------------------------------------
- private Map> prepareSheetRowsData(List headers,
- List rowObjects) throws Exception {
+ private Map> prepareSheetRowsData(List headers, List rowObjects)
+ throws Exception {
final Map> sheetData = new LinkedHashMap>();
// Iterate over Objects
for (EB excelBean : rowObjects) {
- Map row = Spreadsheet.asRowDataMap(excelBean, headers);
+ final Map row = Spreadsheet.asRowDataMap(excelBean, headers);
for (String header : headers) {
List data = sheetData.containsKey(header) ? sheetData.get(header) : new ArrayList();
@@ -171,6 +220,50 @@ private Map> prepareSheetRowsData(List headers
return sheetData;
}
+ public static Map getFormats(Class> beanType) {
+ if (beanType == null) {
+ throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType);
+ }
+ final Map headFormatMap = new HashMap();
+
+ // Fields
+ final Field[] fields = beanType.getDeclaredFields();
+
+ for (Field f : fields) {
+ if (!f.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+
+ final SheetColumn ec = f.getAnnotation(SheetColumn.class);
+
+ if (ec != null) {
+ final Class> fieldType = f.getType();
+ if (fieldType == Date.class || fieldType == LocalDate.class) {
+ final String value = ec.value();
+ headFormatMap.put(StringUtils.isNotBlank(value) ? value : f.getName(), ec.format());
+ }
+ }
+ }
+
+ // Methods
+ final Method[] methods = beanType.getDeclaredMethods();
+
+ for (Method m : methods) {
+ if (!m.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+
+ final String fieldName = Beans.getFieldName(m);
+ final Class> objType = m.getReturnType();
+
+ final SheetColumn ec = m.getAnnotation(SheetColumn.class);
+ if (objType == Date.class || objType == LocalDate.class) {
+ final String value = StringUtils.isBlank(ec.value()) ? fieldName : ec.value();
+ headFormatMap.put(value, ec.format());
+ }
+ }
+ return headFormatMap;
+ }
}
diff --git a/src/main/java/io/github/millij/poi/util/Spreadsheet.java b/src/main/java/io/github/millij/poi/util/Spreadsheet.java
index 5412bf5..7a98bb6 100644
--- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java
+++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java
@@ -1,21 +1,24 @@
package io.github.millij.poi.util;
-import io.github.millij.poi.ss.model.annotations.SheetColumn;
-
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.github.millij.poi.ss.model.annotations.SheetColumn;
+
+
/**
* Spreadsheet related utilites.
*/
@@ -35,6 +38,7 @@ private Spreadsheet() {
* Splits the CellReference and returns only the column reference.
*
* @param cellRef the cell reference value (ex. D3)
+ *
* @return returns the column index "D" from the cell reference "D3"
*/
public static String getCellColumnReference(String cellRef) {
@@ -56,28 +60,28 @@ public static Map getPropertyToColumnNameMap(Class> beanType)
final Map mapping = new HashMap();
// Fields
- Field[] fields = beanType.getDeclaredFields();
+ final Field[] fields = beanType.getDeclaredFields();
for (Field f : fields) {
- String fieldName = f.getName();
- mapping.put(fieldName, fieldName);
+ final String fieldName = f.getName();
SheetColumn ec = f.getAnnotation(SheetColumn.class);
- if (ec != null && StringUtils.isNotEmpty(ec.value())) {
- mapping.put(fieldName, ec.value());
+
+ if (ec != null) {
+ final String value = StringUtils.isNotEmpty(ec.value()) ? ec.value() : fieldName;
+ mapping.put(fieldName, value);
}
}
// Methods
- Method[] methods = beanType.getDeclaredMethods();
+ final Method[] methods = beanType.getDeclaredMethods();
for (Method m : methods) {
String fieldName = Beans.getFieldName(m);
- if (!mapping.containsKey(fieldName)) {
- mapping.put(fieldName, fieldName);
- }
SheetColumn ec = m.getAnnotation(SheetColumn.class);
- if (ec != null && StringUtils.isNotEmpty(ec.value())) {
- mapping.put(fieldName, ec.value());
+
+ if (ec != null && !mapping.containsKey(fieldName)) {
+ String value = StringUtils.isNotEmpty(ec.value()) ? ec.value() : fieldName;
+ mapping.put(fieldName, value);
}
}
@@ -108,7 +112,6 @@ public static List getColumnNames(Class> beanType) {
}
-
// Read from Bean : as Row Data
// ------------------------------------------------------------------------
@@ -180,7 +183,7 @@ public static T rowAsBean(Class beanClz, Map cellProperie
continue;
}
- Object propValue = cellValues.get(cellName);
+ Object propValue = Objects.isNull(cellValues.get(cellName)) ? cellValues.get(propName) : cellValues.get(cellName);
try {
// Set the property value in the current row object bean
BeanUtils.setProperty(rowBean, propName, propValue);
diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java
index 83ba764..33579e2 100644
--- a/src/test/java/io/github/millij/bean/Employee.java
+++ b/src/test/java/io/github/millij/bean/Employee.java
@@ -23,6 +23,11 @@ public class Employee {
@SheetColumn("Address")
private String address;
+ @SheetColumn(value = "Formula")
+ private String formula;
+
+ @SheetColumn(value = "Date", format = "yyyy/MM/dd")
+ private String date;
// Constructors
// ------------------------------------------------------------------------
@@ -31,7 +36,8 @@ public Employee() {
// Default
}
- public Employee(String id, String name, Integer age, String gender, Double height) {
+ public Employee(String id, String name, Integer age, String gender, Double height, String formula, String date,
+ String address) {
super();
this.id = id;
@@ -39,9 +45,11 @@ public Employee(String id, String name, Integer age, String gender, Double heigh
this.age = age;
this.gender = gender;
this.height = height;
+ this.date = date;
+ this.address = address;
+ this.formula = formula;
}
-
// Getters and Setters
// ------------------------------------------------------------------------
@@ -95,6 +103,21 @@ public void setAddress(String address) {
this.address = address;
}
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+
+ public String getFormula() {
+ return formula;
+ }
+
+ public void setFormula(String formula) {
+ this.formula = formula;
+ }
// Object Methods
// ------------------------------------------------------------------------
@@ -102,8 +125,7 @@ public void setAddress(String address) {
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height
- + ", address=" + address + "]";
+ + ", date=" + date + ", Formula=" + formula + "]";
}
-
}
diff --git a/src/test/java/io/github/millij/bean/Schedule.java b/src/test/java/io/github/millij/bean/Schedule.java
new file mode 100644
index 0000000..fb5ebd4
--- /dev/null
+++ b/src/test/java/io/github/millij/bean/Schedule.java
@@ -0,0 +1,73 @@
+package io.github.millij.bean;
+
+import java.time.LocalDate;
+import java.util.Date;
+
+// import java.util.Date;
+
+import io.github.millij.poi.ss.model.annotations.Sheet;
+import io.github.millij.poi.ss.model.annotations.SheetColumn;
+
+
+@Sheet("Schedules")
+public class Schedule {
+
+ @SheetColumn("Day")
+ private String day;
+
+ @SheetColumn(value = "Date", format = "dd/MM/yyyy")
+ private Date date;
+
+ @SheetColumn(value = "LocalDate", format = "dd/MM/yyyy")
+ private LocalDate localDate;
+
+ // Constructor
+ // -------------------------------------------------------------------------
+
+ public Schedule() {
+ super();
+ }
+
+ public Schedule(String day, Date date, LocalDate localDate) {
+ super();
+ this.day = day;
+ this.date = date;
+ this.localDate = localDate;
+ }
+
+ // Getters and Setters
+ // -------------------------------------------------------------------------
+
+
+ public String getDay() {
+ return day;
+ }
+
+ public void setDay(String day) {
+ this.day = day;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ public void setLocalDate(LocalDate localDate) {
+ this.localDate = localDate;
+ }
+
+ // Object Methods
+ // ------------------------------------------------------------------------
+ @Override
+ public String toString() {
+ return "Schedule [day=" + day + ", date=" + date + ", LocalDate=" + localDate + "]";
+ }
+
+}
diff --git a/src/test/java/io/github/millij/dates/DateTest.java b/src/test/java/io/github/millij/dates/DateTest.java
new file mode 100644
index 0000000..629f7a3
--- /dev/null
+++ b/src/test/java/io/github/millij/dates/DateTest.java
@@ -0,0 +1,90 @@
+package io.github.millij.dates;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.github.millij.bean.Schedule;
+import io.github.millij.poi.SpreadsheetReadException;
+import io.github.millij.poi.ss.reader.XlsReader;
+import io.github.millij.poi.ss.reader.XlsxReader;
+import io.github.millij.poi.ss.writer.SpreadsheetWriter;
+
+
+public class DateTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DateTest.class);
+
+ @Test
+ public void writeDatesTest() throws IOException, ParseException {
+
+ List schedules = new ArrayList();
+ final String filepath_output_file = "src/test/resources/sample-files/write_formatted_date_sample.xls";
+ SpreadsheetWriter gew = new SpreadsheetWriter(filepath_output_file);
+
+ SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
+ DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy");
+
+ Date date1 = formatter.parse("02/05/2001");
+ Date date2 = formatter.parse("03/06/2001");
+ LocalDate ldate1 = LocalDate.parse("02/05/2002", format);
+ LocalDate ldate2 = LocalDate.parse("03/06/2002", format);
+
+ // Schedules
+ schedules.add(new Schedule("Friday", date1, ldate1));
+ schedules.add(new Schedule("Saturday", date2, ldate2));
+
+ gew.addSheet(Schedule.class, schedules);
+ gew.write();
+ }
+
+ @Test
+ public void xlsx_read_dates_test() throws SpreadsheetReadException {
+ // Excel Reader
+ LOGGER.info("xlsx_read_dates_test :: Reading file - {}",
+ "src/test/resources/sample-files/write_formatted_date_sample.xlsx");
+ XlsxReader reader = new XlsxReader();
+
+ // Read
+ List schedules = reader.read(Schedule.class,
+ new File("src/test/resources/sample-files/write_formatted_date_sample.xlsx"));
+ Assert.assertNotNull(schedules);
+ Assert.assertTrue(schedules.size() > 0);
+
+ for (Schedule emp : schedules) {
+ LOGGER.info("xlsx_read_dates_test :: Output - {}", emp);
+ }
+
+ }
+
+ @Test
+ public void xls_read_dates_test() throws SpreadsheetReadException {
+ // Excel Reader
+ LOGGER.info("xlsx_read_dates_test :: Reading file - {}",
+ "src/test/resources/sample-files/xls_sample_read_dates.xls");
+ XlsReader reader = new XlsReader();
+
+ // Read
+ List schedules =
+ reader.read(Schedule.class, new File("src/test/resources/sample-files/xls_sample_read_dates.xls"));
+ Assert.assertNotNull(schedules);
+ Assert.assertTrue(schedules.size() > 0);
+
+ for (Schedule emp : schedules) {
+ LOGGER.info("xlsx_read_dates_test :: Output - {}", emp);
+ }
+
+ }
+
+}
diff --git a/src/test/java/io/github/millij/poi/ss/reader/XlsReaderTest.java b/src/test/java/io/github/millij/poi/ss/reader/XlsReaderTest.java
index dd3e056..f3511eb 100644
--- a/src/test/java/io/github/millij/poi/ss/reader/XlsReaderTest.java
+++ b/src/test/java/io/github/millij/poi/ss/reader/XlsReaderTest.java
@@ -1,6 +1,7 @@
package io.github.millij.poi.ss.reader;
import io.github.millij.bean.Company;
+
import io.github.millij.bean.Employee;
import io.github.millij.poi.SpreadsheetReadException;
import io.github.millij.poi.ss.handler.RowListener;
diff --git a/src/test/java/io/github/millij/poi/ss/writer/SpreadsheetWriterTest.java b/src/test/java/io/github/millij/poi/ss/writer/SpreadsheetWriterTest.java
index dd3b1c6..c52e8ce 100644
--- a/src/test/java/io/github/millij/poi/ss/writer/SpreadsheetWriterTest.java
+++ b/src/test/java/io/github/millij/poi/ss/writer/SpreadsheetWriterTest.java
@@ -55,9 +55,9 @@ public void test_write_xlsx_single_sheet() throws IOException {
// Employees
List employees = new ArrayList();
- employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
- employees.add(new Employee("2", "bar", null, "MALE", 1.68));
- employees.add(new Employee("3", "foo bar", null, null, null));
+ employees.add(new Employee("1", "foo", 12, "MALE", 1.68, "F2+G2", "02/11/2001", "Chennai"));
+ employees.add(new Employee("2", "bar", 24, "MALE", 1.98, "F3+G3", "03/11/2001", "Banglore"));
+ employees.add(new Employee("3", "foo bar", 10, "FEMALE", 2.0, "F4+G4", "04/11/2001", "Kolkata"));
// Write
gew.addSheet(Employee.class, employees);
@@ -74,9 +74,9 @@ public void test_write_xlsx_single_sheet_custom_headers() throws IOException {
// Employees
List employees = new ArrayList();
- employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
- employees.add(new Employee("2", "bar", null, "MALE", 1.68));
- employees.add(new Employee("3", "foo bar", null, null, null));
+ employees.add(new Employee("1", "foo", 12, "MALE", 1.68, "F2+G2", "02/11/2001", "Chennai"));
+ employees.add(new Employee("2", "bar", 24, "MALE", 1.98, "F3+G3", "03/11/2001", "Banglore"));
+ employees.add(new Employee("3", "foo bar", 10, "FEMALE", 2.0, "F4+G4", "04/11/2001", "Kolkata"));
List headers = Arrays.asList("ID", "Age", "Name", "Address");
@@ -98,9 +98,9 @@ public void test_write_xlsx_multiple_sheets() throws IOException {
// Employees
List employees = new ArrayList();
- employees.add(new Employee("1", "foo", 12, "MALE", 1.68));
- employees.add(new Employee("2", "bar", null, "MALE", 1.68));
- employees.add(new Employee("3", "foo bar", null, null, null));
+ employees.add(new Employee("1", "foo", 12, "MALE", 1.68, "F2+G2", "02/11/2001", "Chennai"));
+ employees.add(new Employee("2", "bar", 24, "MALE", 1.98, "F3+G3", "03/11/2001", "Banglore"));
+ employees.add(new Employee("3", "foo bar", 10, "FEMALE", 2.0, "F4+G4", "04/11/2001", "Kolkata"));
// Campanies
List companies = new ArrayList();
diff --git a/src/test/resources/sample-files/write_formatted_date_sample.xlsx b/src/test/resources/sample-files/write_formatted_date_sample.xlsx
new file mode 100644
index 0000000..bb02461
Binary files /dev/null and b/src/test/resources/sample-files/write_formatted_date_sample.xlsx differ
diff --git a/src/test/resources/sample-files/xls_sample_read_dates.xls b/src/test/resources/sample-files/xls_sample_read_dates.xls
new file mode 100644
index 0000000..2a443ca
Binary files /dev/null and b/src/test/resources/sample-files/xls_sample_read_dates.xls differ
diff --git a/src/test/resources/sample-files/xls_sample_single_sheet.xls b/src/test/resources/sample-files/xls_sample_single_sheet.xls
index 4865c52..7dc20cc 100644
Binary files a/src/test/resources/sample-files/xls_sample_single_sheet.xls and b/src/test/resources/sample-files/xls_sample_single_sheet.xls differ
diff --git a/src/test/resources/sample-files/xlsx_sample_multiple_sheets.xlsx b/src/test/resources/sample-files/xlsx_sample_multiple_sheets.xlsx
index 9b00f63..f0a14e8 100644
Binary files a/src/test/resources/sample-files/xlsx_sample_multiple_sheets.xlsx and b/src/test/resources/sample-files/xlsx_sample_multiple_sheets.xlsx differ
diff --git a/src/test/resources/sample-files/xlsx_sample_single_sheet.xlsx b/src/test/resources/sample-files/xlsx_sample_single_sheet.xlsx
index 06f9646..667c579 100644
Binary files a/src/test/resources/sample-files/xlsx_sample_single_sheet.xlsx and b/src/test/resources/sample-files/xlsx_sample_single_sheet.xlsx differ
| |