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..29b082c 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
@@ -25,6 +25,16 @@
* @return column name/header.
*/
String value() default "";
+
+ int index() default -1;
+
+
+// boolean isFormatted() default false;
+// String format() default "dd/MM/yyyy";
+//
+// boolean isFromula() default false;
+
+
/**
* Setting this to false will enable the null check on the Column values, to ensure
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..2a46862 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
@@ -66,7 +66,7 @@ public void addSheet(Class beanType, List rowObjects) {
}
public void addSheet(Class beanType, List rowObjects, List headers) {
- // SheetName
+ // SheetNameindex
Sheet sheet = beanType.getAnnotation(Sheet.class);
String sheetName = sheet != null ? sheet.value() : null;
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..cf4b75d 100644
--- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java
+++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java
@@ -10,8 +10,11 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,184 +24,238 @@
*/
public final class Spreadsheet {
- private static final Logger LOGGER = LoggerFactory.getLogger(Spreadsheet.class);
-
- private Spreadsheet() {
- // Utility Class
- }
-
-
- // Utilities
- // ------------------------------------------------------------------------
-
- /**
- * 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) {
- String cellColRef = cellRef.split("[0-9]*$")[0];
- return cellColRef;
- }
-
-
-
- // Bean :: Property Utils
-
- public static Map getPropertyToColumnNameMap(Class> beanType) {
- // Sanity checks
- if (beanType == null) {
- throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType);
- }
-
- // Property to Column name Mapping
- final Map mapping = new HashMap();
-
- // Fields
- Field[] fields = beanType.getDeclaredFields();
- for (Field f : fields) {
- String fieldName = f.getName();
- mapping.put(fieldName, fieldName);
-
- SheetColumn ec = f.getAnnotation(SheetColumn.class);
- if (ec != null && StringUtils.isNotEmpty(ec.value())) {
- mapping.put(fieldName, ec.value());
- }
- }
-
- // Methods
- 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());
- }
- }
-
- LOGGER.info("Bean property to Excel Column of - {} : {}", beanType, mapping);
- return Collections.unmodifiableMap(mapping);
- }
-
- public static Map getColumnToPropertyMap(Class> beanType) {
- // Column to Property Mapping
- final Map columnToPropMap = new HashMap();
-
- // Bean Property to Column Mapping
- final Map propToColumnMap = getPropertyToColumnNameMap(beanType);
- for (String prop : propToColumnMap.keySet()) {
- columnToPropMap.put(propToColumnMap.get(prop), prop);
- }
-
- LOGGER.info("Excel Column to property map of - {} : {}", beanType, columnToPropMap);
- return Collections.unmodifiableMap(columnToPropMap);
- }
-
- public static List getColumnNames(Class> beanType) {
- // Bean Property to Column Mapping
- final Map propToColumnMap = getPropertyToColumnNameMap(beanType);
-
- final ArrayList columnNames = new ArrayList<>(propToColumnMap.values());
- return columnNames;
- }
-
-
-
-
- // Read from Bean : as Row Data
- // ------------------------------------------------------------------------
-
- public static Map asRowDataMap(Object beanObj, List colHeaders) throws Exception {
- // Excel Bean Type
- final Class> beanType = beanObj.getClass();
-
- // RowData map
- final Map rowDataMap = new HashMap();
-
- // Fields
- for (Field f : beanType.getDeclaredFields()) {
- if (!f.isAnnotationPresent(SheetColumn.class)) {
- continue;
- }
-
- String fieldName = f.getName();
-
- SheetColumn ec = f.getAnnotation(SheetColumn.class);
- String header = StringUtils.isEmpty(ec.value()) ? fieldName : ec.value();
- if (!colHeaders.contains(header)) {
- continue;
- }
-
- rowDataMap.put(header, Beans.getFieldValueAsString(beanObj, fieldName));
- }
-
- // Methods
- for (Method m : beanType.getDeclaredMethods()) {
- if (!m.isAnnotationPresent(SheetColumn.class)) {
- continue;
- }
-
- String fieldName = Beans.getFieldName(m);
-
- SheetColumn ec = m.getAnnotation(SheetColumn.class);
- String header = StringUtils.isEmpty(ec.value()) ? fieldName : ec.value();
- if (!colHeaders.contains(header)) {
- continue;
- }
-
- rowDataMap.put(header, Beans.getFieldValueAsString(beanObj, fieldName));
- }
-
- return rowDataMap;
- }
-
-
-
- // Write to Bean :: from Row data
- // ------------------------------------------------------------------------
-
- public static T rowAsBean(Class beanClz, Map cellProperies, Map cellValues) {
- // Sanity checks
- if (cellValues == null || cellProperies == null) {
- return null;
- }
-
- try {
- // Create new Instance
- T rowBean = beanClz.newInstance();
-
- // Fill in the datat
- for (String cellName : cellProperies.keySet()) {
- String propName = cellProperies.get(cellName);
- if (StringUtils.isEmpty(propName)) {
- LOGGER.debug("{} : No mathching property found for column[name] - {} ", beanClz, cellName);
- continue;
- }
-
- Object propValue = cellValues.get(cellName);
- try {
- // Set the property value in the current row object bean
- BeanUtils.setProperty(rowBean, propName, propValue);
- } catch (IllegalAccessException | InvocationTargetException ex) {
- String errMsg = String.format("Failed to set bean property - %s, value - %s", propName, propValue);
- LOGGER.error(errMsg, ex);
- }
- }
-
- return rowBean;
- } catch (Exception ex) {
- String errMsg = String.format("Error while creating bean - %s, from - %s", beanClz, cellValues);
- LOGGER.error(errMsg, ex);
- }
-
- return null;
- }
-
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(Spreadsheet.class);
+
+ private Spreadsheet() {
+ // Utility Class
+ }
+
+ // Utilities
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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) {
+ String cellColRef = cellRef.split("[0-9]*$")[0];
+ return cellColRef;
+ }
+
+ // Bean :: Property Utils
+
+ public static Map getPropertyToColumnNameMap(Class> beanType) {
+ // Sanity checks
+ if (beanType == null) {
+ throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType);
+ }
+
+ // Property to Column name Mapping
+ final Map mapping = new HashMap();
+
+ // Fields
+ Field[] fields = beanType.getDeclaredFields();
+ for (Field f : fields) {
+ String fieldName = f.getName();
+ mapping.put(fieldName, fieldName);
+
+ SheetColumn ec = f.getAnnotation(SheetColumn.class);
+ if (ec != null && StringUtils.isNotEmpty(ec.value())) {
+ mapping.put(fieldName, ec.value());
+ }
+ }
+
+ // Methods
+ 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());
+ }
+ }
+
+ LOGGER.info("Bean property to Excel Column of - {} : {}", beanType, mapping);
+ return Collections.unmodifiableMap(mapping);
+ }
+
+ public static Map getColumnToPropertyMap(Class> beanType) {
+ // Column to Property Mapping
+ final Map columnToPropMap = new HashMap();
+
+ // Bean Property to Column Mapping
+ final Map propToColumnMap = getPropertyToColumnNameMap(beanType);
+ for (String prop : propToColumnMap.keySet()) {
+ columnToPropMap.put(propToColumnMap.get(prop), prop);
+ }
+
+ LOGGER.info("Excel Column to property map of - {} : {}", beanType, columnToPropMap);
+ return Collections.unmodifiableMap(columnToPropMap);
+ }
+
+ public static List getColumnNames(Class> beanType) {
+ // Bean Property to Column Mapping
+ final Map propToColumnMap = getPropertyToColumnNameMap(beanType);
+ final Map indexToPropMap = getIndexToPropertyMap(beanType);
+
+ Set indexes = indexToPropMap.keySet();
+ List indexList = new ArrayList(indexes);
+ Collections.sort(indexList);
+
+ ArrayList columnNames = new ArrayList<>();
+
+ for (Integer index : indexList) {
+ String colValue = propToColumnMap.get(indexToPropMap.get(index));
+ columnNames.add(colValue);
+ }
+ return columnNames;
+ }
+
+ // Read from Bean : as Row Data
+ // ------------------------------------------------------------------------
+
+ public static Map asRowDataMap(Object beanObj, List colHeaders) throws Exception {
+ // Excel Bean Type
+ final Class> beanType = beanObj.getClass();
+
+ // RowData map
+ final Map rowDataMap = new HashMap();
+
+ // Fields
+ for (Field f : beanType.getDeclaredFields()) {
+ if (!f.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+
+ String fieldName = f.getName();
+
+ SheetColumn ec = f.getAnnotation(SheetColumn.class);
+ String header = StringUtils.isEmpty(ec.value()) ? fieldName : ec.value();
+ if (!colHeaders.contains(header)) {
+ continue;
+ }
+
+ rowDataMap.put(header, Beans.getFieldValueAsString(beanObj, fieldName));
+ }
+
+ // Methods
+ for (Method m : beanType.getDeclaredMethods()) {
+ if (!m.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+
+ String fieldName = Beans.getFieldName(m);
+
+ SheetColumn ec = m.getAnnotation(SheetColumn.class);
+ String header = StringUtils.isEmpty(ec.value()) ? fieldName : ec.value();
+ if (!colHeaders.contains(header)) {
+ continue;
+ }
+
+ rowDataMap.put(header, Beans.getFieldValueAsString(beanObj, fieldName));
+ }
+
+ return rowDataMap;
+ }
+
+ // Write to Bean :: from Row data
+ // ------------------------------------------------------------------------
+
+ public static T rowAsBean(Class beanClz, Map cellProperies, Map cellValues) {
+ // Sanity checks
+ if (cellValues == null || cellProperies == null) {
+ return null;
+ }
+
+ try {
+ // Create new Instance
+ T rowBean = beanClz.newInstance();
+
+ // Fill in the datat
+ for (String cellName : cellProperies.keySet()) {
+ String propName = cellProperies.get(cellName);
+ if (StringUtils.isEmpty(propName)) {
+ LOGGER.debug("{} : No mathching property found for column[name] - {} ", beanClz, cellName);
+ continue;
+ }
+
+ Object propValue = cellValues.get(cellName);
+ try {
+ // Set the property value in the current row object bean
+ BeanUtils.setProperty(rowBean, propName, propValue);
+ } catch (IllegalAccessException | InvocationTargetException ex) {
+ String errMsg = String.format("Failed to set bean property - %s, value - %s", propName, propValue);
+ LOGGER.error(errMsg, ex);
+ }
+ }
+
+ return rowBean;
+ } catch (Exception ex) {
+ String errMsg = String.format("Error while creating bean - %s, from - %s", beanClz, cellValues);
+ LOGGER.error(errMsg, ex);
+ }
+
+ return null;
+ }
+
+ public static Map getIndexToPropertyMap(Class> beanType) {
+ // Sanity checks
+ if (Objects.isNull(beanType)) {
+ throw new IllegalArgumentException("getColumnIndexToPropertyMap :: Invalid ExcelBean type - " + beanType);
+ }
+
+ // Column Index to Property Mapping
+ final Map mapping = new HashMap();
+
+ // Fields
+ Field[] fields = beanType.getDeclaredFields();
+ for (Field f : fields) {
+ String fieldName = f.getName();
+
+ SheetColumn ec = f.getAnnotation(SheetColumn.class);
+ try {
+ if (ec != null && ec.index() == -1) {
+ throw new NullPointerException(
+ "Index must be intialized at annotation level for field " + fieldName);
+ } else {
+ mapping.put(ec.index(), fieldName);
+ }
+ } catch (NullPointerException ex) {
+ if (!Objects.isNull(ex.getMessage())) {
+ System.out.println("Error : " + ex.getMessage());
+ }
+ }
+ }
+
+ // Methods
+ Method[] methods = beanType.getDeclaredMethods();
+ for (Method m : methods) {
+ String fieldName = Beans.getFieldName(m);
+
+ SheetColumn ec = m.getAnnotation(SheetColumn.class);
+
+ try {
+ if (ec != null && ec.index() == -1) {
+ throw new NullPointerException(
+ "Index must be intialized at annotation level for field " + fieldName);
+ } else {
+ mapping.put(ec.index(), fieldName);
+ }
+ } catch (NullPointerException ex) {
+ if (!Objects.isNull(ex.getMessage())) {
+ System.out.println("Error : " + ex.getMessage());
+ }
+ }
+ }
+
+ LOGGER.info("Java Bean Index to Bean Property - {} : {}", beanType, mapping);
+ return mapping;
+ }
}
diff --git a/src/test/java/indexingCols/IndexedHeaderWriteTest.java b/src/test/java/indexingCols/IndexedHeaderWriteTest.java
new file mode 100644
index 0000000..b75dc2d
--- /dev/null
+++ b/src/test/java/indexingCols/IndexedHeaderWriteTest.java
@@ -0,0 +1,44 @@
+package indexingCols;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.github.millij.bean.Emp_indexed;
+import io.github.millij.bean.Employee;
+import io.github.millij.poi.ss.model.annotations.SheetColumn;
+import io.github.millij.poi.ss.writer.SpreadsheetWriter;
+import io.github.millij.poi.ss.writer.SpreadsheetWriterTest;
+
+public class IndexedHeaderWriteTest
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriterTest.class);
+
+ private final String _path_test_output = "test-cases/output/";
+
+
+
+ @Test
+ public void test_write_xlsx_single_sheet() throws IOException {
+ final String filepath_output_file = _path_test_output.concat("indexed_header_sample.xlsx");
+
+ // Excel Writer
+ LOGGER.info("test_write_xlsx_single_sheet :: Writing to file - {}", filepath_output_file);
+ SpreadsheetWriter gew = new SpreadsheetWriter(filepath_output_file);
+
+ // Employees
+ List employees = new ArrayList();
+ employees.add(new Emp_indexed("1", "foo", 12, "MALE", 1.68,"Chennai"));
+ employees.add(new Emp_indexed("2", "bar", 24, "MALE", 1.98,"Banglore"));
+ employees.add(new Emp_indexed("3", "foo bar", 10, "FEMALE",2.0,"Kolkata"));
+
+ // Write
+ gew.addSheet(Emp_indexed.class, employees);
+ gew.write();
+ }
+
+}
diff --git a/src/test/java/io/github/millij/bean/Emp_indexed.java b/src/test/java/io/github/millij/bean/Emp_indexed.java
new file mode 100644
index 0000000..5d948fb
--- /dev/null
+++ b/src/test/java/io/github/millij/bean/Emp_indexed.java
@@ -0,0 +1,102 @@
+package io.github.millij.bean;
+
+import io.github.millij.poi.ss.model.annotations.Sheet;
+import io.github.millij.poi.ss.model.annotations.SheetColumn;
+
+@Sheet
+public class Emp_indexed
+{
+ private String id;
+ private String name;
+
+ @SheetColumn(value="Age",index=2)
+ private Integer age;
+
+ @SheetColumn(value="Gender",index=3)
+ private String gender;
+
+ @SheetColumn(value="Height (mts)",index=4)
+ private Double height;
+
+ @SheetColumn(value="Address",index=5)
+ private String address;
+
+
+ public Emp_indexed() {
+ // Default
+ }
+
+ public Emp_indexed(String id, String name, Integer age, String gender, Double height,String address) {
+ super();
+
+ this.id = id;
+ this.name = name;
+ this.age = age;
+ this.gender = gender;
+ this.height = height;
+ this.address = address;
+
+ }
+
+
+
+ @SheetColumn(value="ID",index=0)
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @SheetColumn(value="Name",index=1)
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public Double getHeight() {
+ return height;
+ }
+
+ public void setHeight(Double height) {
+ this.height = height;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public String toString() {
+ return "Emp_indexed [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height
+ + ", address=" + address + "]";
+ }
+
+
+
+}
+