From 9c5dad35e0adc7e6a6ec452e915f71a2e117a79b Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 14:02:14 +0530 Subject: [PATCH 1/2] [Indexing and Sorting] Added primary code with indexing at Java class and sorting headers --- .../poi/ss/model/annotations/SheetColumn.java | 2 + .../github/millij/poi/util/Spreadsheet.java | 45 +++++++++ .../github/millij/bean/EmployeeIndexed.java | 98 +++++++++++++++++++ .../ss/writer/IndexedHeadersWriterTest.java | 44 +++++++++ 4 files changed, 189 insertions(+) create mode 100644 src/test/java/io/github/millij/bean/EmployeeIndexed.java create mode 100644 src/test/java/io/github/millij/poi/ss/writer/IndexedHeadersWriterTest.java 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..826b151 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; @@ -103,11 +104,55 @@ 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()) { + + 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))); + } + return indexedColumns; + } + + + 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; + } + String fieldName = f.getName(); + SheetColumn ec = f.getDeclaredAnnotation(SheetColumn.class); + indexToPropMap.put(ec.index(), StringUtils.isBlank(ec.value()) ? fieldName : ec.value()); + } + + 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); + indexToPropMap.put(ec.index(), StringUtils.isBlank(ec.value()) ? fieldName : ec.value()); + } + + 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..1367610 --- /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(); + } + +} From 6b43e96ff433e15afccae6bb4d477e58efcb83de Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 14:46:31 +0530 Subject: [PATCH 2/2] [Code Refactor] Added LOGGER and modified to handle more Test Cases --- .../github/millij/poi/util/Spreadsheet.java | 38 +++++++++++-------- .../github/millij/bean/EmployeeIndexed.java | 2 +- 2 files changed, 23 insertions(+), 17 deletions(-) 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 826b151..b262c47 100644 --- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java +++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java @@ -59,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()); } } @@ -108,19 +110,23 @@ public static List getColumnNames(Class beanType) { if (propToColumnMap.size() == indexToPropMap.size()) { - Set indexSet = indexToPropMap.keySet(); + 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; } @@ -135,9 +141,9 @@ public static Map getIndexToPropertyMap(Class beanClz) { if (!f.isAnnotationPresent(SheetColumn.class)) { continue; } - String fieldName = f.getName(); + final String fieldName = f.getName(); SheetColumn ec = f.getDeclaredAnnotation(SheetColumn.class); - indexToPropMap.put(ec.index(), StringUtils.isBlank(ec.value()) ? fieldName : ec.value()); + indexToPropMap.put(ec.index(), fieldName); } Method[] methods = beanClz.getDeclaredMethods(); @@ -145,15 +151,15 @@ public static Map getIndexToPropertyMap(Class beanClz) { if (!m.isAnnotationPresent(SheetColumn.class)) { continue; } - String fieldName = Beans.getFieldName(m); + final String fieldName = Beans.getFieldName(m); SheetColumn ec = m.getDeclaredAnnotation(SheetColumn.class); - indexToPropMap.put(ec.index(), StringUtils.isBlank(ec.value()) ? fieldName : ec.value()); + 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 index 1367610..ac0abe8 100644 --- a/src/test/java/io/github/millij/bean/EmployeeIndexed.java +++ b/src/test/java/io/github/millij/bean/EmployeeIndexed.java @@ -9,7 +9,7 @@ public class EmployeeIndexed { private String id; private String name; - @SheetColumn(value = "Age", index = 2) + @SheetColumn(value = "Age",index = 2) private Integer age; @SheetColumn(value = "Gender", index = 3)