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..68a626a 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 "";
+ int index() default -1;
+
/**
* 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/util/Spreadsheet.java b/src/main/java/io/github/millij/poi/util/Spreadsheet.java
index 5412bf5..b262c47 100644
--- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java
+++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java
@@ -10,6 +10,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
@@ -58,26 +59,28 @@ public static Map getPropertyToColumnNameMap(Class> beanType)
// Fields
Field[] fields = beanType.getDeclaredFields();
for (Field f : fields) {
- String fieldName = f.getName();
- mapping.put(fieldName, fieldName);
+ if (!f.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+ 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) {
+ mapping.put(fieldName, StringUtils.isBlank(ec.value()) ? 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);
+ if (!m.isAnnotationPresent(SheetColumn.class)) {
+ continue;
}
+ final String fieldName = Beans.getFieldName(m);
SheetColumn ec = m.getAnnotation(SheetColumn.class);
- if (ec != null && StringUtils.isNotEmpty(ec.value())) {
- mapping.put(fieldName, ec.value());
+ if (ec != null) {
+ mapping.put(fieldName, StringUtils.isBlank(ec.value()) ? fieldName : ec.value());
}
}
@@ -103,12 +106,60 @@ public static List getColumnNames(Class> beanType) {
// Bean Property to Column Mapping
final Map propToColumnMap = getPropertyToColumnNameMap(beanType);
+ final Map indexToPropMap = getIndexToPropertyMap(beanType);
+
+ if (propToColumnMap.size() == indexToPropMap.size()) {
+
+ final Set indexSet = indexToPropMap.keySet();
+ List indexList = new ArrayList(indexSet);
+ Collections.sort(indexList);
+
+ List indexedColumns = new ArrayList();
+ for (Integer index : indexList) {
+ indexedColumns.add(propToColumnMap.get(indexToPropMap.get(index)));
+ if (index == -1) {
+ LOGGER.info("Writing One field : '{}' at first column as no index specified",
+ propToColumnMap.get(indexToPropMap.get(index)));
+ }
+ }
+ return indexedColumns;
+ }
+
+
+ LOGGER.info("Failed to write headers in partially indexed order. Proceeded to write in random order");
final ArrayList columnNames = new ArrayList<>(propToColumnMap.values());
return columnNames;
}
-
+ public static Map getIndexToPropertyMap(Class> beanClz) {
+
+ Map indexToPropMap = new HashMap();
+
+ Field[] fields = beanClz.getDeclaredFields();
+ for (Field f : fields) {
+ if (!f.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+ final String fieldName = f.getName();
+ SheetColumn ec = f.getDeclaredAnnotation(SheetColumn.class);
+ indexToPropMap.put(ec.index(), fieldName);
+ }
+
+ Method[] methods = beanClz.getDeclaredMethods();
+ for (Method m : methods) {
+ if (!m.isAnnotationPresent(SheetColumn.class)) {
+ continue;
+ }
+ final String fieldName = Beans.getFieldName(m);
+ SheetColumn ec = m.getDeclaredAnnotation(SheetColumn.class);
+ indexToPropMap.put(ec.index(), fieldName);
+ }
+
+ return indexToPropMap;
+ }
+
+
// Read from Bean : as Row Data
// ------------------------------------------------------------------------
diff --git a/src/test/java/io/github/millij/bean/EmployeeIndexed.java b/src/test/java/io/github/millij/bean/EmployeeIndexed.java
new file mode 100644
index 0000000..ac0abe8
--- /dev/null
+++ b/src/test/java/io/github/millij/bean/EmployeeIndexed.java
@@ -0,0 +1,98 @@
+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 EmployeeIndexed {
+ 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 EmployeeIndexed() {
+ // Default
+ }
+
+ public EmployeeIndexed(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 + "]";
+ }
+}
diff --git a/src/test/java/io/github/millij/poi/ss/writer/IndexedHeadersWriterTest.java b/src/test/java/io/github/millij/poi/ss/writer/IndexedHeadersWriterTest.java
new file mode 100644
index 0000000..774eb7f
--- /dev/null
+++ b/src/test/java/io/github/millij/poi/ss/writer/IndexedHeadersWriterTest.java
@@ -0,0 +1,44 @@
+package io.github.millij.poi.ss.writer;
+
+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.Employee;
+import io.github.millij.bean.EmployeeIndexed;
+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 IndexedHeadersWriterTest {
+ 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_writer_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 EmployeeIndexed("1", "foo", 12, "MALE", 1.68, "Chennai"));
+ employees.add(new EmployeeIndexed("2", "bar", 24, "MALE", 1.98, "Banglore"));
+ employees.add(new EmployeeIndexed("3", "foo bar", 10, "FEMALE", 2.0, "Kolkata"));
+
+ // Write
+ gew.addSheet(EmployeeIndexed.class, employees);
+ gew.write();
+ }
+
+}