From 92a2ea6f9eef6faac2ffdf34518b3ece53a75d07 Mon Sep 17 00:00:00 2001 From: harsha Date: Mon, 2 Oct 2023 14:58:09 +0530 Subject: [PATCH 01/21] Enhanced to read and write formatted dates and formulas. --- .../poi/ss/model/annotations/SheetColumn.java | 4 + .../millij/poi/ss/reader/XlsReader.java | 38 ++- .../millij/poi/ss/reader/XlsxReader.java | 140 ---------- .../poi/ss/reader/XlsxReader_ftDate.java | 263 ++++++++++++++++++ .../poi/ss/writer/SpreadsheetWriter.java | 135 ++++++++- .../java/io/github/millij/bean/Employee.java | 167 ++++++----- .../java/io/github/millij/bean/Schedule.java | 44 +++ .../java/io/github/millij/dates/DateTest.java | 34 +++ .../millij/poi/ss/reader/XlsxReaderTest.java | 13 +- .../poi/ss/writer/SpreadsheetWriterTest.java | 18 +- .../write_formatted_date_sample.xls | Bin 0 -> 3424 bytes .../sample-files/xls_sample_single_sheet.xls | Bin 6656 -> 6656 bytes .../xlsx_sample_multiple_sheets.xlsx | Bin 6295 -> 6783 bytes .../xlsx_sample_single_sheet.xlsx | Bin 5028 -> 5452 bytes 14 files changed, 619 insertions(+), 237 deletions(-) delete mode 100644 src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java create mode 100644 src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java create mode 100644 src/test/java/io/github/millij/bean/Schedule.java create mode 100644 src/test/java/io/github/millij/dates/DateTest.java create mode 100644 src/test/resources/sample-files/write_formatted_date_sample.xls 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..bd72e3f 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,10 @@ * @return column name/header. */ String value() default ""; + 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/reader/XlsReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java index 5ed2aa8..284a15c 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,22 @@ 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.LocalDateTime; +import java.time.ZoneId; +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; @@ -117,7 +124,7 @@ protected void processSheet(Class beanClz, HSSFSheet sheet, int headerRow continue; // Skip Header row } - Map rowDataMap = this.extractRowDataAsMap(row, headerMap); + Map rowDataMap = this.extractRowDataAsMap(beanClz,row, headerMap); if (rowDataMap == null || rowDataMap.isEmpty()) { continue; } @@ -169,7 +176,7 @@ 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(); @@ -190,12 +197,35 @@ private Map extractRowDataAsMap(HSSFRow row, Map formats = SpreadsheetWriter.getFormats(beanClz); + String cellFormat = formats.get(cellColName); + + Date date = cell.getDateCellValue(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + + DateTimeFormatter formatter = null; + if (cellFormat != null) { + formatter = DateTimeFormatter.ofPattern(cellFormat); + } else { + formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + } + + String formattedDateTime = localDateTime.format(formatter); + rowDataMap.put(cellColName, formattedDateTime); + break; + + } else { + rowDataMap.put(cellColName, cell.getNumericCellValue()); + break; + } + case BOOLEAN: rowDataMap.put(cellColName, cell.getBooleanCellValue()); break; case FORMULA: + rowDataMap.put(cellColName, cell.getCellFormula()); case BLANK: case ERROR: break; diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java deleted file mode 100644 index 0c66f8a..0000000 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ /dev/null @@ -1,140 +0,0 @@ -package io.github.millij.poi.ss.reader; - -import static io.github.millij.poi.util.Beans.isInstantiableType; - -import java.io.InputStream; - -import org.apache.poi.ooxml.util.SAXHelper; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; -import org.apache.poi.xssf.eventusermodel.XSSFReader; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; -import org.apache.poi.xssf.model.StylesTable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; - -import io.github.millij.poi.SpreadsheetReadException; -import io.github.millij.poi.ss.handler.RowContentsHandler; -import io.github.millij.poi.ss.handler.RowListener; - - -/** - * Reader impletementation of {@link Workbook} for an OOXML .xlsx file. This implementation is - * suitable for low memory sax parsing or similar. - * - * @see XlsReader - */ -public class XlsxReader extends AbstractSpreadsheetReader { - - private static final Logger LOGGER = LoggerFactory.getLogger(XlsxReader.class); - - - // Constructor - - public XlsxReader() { - super(); - } - - - // SpreadsheetReader Impl - // ------------------------------------------------------------------------ - - @Override - 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); - - // 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); - - // 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(); - - 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); - throw new SpreadsheetReadException(errMsg, ex); - } - } - - - @Override - public void read(Class beanClz, InputStream is, int sheetNo, RowListener listener) - throws SpreadsheetReadException { - // Sanity checks - if (!isInstantiableType(beanClz)) { - throw new IllegalArgumentException("XlsxReader :: Invalid bean type passed !"); - } - - 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); - - ContentHandler handler = new XSSFSheetXMLHandler(styles, ssTable, sheetHandler, true); - - // 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(); - } - - } catch (Exception ex) { - String errMsg = String.format("Error reading sheet %d, to Bean %s : %s", sheetNo, beanClz, ex.getMessage()); - LOGGER.error(errMsg, ex); - throw new SpreadsheetReadException(errMsg, ex); - } - } - - - -} diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java new file mode 100644 index 0000000..e5fb0ec --- /dev/null +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java @@ -0,0 +1,263 @@ +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.RowContentsHandler; +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.LocalDateTime; +import java.time.ZoneId; +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.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Workbook; +//import org.apache.poi.util.SAXHelper; +import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; +import org.apache.poi.xssf.eventusermodel.XSSFReader; +import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; +import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; +import org.apache.poi.xssf.model.StylesTable; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + + +/** + * Reader impletementation of {@link Workbook} for an OOXML .xlsx file. This implementation is + * suitable for low memory sax parsing or similar. + * + * @see XlsReader + */ +public class XlsxReader_ftDate extends AbstractSpreadsheetReader { + + private static final Logger LOGGER = LoggerFactory.getLogger(XlsxReader_ftDate.class); + + + // Constructor + + public XlsxReader_ftDate() { + super(); + } + + + // SpreadsheetReader Impl + // ------------------------------------------------------------------------ + + @Override + public void read(Class beanClz, InputStream is, RowListener listener) + throws SpreadsheetReadException { + // Sanity checks + if (!isInstantiableType(beanClz)) { + throw new IllegalArgumentException("XlsxReader_ftDate :: Invalid bean type passed !"); + } + + try { + final XSSFWorkbook wb = new XSSFWorkbook(is); + final int sheetCount = wb.getNumberOfSheets(); + LOGGER.debug("Total no. of sheets found in HSSFWorkbook : #{}", sheetCount); + + // Iterate over sheets + for (int i = 0; i < sheetCount; i++) { + final XSSFSheet sheet = wb.getSheetAt(i); + LOGGER.debug("Processing HSSFSheet at No. : {}", i); + + // Process Sheet + this.processSheet(beanClz, sheet, 0, listener); + } + + // Close workbook + wb.close(); + + + } catch (Exception ex) { + String errMsg = String.format("Error reading sheet data, to Bean %s : %s", beanClz, ex.getMessage()); + LOGGER.error(errMsg, ex); + throw new SpreadsheetReadException(errMsg, ex); + } + } + + @Override + public void read(Class beanClz, InputStream is, int sheetNo, RowListener listener) + throws SpreadsheetReadException { + // Sanity checks + if (!isInstantiableType(beanClz)) { + throw new IllegalArgumentException("XlsReader :: Invalid bean type passed !"); + } + + try { + XSSFWorkbook wb = new XSSFWorkbook(is); + final XSSFSheet sheet = wb.getSheetAt(sheetNo); + + // Process Sheet + this.processSheet(beanClz, sheet, 0, listener); + + // Close workbook + wb.close(); + + } catch (Exception ex) { + String errMsg = String.format("Error reading sheet %d, to Bean %s : %s", sheetNo, beanClz, ex.getMessage()); + LOGGER.error(errMsg, ex); + throw new SpreadsheetReadException(errMsg, ex); + } + } + + //Process Sheet + + protected void processSheet(Class beanClz, XSSFSheet sheet, int headerRowNo, RowListener eventHandler) { + // Header column - name mapping + XSSFRow headerRow = sheet.getRow(headerRowNo); + Map headerMap = this.extractCellHeaderMap(headerRow); + System.out.println(headerMap); + // Bean Properties - column name mapping + Map cellPropMapping = Spreadsheet.getColumnToPropertyMap(beanClz); + System.out.println(cellPropMapping); + Iterator rows = sheet.rowIterator(); + while (rows.hasNext()) { + // Process Row Data + XSSFRow row = (XSSFRow) rows.next(); + int rowNum = row.getRowNum(); + if (rowNum == 0) { + continue; // Skip Header row + } + + 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(); + + 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(); + + int cellCol = cell.getColumnIndex(); + 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)) { + + Map formats = SpreadsheetWriter.getFormats(beanClz); + String cellFormat = formats.get(cellColName); + + Date date = cell.getDateCellValue(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + + DateTimeFormatter formatter = null; + if (cellFormat != null) { + formatter = DateTimeFormatter.ofPattern(cellFormat); + } else { + formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + } + + String formattedDateTime = localDateTime.format(formatter); + rowDataMap.put(cellColName, formattedDateTime); + break; + + } else { + rowDataMap.put(cellColName, cell.getNumericCellValue()); + break; + } + + case BOOLEAN: + rowDataMap.put(cellColName, cell.getBooleanCellValue()); + break; + case FORMULA: + rowDataMap.put(cellColName, cell.getCellFormula()); + 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..6673173 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,6 +1,7 @@ package io.github.millij.poi.ss.writer; import io.github.millij.poi.ss.model.annotations.Sheet; +import io.github.millij.poi.ss.model.annotations.SheetColumn; import io.github.millij.poi.util.Spreadsheet; import java.io.File; @@ -8,7 +9,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -118,13 +124,52 @@ public void addSheet(Class beanType, List rowObjects, List Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { final XSSFRow row = sheet.createRow(rowNum); - + + Map dateFormatsMap = this.getFormats(beanType); + + List formulaCols = this.getFormulaCols(beanType); + int cellNo = 0; for (String key : rowsData.keySet()) { Cell cell = row.createCell(cellNo); - String value = rowsData.get(key).get(i); - cell.setCellValue(value); - cellNo++; + + String keyFormat = dateFormatsMap.get(key); + if(keyFormat != null) + { + + try { + + String value = rowsData.get(key).get(i); + + + LocalDate harsha = LocalDate.parse(value,DateTimeFormatter.ofPattern("dd/MM/yyyy")); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); + + String formattedDateTime = harsha.format(formatter); + + cell.setCellValue(formattedDateTime); + cellNo++; + + } + catch(Exception e) + { + e.printStackTrace(); + } + + } + else if(formulaCols.contains(key)){ + String value = rowsData.get(key).get(i); + cell.setCellFormula(value); + cellNo++; + + } + else { + + String value = rowsData.get(key).get(i); + cell.setCellValue(value); + cellNo++; + } } } @@ -170,6 +215,88 @@ private Map> prepareSheetRowsData(List headers return sheetData; } + + + public static Map getFormats(Class beanType) + { + + if (beanType == null) { + throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); + } + + Map headFormatMap = new HashMap(); + + // Fields + Field[] fields = beanType.getDeclaredFields(); + + for (Field f : fields) { + + SheetColumn ec = f.getAnnotation(SheetColumn.class); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) + { + if(ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); + } + } + + // Methods + Method[] methods = beanType.getDeclaredMethods(); + + for (Method m : methods) { + + SheetColumn ec = m.getAnnotation(SheetColumn.class); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) + { + if(ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); + } + } + + return headFormatMap; + } + + + public static List getFormulaCols(Class beanType) + { + if (beanType == null) { + throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); + } + + List formulaCols = new ArrayList(); + + // Fields + Field[] fields = beanType.getDeclaredFields(); + + for (Field f : fields) { + + SheetColumn ec = f.getAnnotation(SheetColumn.class); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) + { + if(ec.isFromula()) + formulaCols.add(ec.value()); + } + } + + // Methods + Method[] methods = beanType.getDeclaredMethods(); + + for (Method m : methods) { + + SheetColumn ec = m.getAnnotation(SheetColumn.class); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) + { + if(ec.isFromula()) + formulaCols.add(ec.value()); + } + } + + return formulaCols; + + } diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java index 83ba764..5491fea 100644 --- a/src/test/java/io/github/millij/bean/Employee.java +++ b/src/test/java/io/github/millij/bean/Employee.java @@ -3,107 +3,128 @@ import io.github.millij.poi.ss.model.annotations.Sheet; import io.github.millij.poi.ss.model.annotations.SheetColumn; - @Sheet public class Employee { - // Note that Id and Name are annotated at name level - private String id; - private String name; - - @SheetColumn("Age") - private Integer age; + // Note that Id and Name are annotated at name level + private String id; + private String name; - @SheetColumn("Gender") - private String gender; + @SheetColumn("Age") + private Integer age; - @SheetColumn("Height (mts)") - private Double height; + @SheetColumn("Gender") + private String gender; - @SheetColumn("Address") - private String address; + @SheetColumn("Height (mts)") + private Double height; + @SheetColumn("Address") + private String address; - // Constructors - // ------------------------------------------------------------------------ + @SheetColumn(value = "Formula", isFromula = true) + private String formula; - public Employee() { - // Default - } + @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") + private String date; - public Employee(String id, String name, Integer age, String gender, Double height) { - super(); + // Constructors + // ------------------------------------------------------------------------ - this.id = id; - this.name = name; - this.age = age; - this.gender = gender; - this.height = height; - } + public Employee() { + // Default + } + public Employee(String id, String name, Integer age, String gender, Double height, String formula, String date, + String address) { + super(); - // Getters and Setters - // ------------------------------------------------------------------------ + this.id = id; + this.name = name; + this.age = age; + this.gender = gender; + this.height = height; + this.date = date; + this.address = address; + this.formula = formula; + } - @SheetColumn("ID") - public String getId() { - return id; - } + // Getters and Setters + // ------------------------------------------------------------------------ - public void setId(String id) { - this.id = id; - } + @SheetColumn("ID") + public String getId() { + return id; + } - @SheetColumn("Name") - public String getName() { - return name; - } + public void setId(String id) { + this.id = id; + } - public void setName(String name) { - this.name = name; - } + @SheetColumn("Name") + public String getName() { + return name; + } - public Integer getAge() { - return age; - } + public void setName(String name) { + this.name = name; + } - public void setAge(Integer age) { - this.age = age; - } + public Integer getAge() { + return age; + } - public String getGender() { - return gender; - } + public void setAge(Integer age) { + this.age = age; + } - public void setGender(String gender) { - this.gender = gender; - } + public String getGender() { + return gender; + } - public Double getHeight() { - return height; - } + public void setGender(String gender) { + this.gender = gender; + } - public void setHeight(Double height) { - this.height = height; - } + public Double getHeight() { + return height; + } - public String getAddress() { - return address; - } + public void setHeight(Double height) { + this.height = height; + } - public void setAddress(String address) { - this.address = address; - } + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } - // Object Methods - // ------------------------------------------------------------------------ + public String getDate() { + return date; + } - @Override - public String toString() { - return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height - + ", address=" + address + "]"; - } + public void setDate(String date) { + this.date = date; + } + public String getFormula() { + return formula; + } + + public void setFormula(String formula) { + this.formula = formula; + } + + // Object Methods + // ------------------------------------------------------------------------ + + @Override + public String toString() { + return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height + + ", date=" + date + ", Address =" + address + ", 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..bea877e --- /dev/null +++ b/src/test/java/io/github/millij/bean/Schedule.java @@ -0,0 +1,44 @@ +package io.github.millij.bean; + +//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", isFormatted = true, format = "yyyy/MM/dd") + private String date; + + public Schedule(String day, String date) { + super(); + this.day = day; + this.date = date; + } + + public String getDay() { + return day; + } + + public void setDay(String day) { + this.day = day; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + @Override + public String toString() { + return "Schedules [day=" + day + ", date=" + date + "]"; + } + +} 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..573d090 --- /dev/null +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -0,0 +1,34 @@ +package io.github.millij.dates; + +import java.io.FileNotFoundException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import io.github.millij.bean.Schedule; +//import io.github.millij.bean.Schedules; +import io.github.millij.poi.ss.writer.SpreadsheetWriter; + +//import io.github.millij.bean.Schedules; + +public class DateTest { + + @Test + public void writeDatesTest() throws IOException { + + 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); + + // Schedules + schedules.add(new Schedule("Friday", "02/11/2001")); + schedules.add(new Schedule("Saturday", "16/09/2023")); + + gew.addSheet(Schedule.class, schedules); + gew.write(); + } + +} diff --git a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java index f33df25..38e5218 100644 --- a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java +++ b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java @@ -4,7 +4,6 @@ import io.github.millij.bean.Employee; import io.github.millij.poi.SpreadsheetReadException; import io.github.millij.poi.ss.handler.RowListener; -import io.github.millij.poi.ss.reader.XlsxReader; import java.io.File; import java.io.FileInputStream; @@ -57,7 +56,7 @@ public void teardown() { public void test_read_xlsx_single_sheet() throws SpreadsheetReadException { // Excel Reader LOGGER.info("test_read_xlsx_single_sheet :: Reading file - {}", _filepath_xlsx_single_sheet); - XlsxReader reader = new XlsxReader(); + XlsxReader_ftDate reader = new XlsxReader_ftDate(); // Read List employees = reader.read(Employee.class, new File(_filepath_xlsx_single_sheet)); @@ -74,7 +73,7 @@ public void test_read_xlsx_single_sheet() throws SpreadsheetReadException { public void test_read_xlsx_multiple_sheets() throws SpreadsheetReadException { // Excel Reader LOGGER.info("test_read_xlsx_multiple_sheets :: Reading file - {}", _filepath_xlsx_multiple_sheets); - XlsxReader ger = new XlsxReader(); + XlsxReader_ftDate ger = new XlsxReader_ftDate(); // Read Sheet 1 List employees = ger.read(Employee.class, new File(_filepath_xlsx_multiple_sheets), 0); @@ -103,7 +102,7 @@ public void test_read_xlsx_multiple_sheets() throws SpreadsheetReadException { public void test_read_xlsx_single_sheet_from_stream() throws SpreadsheetReadException, FileNotFoundException { // Excel Reader LOGGER.info("test_read_xlsx_single_sheet_from_stream :: Reading file - {}", _filepath_xlsx_single_sheet); - XlsxReader reader = new XlsxReader(); + XlsxReader_ftDate reader = new XlsxReader_ftDate(); // InputStream final InputStream fis = new FileInputStream(new File(_filepath_xlsx_single_sheet)); @@ -122,7 +121,7 @@ public void test_read_xlsx_single_sheet_from_stream() throws SpreadsheetReadExce public void test_read_xlsx_multiple_sheets_from_stream() throws SpreadsheetReadException, FileNotFoundException { // Excel Reader LOGGER.info("test_read_xlsx_multiple_sheets_from_stream :: Reading file - {}", _filepath_xlsx_multiple_sheets); - XlsxReader reader = new XlsxReader(); + XlsxReader_ftDate reader = new XlsxReader_ftDate(); // InputStream final InputStream fisSheet1 = new FileInputStream(new File(_filepath_xlsx_multiple_sheets)); @@ -163,7 +162,7 @@ public void test_read_xlsx_single_sheet_with_callback() throws SpreadsheetReadEx final List employees = new ArrayList(); // Read - XlsxReader reader = new XlsxReader(); + XlsxReader_ftDate reader = new XlsxReader_ftDate(); reader.read(Employee.class, xlsxFile, new RowListener() { @Override @@ -187,7 +186,7 @@ public void row(int rowNum, Employee employee) { public void test_read_xlsx_as_Map() throws FileNotFoundException { // Excel Reader LOGGER.info("test_read_xlsx_as_Map :: Reading file - {}", _filepath_xlsx_single_sheet); - XlsxReader ger = new XlsxReader(); + XlsxReader_ftDate ger = new XlsxReader_ftDate(); // Read /* 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..453182a 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.xls b/src/test/resources/sample-files/write_formatted_date_sample.xls new file mode 100644 index 0000000000000000000000000000000000000000..6766eb0315f2a9d87f07b93c74356f5488573667 GIT binary patch literal 3424 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 delta 1127 zcmb_aOH30{6g_WdT82`XT4;fo=)@S~rzoG%7+0+gAqp7Oh|!Iy!eWx9HGBj~WYDl+ zX?R=X%7yMUb?E{VcDhnxOxzk1H-wEFBjUN!QXp*QFsz1QjZU-hC79?s$%^m_c*tpk)SPnV_&e#ss6$7eEbJ|`8u1TZk|7yUx1 z?B)v-MZe^yphl=%WF?o1MOG+>`uV!PNA+q2ooVhc(|AxBXwIu3hDV5VIAE#C32)(w zXSHRA8!-38Em&CFl^;O_>xXypqk!7hgV7S|a&i1)1h&B$s&=5nSWv0ZDMX%%56TIB zoSEW#eO&s!Jbr?GKE9KOd-S9M=GJ_A$+N{!Nfow!#R#=@Mzs7dgldU`W zP^)K!D#===jOw7Z#$-qbZFMFSrO4)WXY!yfBxhP|b|G7^c}!FPNM6#}){VgCE}Fvt zaG$qqf0mHsMM9c=N=Uh9gcN#7$hzJVGW7}}YxqdSh_6Hw@tu&L+6Eyt{t%-7a}zkk zo23i9>g2!JQlOj2hHCr>i*2qxY9%TwZCRy9QrYG7tb%@+4vf*5{+*svC-roDpfdVb adl2p7tMf|Fb<9P2X-?@}YEZ9Q@BRUagOtkv 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 9b00f632f9cea9bfdbafae8db0225cdb5a365032..f0a14e8bf35ead0e95c4d54233f47a6ddc232863 100644 GIT binary patch delta 5772 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 F`X5*-P}Beb delta 5281 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 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 06f9646883cd457f32dd26079029237f7a01bcd1..667c57969a26f061f676dcf72d10e9df30bddaf5 100644 GIT binary patch delta 4606 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 delta 4064 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 From 9327ba4b9d0eae584bb9375c25c2cc35f106f1ad Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 3 Oct 2023 10:08:17 +0530 Subject: [PATCH 02/21] Issue-27 fix --- .../github/millij/poi/util/Spreadsheet.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 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 5412bf5..5c52edc 100644 --- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java +++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java @@ -59,11 +59,14 @@ public static Map getPropertyToColumnNameMap(Class beanType) 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()); + + if (ec != null) { + String value = StringUtils.isNotEmpty(ec.value()) + ? ec.value() + : fieldName; + mapping.put(fieldName, value); } } @@ -71,13 +74,14 @@ public static Map getPropertyToColumnNameMap(Class beanType) 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); } } From bfdb650225b0efcd3d659ce391020b4ce97d6be8 Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 3 Oct 2023 12:04:07 +0530 Subject: [PATCH 03/21] minor variable name change --- .../io/github/millij/poi/ss/writer/SpreadsheetWriter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 6673173..cd3a0fc 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 @@ -142,11 +142,11 @@ public void addSheet(Class beanType, List rowObjects, List String value = rowsData.get(key).get(i); - LocalDate harsha = LocalDate.parse(value,DateTimeFormatter.ofPattern("dd/MM/yyyy")); + LocalDate localDate = LocalDate.parse(value,DateTimeFormatter.ofPattern("dd/MM/yyyy")); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); - String formattedDateTime = harsha.format(formatter); + String formattedDateTime = localDate.format(formatter); cell.setCellValue(formattedDateTime); cellNo++; From 1a44805c3335238860930d3a061419592eacbd22 Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 3 Oct 2023 15:21:57 +0530 Subject: [PATCH 04/21] Enhanced to read and write formatted dates and formulas-modified acc. to cmnts --- .../millij/poi/ss/handler/RowListener.java | 2 +- .../poi/ss/model/annotations/Sheet.java | 9 +- .../poi/ss/model/annotations/SheetColumn.java | 18 +- .../poi/ss/reader/SpreadsheetReader.java | 86 ++--- .../millij/poi/ss/reader/XlsReader.java | 59 ++- .../poi/ss/reader/XlsxReader_ftDate.java | 351 +++++++++--------- .../poi/ss/writer/SpreadsheetWriter.java | 163 ++++---- .../java/io/github/millij/poi/util/Beans.java | 7 +- .../github/millij/poi/util/Spreadsheet.java | 17 +- .../java/io/github/millij/bean/Employee.java | 189 +++++----- .../java/io/github/millij/bean/Schedule.java | 53 +-- .../java/io/github/millij/dates/DateTest.java | 27 +- .../millij/poi/ss/reader/XlsxReaderTest.java | 13 +- .../poi/ss/writer/SpreadsheetWriterTest.java | 18 +- 14 files changed, 501 insertions(+), 511 deletions(-) diff --git a/src/main/java/io/github/millij/poi/ss/handler/RowListener.java b/src/main/java/io/github/millij/poi/ss/handler/RowListener.java index 29de1a2..423e668 100644 --- a/src/main/java/io/github/millij/poi/ss/handler/RowListener.java +++ b/src/main/java/io/github/millij/poi/ss/handler/RowListener.java @@ -12,7 +12,7 @@ public interface RowListener { * This method will be called after every row by the {@link SpreadsheetReader} implementation. * * @param rowNum the Row Number in the sheet. (indexed from 0) - * @param rowObj the java bean constructed using the Row data. + * @param rowObj the java bean constructed using the Row data. */ void row(int rowNum, T rowObj); diff --git a/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java b/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java index 103a0f6..7a8becd 100644 --- a/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java +++ b/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java @@ -8,12 +8,12 @@ /** - * Marker annotation that can be used to define a "type" for a sheet. The value of this annotation - * will be used to map the sheet of the workbook to this bean definition. + * Marker annotation that can be used to define a "type" for a sheet. The value of this annotation will be used to map + * the sheet of the workbook to this bean definition. * *

- * Default value ("") indicates that the default sheet name to be used without any modifications, - * but it can be specified to non-empty value to specify different name. + * Default value ("") indicates that the default sheet name to be used without any modifications, but it can be + * specified to non-empty value to specify different name. *

* *

@@ -26,6 +26,7 @@ /** * Name of the sheet. + * * @return the Sheet name */ String value() default ""; 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 bd72e3f..503fdc1 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 @@ -7,12 +7,12 @@ /** - * Marker annotation that can be used to define a non-static method as a "setter" or "getter" for a - * column, or non-static field to be used as a column. + * Marker annotation that can be used to define a non-static method as a "setter" or "getter" for a column, or + * non-static field to be used as a column. * *

- * Default value ("") indicates that the field name is used as the column name without any - * modifications, but it can be specified to non-empty value to specify different name. + * Default value ("") indicates that the field name is used as the column name without any modifications, but it can be + * specified to non-empty value to specify different name. *

*/ @Retention(RetentionPolicy.RUNTIME) @@ -25,14 +25,16 @@ * @return column name/header. */ String value() default ""; + boolean isFormatted() default false; + String format() default "dd/MM/yyyy"; - - boolean isFromula() default false; + + boolean isFormula() default false; /** - * Setting this to false will enable the null check on the Column values, to ensure - * non-null values for the field. + * Setting this to false will enable the null check on the Column values, to ensure non-null values for + * the field. * * default is true. i.e., null values are allowed. * 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..66df117 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 @@ -9,22 +9,24 @@ /** - * An Abstract representation of a Spreadsheet Reader. Any reader implementation (HSSF or XSSF) is - * expected to implement and provide the below APIs. + * An Abstract representation of a Spreadsheet Reader. Any reader implementation (HSSF or XSSF) is expected to implement + * and provide the below APIs. * */ public interface SpreadsheetReader { + public static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; + // Read with Custom RowListener /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all - * the available sheets of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets + * of the file and creates the objects of the passed type. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best - * Suited for reading Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading + * Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -32,19 +34,19 @@ public interface SpreadsheetReader { * @param file {@link File} object of the spreadsheet file * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not - * readable or row data to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data + * to bean mapping failed. */ void read(Class beanClz, File file, RowListener listener) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all - * the available sheets of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets + * of the file and creates the objects of the passed type. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best - * Suited for reading Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading + * Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -52,19 +54,19 @@ public interface SpreadsheetReader { * @param is {@link InputStream} of the spreadsheet file * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not - * readable or row data to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data + * to bean mapping failed. */ void read(Class beanClz, InputStream is, RowListener listener) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet - * (sheet numbers are indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are + * indexed from 0) will be read. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best - * Suited for reading Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading + * Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -73,19 +75,19 @@ public interface SpreadsheetReader { * @param sheetNo index of the Sheet to be read (index starts from 0) * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not - * readable or row data to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data + * to bean mapping failed. */ void read(Class beanClz, File file, int sheetNo, RowListener listener) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet - * (sheet numbers are indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are + * indexed from 0) will be read. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best - * Suited for reading Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading + * Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -94,8 +96,8 @@ public interface SpreadsheetReader { * @param sheetNo index of the Sheet to be read (index starts from 0) * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not - * readable or row data to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data + * to bean mapping failed. */ void read(Class beanClz, InputStream is, int sheetNo, RowListener listener) throws SpreadsheetReadException; @@ -105,8 +107,8 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list // Read with default RowListener /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all - * the available sheets of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets + * of the file and creates the objects of the passed type. * * @param The Parameterized bean Class. * @param beanClz The Class type to deserialize the rows data @@ -114,15 +116,15 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not - * readable or row data to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data + * to bean mapping failed. */ List read(Class beanClz, File file) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all - * the available sheets of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets + * of the file and creates the objects of the passed type. * * @param The Parameterized bean Class. * @param beanClz The Class type to deserialize the rows data @@ -130,15 +132,15 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not - * readable or row data to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data + * to bean mapping failed. */ List read(Class beanClz, InputStream is) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet - * (sheet numbers are indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are + * indexed from 0) will be read. * * @param The Parameterized bean Class. * @param beanClz beanClz The Class type to deserialize the rows data @@ -147,15 +149,15 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases - * where the file data is not readable or row data to bean mapping failed. + * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases where the file data is + * not readable or row data to bean mapping failed. */ List read(Class beanClz, File file, int sheetNo) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet - * (sheet numbers are indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are + * indexed from 0) will be read. * * @param The Parameterized bean Class. * @param beanClz beanClz The Class type to deserialize the rows data @@ -164,8 +166,8 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases - * where the file data is not readable or row data to bean mapping failed. + * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases where the file data is + * not readable or row data to bean mapping failed. */ List read(Class beanClz, InputStream is, int sheetNo) throws SpreadsheetReadException; 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 284a15c..8726b87 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 @@ -76,7 +76,7 @@ public void read(Class beanClz, InputStream is, RowListener listener) LOGGER.error(errMsg, ex); throw new SpreadsheetReadException(errMsg, ex); } - + } @Override @@ -106,12 +106,12 @@ 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); - + // Bean Properties - column name mapping Map cellPropMapping = Spreadsheet.getColumnToPropertyMap(beanClz); @@ -124,7 +124,7 @@ protected void processSheet(Class beanClz, HSSFSheet sheet, int headerRow continue; // Skip Header row } - Map rowDataMap = this.extractRowDataAsMap(beanClz,row, headerMap); + Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap); if (rowDataMap == null || rowDataMap.isEmpty()) { continue; } @@ -176,7 +176,8 @@ private Map extractCellHeaderMap(HSSFRow headerRow) { return cellHeaderMap; } - private Map extractRowDataAsMap(Class beanClz,HSSFRow row, Map columnHeaderMap) { + private Map extractRowDataAsMap(Class beanClz, HSSFRow row, + Map columnHeaderMap) { // Sanity checks if (row == null) { return new HashMap(); @@ -197,35 +198,32 @@ private Map extractRowDataAsMap(Class beanClz,HSSFRow row rowDataMap.put(cellColName, cell.getStringCellValue()); break; case NUMERIC: - if (DateUtil.isCellDateFormatted(cell)) { - - Map formats = SpreadsheetWriter.getFormats(beanClz); - String cellFormat = formats.get(cellColName); - - Date date = cell.getDateCellValue(); - LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); - - DateTimeFormatter formatter = null; - if (cellFormat != null) { - formatter = DateTimeFormatter.ofPattern(cellFormat); - } else { - formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); - } - - String formattedDateTime = localDateTime.format(formatter); - rowDataMap.put(cellColName, formattedDateTime); - break; - - } else { - rowDataMap.put(cellColName, cell.getNumericCellValue()); - break; - } - + if (DateUtil.isCellDateFormatted(cell)) { + + final Map formats = SpreadsheetWriter.getFormats(beanClz); + final String cellFormat = formats.get(cellColName); + + Date date = cell.getDateCellValue(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + + final DateTimeFormatter formatter = cellFormat != null ? DateTimeFormatter.ofPattern(cellFormat) + : DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); + + String formattedDateTime = localDateTime.format(formatter); + + rowDataMap.put(cellColName, formattedDateTime); + break; + + } else { + rowDataMap.put(cellColName, cell.getNumericCellValue()); + break; + } + case BOOLEAN: rowDataMap.put(cellColName, cell.getBooleanCellValue()); break; case FORMULA: - rowDataMap.put(cellColName, cell.getCellFormula()); + rowDataMap.put(cellColName, cell.getCellFormula()); case BLANK: case ERROR: break; @@ -239,5 +237,4 @@ private Map extractRowDataAsMap(Class beanClz,HSSFRow row - } diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java index e5fb0ec..62fa94e 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java @@ -28,7 +28,7 @@ import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Workbook; -//import org.apache.poi.util.SAXHelper; +// import org.apache.poi.util.SAXHelper; import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; @@ -46,8 +46,8 @@ /** - * Reader impletementation of {@link Workbook} for an OOXML .xlsx file. This implementation is - * suitable for low memory sax parsing or similar. + * Reader impletementation of {@link Workbook} for an OOXML .xlsx file. This implementation is suitable for low memory + * sax parsing or similar. * * @see XlsReader */ @@ -55,7 +55,6 @@ public class XlsxReader_ftDate extends AbstractSpreadsheetReader { private static final Logger LOGGER = LoggerFactory.getLogger(XlsxReader_ftDate.class); - // Constructor public XlsxReader_ftDate() { @@ -67,31 +66,30 @@ public XlsxReader_ftDate() { // ------------------------------------------------------------------------ @Override - public 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_ftDate :: Invalid bean type passed !"); } try { - final XSSFWorkbook wb = new XSSFWorkbook(is); - final int sheetCount = wb.getNumberOfSheets(); - LOGGER.debug("Total no. of sheets found in HSSFWorkbook : #{}", sheetCount); - - // Iterate over sheets - for (int i = 0; i < sheetCount; i++) { - final XSSFSheet sheet = wb.getSheetAt(i); - LOGGER.debug("Processing HSSFSheet at No. : {}", i); - - // Process Sheet - this.processSheet(beanClz, sheet, 0, listener); - } - - // Close workbook - wb.close(); - - + final XSSFWorkbook wb = new XSSFWorkbook(is); + final int sheetCount = wb.getNumberOfSheets(); + LOGGER.debug("Total no. of sheets found in HSSFWorkbook : #{}", sheetCount); + + // Iterate over sheets + for (int i = 0; i < sheetCount; i++) { + final XSSFSheet sheet = wb.getSheetAt(i); + LOGGER.debug("Processing HSSFSheet at No. : {}", i); + + // Process Sheet + this.processSheet(beanClz, sheet, 0, listener); + } + + // Close workbook + wb.close(); + + } catch (Exception ex) { String errMsg = String.format("Error reading sheet data, to Bean %s : %s", beanClz, ex.getMessage()); LOGGER.error(errMsg, ex); @@ -101,163 +99,164 @@ public void read(Class beanClz, InputStream is, RowListener listener) @Override public void read(Class beanClz, InputStream is, int sheetNo, RowListener listener) - throws SpreadsheetReadException { - // Sanity checks - if (!isInstantiableType(beanClz)) { - throw new IllegalArgumentException("XlsReader :: Invalid bean type passed !"); - } - - try { - XSSFWorkbook wb = new XSSFWorkbook(is); - final XSSFSheet sheet = wb.getSheetAt(sheetNo); - - // Process Sheet - this.processSheet(beanClz, sheet, 0, listener); - - // Close workbook - wb.close(); - - } catch (Exception ex) { - String errMsg = String.format("Error reading sheet %d, to Bean %s : %s", sheetNo, beanClz, ex.getMessage()); - LOGGER.error(errMsg, ex); - throw new SpreadsheetReadException(errMsg, ex); - } + throws SpreadsheetReadException { + // Sanity checks + if (!isInstantiableType(beanClz)) { + throw new IllegalArgumentException("XlsReader :: Invalid bean type passed !"); + } + + try { + XSSFWorkbook wb = new XSSFWorkbook(is); + final XSSFSheet sheet = wb.getSheetAt(sheetNo); + + // Process Sheet + this.processSheet(beanClz, sheet, 0, listener); + + // Close workbook + wb.close(); + + } catch (Exception ex) { + String errMsg = String.format("Error reading sheet %d, to Bean %s : %s", sheetNo, beanClz, ex.getMessage()); + LOGGER.error(errMsg, ex); + throw new SpreadsheetReadException(errMsg, ex); + } } - - //Process Sheet - + + // Process Sheet + protected void processSheet(Class beanClz, XSSFSheet sheet, int headerRowNo, RowListener eventHandler) { - // Header column - name mapping - XSSFRow headerRow = sheet.getRow(headerRowNo); - Map headerMap = this.extractCellHeaderMap(headerRow); - System.out.println(headerMap); - // Bean Properties - column name mapping - Map cellPropMapping = Spreadsheet.getColumnToPropertyMap(beanClz); - System.out.println(cellPropMapping); - Iterator rows = sheet.rowIterator(); - while (rows.hasNext()) { - // Process Row Data - XSSFRow row = (XSSFRow) rows.next(); - int rowNum = row.getRowNum(); - if (rowNum == 0) { - continue; // Skip Header row - } - - 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 - + // 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(); + int rowNum = row.getRowNum(); + if (rowNum == 0) { + continue; // Skip Header row + } + + 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(); - - 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; - } - - + // 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(); + + 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(); - - int cellCol = cell.getColumnIndex(); - 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)) { - - Map formats = SpreadsheetWriter.getFormats(beanClz); - String cellFormat = formats.get(cellColName); - - Date date = cell.getDateCellValue(); - LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); - - DateTimeFormatter formatter = null; - if (cellFormat != null) { - formatter = DateTimeFormatter.ofPattern(cellFormat); - } else { - formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); - } - - String formattedDateTime = localDateTime.format(formatter); - rowDataMap.put(cellColName, formattedDateTime); - break; - - } else { - rowDataMap.put(cellColName, cell.getNumericCellValue()); - break; - } - - case BOOLEAN: - rowDataMap.put(cellColName, cell.getBooleanCellValue()); - break; - case FORMULA: - rowDataMap.put(cellColName, cell.getCellFormula()); - case BLANK: - case ERROR: - break; - default: - break; - } - } - - return rowDataMap; - } + 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(); + + int cellCol = cell.getColumnIndex(); + 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)) { + + final Map formats = SpreadsheetWriter.getFormats(beanClz); + final String cellFormat = formats.get(cellColName); + + final Date date = cell.getDateCellValue(); + final LocalDateTime localDateTime = + LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + + DateTimeFormatter formatter = null; + if (cellFormat != null) { + formatter = DateTimeFormatter.ofPattern(cellFormat); + } else { + formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); + } + + final String formattedDateTime = localDateTime.format(formatter); + rowDataMap.put(cellColName, formattedDateTime); + break; + + } else { + rowDataMap.put(cellColName, cell.getNumericCellValue()); + break; + } + + case BOOLEAN: + rowDataMap.put(cellColName, cell.getBooleanCellValue()); + break; + case FORMULA: + rowDataMap.put(cellColName, cell.getCellFormula()); + 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 cd3a0fc..7daeb4f 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 @@ -3,6 +3,7 @@ import io.github.millij.poi.ss.model.annotations.Sheet; import io.github.millij.poi.ss.model.annotations.SheetColumn; import io.github.millij.poi.util.Spreadsheet; +import io.github.millij.poi.ss.reader.SpreadsheetReader; import java.io.File; import java.io.FileNotFoundException; @@ -34,6 +35,7 @@ public class SpreadsheetWriter { private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); + // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; private final XSSFWorkbook workbook; private final OutputStream outputStrem; @@ -61,9 +63,9 @@ public SpreadsheetWriter(OutputStream outputStream) { // Methods // ------------------------------------------------------------------------ - + // Sheet :: Add - + public void addSheet(Class beanType, List rowObjects) { // Sheet Headers List headers = Spreadsheet.getColumnNames(beanType); @@ -86,8 +88,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"); @@ -124,51 +125,45 @@ public void addSheet(Class beanType, List rowObjects, List Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { final XSSFRow row = sheet.createRow(rowNum); - - Map dateFormatsMap = this.getFormats(beanType); - - List formulaCols = this.getFormulaCols(beanType); - + + final Map dateFormatsMap = this.getFormats(beanType); + + final List formulaCols = this.getFormulaCols(beanType); + int cellNo = 0; for (String key : rowsData.keySet()) { Cell cell = row.createCell(cellNo); - + String keyFormat = dateFormatsMap.get(key); - if(keyFormat != null) - { - + if (keyFormat != null) { + try { - - String value = rowsData.get(key).get(i); - - - LocalDate localDate = LocalDate.parse(value,DateTimeFormatter.ofPattern("dd/MM/yyyy")); + + String value = rowsData.get(key).get(i); + + LocalDate localDate = LocalDate.parse(value, + DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); - + String formattedDateTime = localDate.format(formatter); - - cell.setCellValue(formattedDateTime); - cellNo++; - } - catch(Exception e) - { + cell.setCellValue(formattedDateTime); + cellNo++; + + } catch (Exception e) { e.printStackTrace(); } - - } - else if(formulaCols.contains(key)){ - String value = rowsData.get(key).get(i); - cell.setCellFormula(value); - cellNo++; - - } - else { - - String value = rowsData.get(key).get(i); - cell.setCellValue(value); - cellNo++; + + } else if (formulaCols.contains(key)) { + String value = rowsData.get(key).get(i); + cell.setCellFormula(value); + cellNo++; + + } else { + String value = rowsData.get(key).get(i); + cell.setCellValue(value); + cellNo++; } } } @@ -183,7 +178,7 @@ else if(formulaCols.contains(key)){ // Sheet :: Append to existing - + // Write public void write() throws IOException { @@ -195,8 +190,8 @@ public void write() throws IOException { // 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>(); @@ -215,87 +210,81 @@ private Map> prepareSheetRowsData(List headers return sheetData; } - - - public static Map getFormats(Class beanType) - { - - if (beanType == null) { + + + public static Map getFormats(Class beanType) { + + if (beanType == null) { throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); } Map headFormatMap = new HashMap(); // Fields - Field[] fields = beanType.getDeclaredFields(); - + final Field[] fields = beanType.getDeclaredFields(); + for (Field f : fields) { - + SheetColumn ec = f.getAnnotation(SheetColumn.class); - - if (ec != null && StringUtils.isNotEmpty(ec.value())) - { - if(ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); } } // Methods - Method[] methods = beanType.getDeclaredMethods(); - + final Method[] methods = beanType.getDeclaredMethods(); + for (Method m : methods) { - + SheetColumn ec = m.getAnnotation(SheetColumn.class); - - if (ec != null && StringUtils.isNotEmpty(ec.value())) - { - if(ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); } } return headFormatMap; } - - - public static List getFormulaCols(Class beanType) - { - if (beanType == null) { + + + public static List getFormulaCols(Class beanType) { + if (beanType == null) { throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); } - List formulaCols = new ArrayList(); + List formulaCols = new ArrayList(); // Fields - Field[] fields = beanType.getDeclaredFields(); - + final Field[] fields = beanType.getDeclaredFields(); + for (Field f : fields) { - + SheetColumn ec = f.getAnnotation(SheetColumn.class); - - if (ec != null && StringUtils.isNotEmpty(ec.value())) - { - if(ec.isFromula()) - formulaCols.add(ec.value()); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormula()) + formulaCols.add(ec.value()); } } // Methods - Method[] methods = beanType.getDeclaredMethods(); - + final Method[] methods = beanType.getDeclaredMethods(); + for (Method m : methods) { - + SheetColumn ec = m.getAnnotation(SheetColumn.class); - - if (ec != null && StringUtils.isNotEmpty(ec.value())) - { - if(ec.isFromula()) - formulaCols.add(ec.value()); + + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormula()) + formulaCols.add(ec.value()); } } - return formulaCols; - + return formulaCols; + } diff --git a/src/main/java/io/github/millij/poi/util/Beans.java b/src/main/java/io/github/millij/poi/util/Beans.java index 288e611..94267b3 100644 --- a/src/main/java/io/github/millij/poi/util/Beans.java +++ b/src/main/java/io/github/millij/poi/util/Beans.java @@ -28,6 +28,7 @@ private Beans() { * Extrats the name of the field from its accessor method. * * @param method any accessor {@link Method} of the field. + * * @return the name of the field. */ public static String getFieldName(Method method) { @@ -40,12 +41,13 @@ public static String getFieldName(Method method) { * Given a Bean and a field of it, returns the value of the field converted to String. * *
    - *
  • null is returned if the value of the field itself is null.
  • - *
  • In the case of an Object type, its String representation will be returned.
  • + *
  • null is returned if the value of the field itself is null.
  • + *
  • In the case of an Object type, its String representation will be returned.
  • *
* * @param beanObj bean of which the field value to be extracted. * @param fieldName Name of the property/field of the object. + * * @return the field value converted to String. * * @throws Exception if the bean or the fields accessor methods are not accessible. @@ -66,6 +68,7 @@ public static String getFieldValueAsString(Object beanObj, String fieldName) thr * Check whether a class is instantiable of not. * * @param clz the {@link Class} which needs to verified. + * * @return false if the class in primitive/abstract/interface/array */ public static boolean isInstantiableType(Class clz) { 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 5c52edc..3080727 100644 --- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java +++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java @@ -16,6 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; + /** * Spreadsheet related utilites. */ @@ -35,6 +36,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,31 +58,27 @@ 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(); SheetColumn ec = f.getAnnotation(SheetColumn.class); - + if (ec != null) { - String value = StringUtils.isNotEmpty(ec.value()) - ? ec.value() - : fieldName; + 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); SheetColumn ec = m.getAnnotation(SheetColumn.class); if (ec != null && !mapping.containsKey(fieldName)) { - String value = StringUtils.isNotEmpty(ec.value()) - ? ec.value() - : fieldName; + String value = StringUtils.isNotEmpty(ec.value()) ? ec.value() : fieldName; mapping.put(fieldName, value); } } @@ -112,7 +110,6 @@ public static List getColumnNames(Class beanType) { } - // Read from Bean : as Row Data // ------------------------------------------------------------------------ diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java index 5491fea..cf66d61 100644 --- a/src/test/java/io/github/millij/bean/Employee.java +++ b/src/test/java/io/github/millij/bean/Employee.java @@ -3,128 +3,129 @@ import io.github.millij.poi.ss.model.annotations.Sheet; import io.github.millij.poi.ss.model.annotations.SheetColumn; + @Sheet public class Employee { - // Note that Id and Name are annotated at name level - private String id; - private String name; + // Note that Id and Name are annotated at name level + private String id; + private String name; - @SheetColumn("Age") - private Integer age; + @SheetColumn("Age") + private Integer age; - @SheetColumn("Gender") - private String gender; + @SheetColumn("Gender") + private String gender; - @SheetColumn("Height (mts)") - private Double height; + @SheetColumn("Height (mts)") + private Double height; - @SheetColumn("Address") - private String address; + @SheetColumn("Address") + private String address; - @SheetColumn(value = "Formula", isFromula = true) - private String formula; + @SheetColumn(value = "Formula", isFormula = true) + private String formula; - @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") - private String date; + @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") + private String date; - // Constructors - // ------------------------------------------------------------------------ + // Constructors + // ------------------------------------------------------------------------ - public Employee() { - // Default - } + public Employee() { + // Default + } - public Employee(String id, String name, Integer age, String gender, Double height, String formula, String date, - String address) { - super(); + public Employee(String id, String name, Integer age, String gender, Double height, String formula, String date, + String address) { + super(); - this.id = id; - this.name = name; - this.age = age; - this.gender = gender; - this.height = height; - this.date = date; - this.address = address; - this.formula = formula; - } + this.id = id; + this.name = name; + this.age = age; + this.gender = gender; + this.height = height; + this.date = date; + this.address = address; + this.formula = formula; + } - // Getters and Setters - // ------------------------------------------------------------------------ + // Getters and Setters + // ------------------------------------------------------------------------ - @SheetColumn("ID") - public String getId() { - return id; - } + @SheetColumn("ID") + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } - @SheetColumn("Name") - public String getName() { - return name; - } + @SheetColumn("Name") + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public Integer getAge() { - return age; - } + public Integer getAge() { + return age; + } - public void setAge(Integer age) { - this.age = age; - } + public void setAge(Integer age) { + this.age = age; + } - public String getGender() { - return gender; - } + public String getGender() { + return gender; + } - public void setGender(String gender) { - this.gender = gender; - } + public void setGender(String gender) { + this.gender = gender; + } - public Double getHeight() { - return height; - } + public Double getHeight() { + return height; + } - public void setHeight(Double height) { - this.height = height; - } + public void setHeight(Double height) { + this.height = height; + } - public String getAddress() { - return address; - } + public String getAddress() { + return address; + } - public void setAddress(String address) { - this.address = address; - } + public void setAddress(String address) { + this.address = address; + } - public String getDate() { - return date; - } + public String getDate() { + return date; + } - public void setDate(String date) { - this.date = date; - } + public void setDate(String date) { + this.date = date; + } - public String getFormula() { - return formula; - } - - public void setFormula(String formula) { - this.formula = formula; - } - - // Object Methods - // ------------------------------------------------------------------------ - - @Override - public String toString() { - return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height - + ", date=" + date + ", Address =" + address + ", Formula=" + formula + "]"; - } + public String getFormula() { + return formula; + } + + public void setFormula(String formula) { + this.formula = formula; + } + + // Object Methods + // ------------------------------------------------------------------------ + + @Override + public String toString() { + return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height + + ", date=" + date + ", Address =" + address + ", Formula=" + formula + "]"; + } } diff --git a/src/test/java/io/github/millij/bean/Schedule.java b/src/test/java/io/github/millij/bean/Schedule.java index bea877e..8e6e74e 100644 --- a/src/test/java/io/github/millij/bean/Schedule.java +++ b/src/test/java/io/github/millij/bean/Schedule.java @@ -1,44 +1,45 @@ package io.github.millij.bean; -//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("Day") + private String day; - @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") - private String date; + @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") + private String date; - public Schedule(String day, String date) { - super(); - this.day = day; - this.date = date; - } + public Schedule(String day, String date) { + super(); + this.day = day; + this.date = date; + } - public String getDay() { - return day; - } + public String getDay() { + return day; + } - public void setDay(String day) { - this.day = day; - } + public void setDay(String day) { + this.day = day; + } - public String getDate() { - return date; - } + public String getDate() { + return date; + } - public void setDate(String date) { - this.date = date; - } + public void setDate(String date) { + this.date = date; + } - @Override - public String toString() { - return "Schedules [day=" + day + ", date=" + date + "]"; - } + @Override + public String toString() { + return "Schedules [day=" + day + ", date=" + date + "]"; + } } diff --git a/src/test/java/io/github/millij/dates/DateTest.java b/src/test/java/io/github/millij/dates/DateTest.java index 573d090..8f3434a 100644 --- a/src/test/java/io/github/millij/dates/DateTest.java +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -9,26 +9,27 @@ import org.junit.Test; import io.github.millij.bean.Schedule; -//import io.github.millij.bean.Schedules; +// import io.github.millij.bean.Schedules; import io.github.millij.poi.ss.writer.SpreadsheetWriter; -//import io.github.millij.bean.Schedules; +// import io.github.millij.bean.Schedules; + public class DateTest { - @Test - public void writeDatesTest() throws IOException { + @Test + public void writeDatesTest() throws IOException { - 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); + 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); - // Schedules - schedules.add(new Schedule("Friday", "02/11/2001")); - schedules.add(new Schedule("Saturday", "16/09/2023")); + // Schedules + schedules.add(new Schedule("Friday", "02/11/2001")); + schedules.add(new Schedule("Saturday", "16/09/2023")); - gew.addSheet(Schedule.class, schedules); - gew.write(); - } + gew.addSheet(Schedule.class, schedules); + gew.write(); + } } diff --git a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java index 38e5218..5585436 100644 --- a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java +++ b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java @@ -190,14 +190,11 @@ public void test_read_xlsx_as_Map() throws FileNotFoundException { // Read /* - List> employees = ger.readAsMap(new File(_filepath_xlsx_single_sheet), 1); - Assert.assertNotNull(employees); - Assert.assertTrue(employees.size() > 0); - - for (Map emp : employees) { - LOGGER.info("test_read_xlsx_single_sheet :: Output - {}", emp); - } - */ + * List> employees = ger.readAsMap(new File(_filepath_xlsx_single_sheet), 1); + * Assert.assertNotNull(employees); Assert.assertTrue(employees.size() > 0); + * + * for (Map emp : employees) { LOGGER.info("test_read_xlsx_single_sheet :: Output - {}", emp); } + */ } 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 453182a..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,"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")); + 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,"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")); + 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,"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")); + 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(); From 41ff52ef53d0d7e1992b5718c65f23eb155c3797 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 4 Oct 2023 15:03:14 +0530 Subject: [PATCH 05/21] minor code refactor --- .../github/millij/poi/ss/reader/XlsReader.java | 10 +++++----- .../{XlsxReader_ftDate.java => XlsxReader.java} | 17 +++++++---------- .../millij/poi/ss/writer/SpreadsheetWriter.java | 17 +++++++++-------- .../millij/poi/ss/reader/XlsxReaderTest.java | 12 ++++++------ 4 files changed, 27 insertions(+), 29 deletions(-) rename src/main/java/io/github/millij/poi/ss/reader/{XlsxReader_ftDate.java => XlsxReader.java} (93%) 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 8726b87..3fb2032 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 @@ -124,7 +124,7 @@ protected void processSheet(Class beanClz, HSSFSheet sheet, int headerRow continue; // Skip Header row } - Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap); + final Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap); if (rowDataMap == null || rowDataMap.isEmpty()) { continue; } @@ -203,14 +203,14 @@ private Map extractRowDataAsMap(Class beanClz, HSSFRow ro final Map formats = SpreadsheetWriter.getFormats(beanClz); final String cellFormat = formats.get(cellColName); - Date date = cell.getDateCellValue(); - LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); + final Date date = cell.getDateCellValue(); + final LocalDateTime localDateTime = + LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); final DateTimeFormatter formatter = cellFormat != null ? DateTimeFormatter.ofPattern(cellFormat) : DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); - String formattedDateTime = localDateTime.format(formatter); - + final String formattedDateTime = localDateTime.format(formatter); rowDataMap.put(cellColName, formattedDateTime); break; diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java similarity index 93% rename from src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java rename to src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index 62fa94e..f766279 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader_ftDate.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -51,13 +51,13 @@ * * @see XlsReader */ -public class XlsxReader_ftDate extends AbstractSpreadsheetReader { +public class XlsxReader extends AbstractSpreadsheetReader { - private static final Logger LOGGER = LoggerFactory.getLogger(XlsxReader_ftDate.class); + private static final Logger LOGGER = LoggerFactory.getLogger(XlsxReader.class); // Constructor - public XlsxReader_ftDate() { + public XlsxReader() { super(); } @@ -141,7 +141,7 @@ protected void processSheet(Class beanClz, XSSFSheet sheet, int headerRow continue; // Skip Header row } - Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap); + final Map rowDataMap = this.extractRowDataAsMap(beanClz, row, headerMap); if (rowDataMap == null || rowDataMap.isEmpty()) { continue; } @@ -226,12 +226,9 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, final LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); - DateTimeFormatter formatter = null; - if (cellFormat != null) { - formatter = DateTimeFormatter.ofPattern(cellFormat); - } else { - formatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); - } + final DateTimeFormatter formatter = cellFormat != null ? DateTimeFormatter.ofPattern(cellFormat) + : DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); + final String formattedDateTime = localDateTime.format(formatter); rowDataMap.put(cellColName, formattedDateTime); 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 7daeb4f..af26299 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 @@ -122,14 +122,15 @@ public void addSheet(Class beanType, List rowObjects, List } // Data Rows - Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); + final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); + + final Map dateFormatsMap = this.getFormats(beanType); + + final List formulaCols = this.getFormulaCols(beanType); + for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { final XSSFRow row = sheet.createRow(rowNum); - final Map dateFormatsMap = this.getFormats(beanType); - - final List formulaCols = this.getFormulaCols(beanType); - int cellNo = 0; for (String key : rowsData.keySet()) { Cell cell = row.createCell(cellNo); @@ -145,14 +146,14 @@ public void addSheet(Class beanType, List rowObjects, List DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); - String formattedDateTime = localDate.format(formatter); cell.setCellValue(formattedDateTime); cellNo++; - } catch (Exception e) { - e.printStackTrace(); + } catch (Exception ex) { + String errMsg = String.format("Error while preparing Date with passed date format : %s", ex.getMessage()); + LOGGER.error(errMsg, ex); } } else if (formulaCols.contains(key)) { diff --git a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java index 5585436..e500c7f 100644 --- a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java +++ b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java @@ -56,7 +56,7 @@ public void teardown() { public void test_read_xlsx_single_sheet() throws SpreadsheetReadException { // Excel Reader LOGGER.info("test_read_xlsx_single_sheet :: Reading file - {}", _filepath_xlsx_single_sheet); - XlsxReader_ftDate reader = new XlsxReader_ftDate(); + XlsxReader reader = new XlsxReader(); // Read List employees = reader.read(Employee.class, new File(_filepath_xlsx_single_sheet)); @@ -73,7 +73,7 @@ public void test_read_xlsx_single_sheet() throws SpreadsheetReadException { public void test_read_xlsx_multiple_sheets() throws SpreadsheetReadException { // Excel Reader LOGGER.info("test_read_xlsx_multiple_sheets :: Reading file - {}", _filepath_xlsx_multiple_sheets); - XlsxReader_ftDate ger = new XlsxReader_ftDate(); + XlsxReader ger = new XlsxReader(); // Read Sheet 1 List employees = ger.read(Employee.class, new File(_filepath_xlsx_multiple_sheets), 0); @@ -102,7 +102,7 @@ public void test_read_xlsx_multiple_sheets() throws SpreadsheetReadException { public void test_read_xlsx_single_sheet_from_stream() throws SpreadsheetReadException, FileNotFoundException { // Excel Reader LOGGER.info("test_read_xlsx_single_sheet_from_stream :: Reading file - {}", _filepath_xlsx_single_sheet); - XlsxReader_ftDate reader = new XlsxReader_ftDate(); + XlsxReader reader = new XlsxReader(); // InputStream final InputStream fis = new FileInputStream(new File(_filepath_xlsx_single_sheet)); @@ -121,7 +121,7 @@ public void test_read_xlsx_single_sheet_from_stream() throws SpreadsheetReadExce public void test_read_xlsx_multiple_sheets_from_stream() throws SpreadsheetReadException, FileNotFoundException { // Excel Reader LOGGER.info("test_read_xlsx_multiple_sheets_from_stream :: Reading file - {}", _filepath_xlsx_multiple_sheets); - XlsxReader_ftDate reader = new XlsxReader_ftDate(); + XlsxReader reader = new XlsxReader(); // InputStream final InputStream fisSheet1 = new FileInputStream(new File(_filepath_xlsx_multiple_sheets)); @@ -162,7 +162,7 @@ public void test_read_xlsx_single_sheet_with_callback() throws SpreadsheetReadEx final List employees = new ArrayList(); // Read - XlsxReader_ftDate reader = new XlsxReader_ftDate(); + XlsxReader reader = new XlsxReader(); reader.read(Employee.class, xlsxFile, new RowListener() { @Override @@ -186,7 +186,7 @@ public void row(int rowNum, Employee employee) { public void test_read_xlsx_as_Map() throws FileNotFoundException { // Excel Reader LOGGER.info("test_read_xlsx_as_Map :: Reading file - {}", _filepath_xlsx_single_sheet); - XlsxReader_ftDate ger = new XlsxReader_ftDate(); + XlsxReader ger = new XlsxReader(); // Read /* From 00efbc60294966d5647d13aca2bc2dae902a939f Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 4 Oct 2023 21:01:47 +0530 Subject: [PATCH 06/21] executed DateTest.java->sample-files changed --- .../write_formatted_date_sample.xls | Bin 3424 -> 3353 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/test/resources/sample-files/write_formatted_date_sample.xls b/src/test/resources/sample-files/write_formatted_date_sample.xls index 6766eb0315f2a9d87f07b93c74356f5488573667..82164be1d50d3c69fbf8dc125b60363258a8ed88 100644 GIT binary patch delta 1088 zcmaDLHB*W=z?+#xgn@&DgQ0M_%SPTxMrI(rxsy>6%$U5C=?q9XyCW*s({s!JfyLe%T4O&m%M=r}f|pr$j=!)_ zbo{o!^@MO@(2u0OVurD`?sF!rU&I_#A5i6G;#EUw`c!O{h4F%`MT$T;d)81dH z3~&gYv`Tc+Ri)wyw#KwT6fA!HXHBGPJgX`b+d59b;-G(D+CMK zcA11OpFO93&--=nf9~3G$}O3H9jk*|)!U+bN_^UiF*lngJDv3VthCyyp7j>H5qIf1^N(4xivm+7f7{%Ak=69`#p+}}Ih#<+<(z@< z?k{K;YBac|{3Gw<@>+A>&qTYJMVt^LFN*IBKkZBH7FqL%g zGAYdGFPY6P%gGn$T{Kzm-LyGZk10g-pIE(g`)o&kQ$MY9Z_fW+CUv&p-Ph;y_j`N< zW;k|^o=&4C6JT(MGJz5hBa;XNJPS^i;5Z9dgJhQRdy;jV}&0*mX+1ow>pErSk@! z1Ko0>-y>B@c;b74ZH}ydeW2*$DeIQ{rc2xb5<8wW9@g=Bo28<@RAlv~eLD*UJs2$( zImy~QiR81-aajImKeP9yN$&P*u9*1V4AG0ZqtSl&?%TtgYOG%Te9hz;Jok!^#S_L< zAy%E58#hjre+r3<-EMtJWQ)e-Im@^ zJuj;CXXVbHECJr^9H;NRo5#w?z_0;`QNnNX4i?q=)CrD$%!WL!-{&NWlzPwQS;REO zQ#@p91T*^vqfGS`p363}AADQLI=gM@{onUD`RoRjd-(?=FMj~;jgH;_O#5V8O|#?BacWLaq0g_ z%G+c33=()=>@zG7y?x!{U;M4t|MfAdD#OnOzZpTEEqRdi<`e@1Lms+k z!-0Zuzzbwm_O)tQNXPY=fb4N)b=pF%+`Y)3gF9!Mx?}oA}?`Hdh9#G)|HC`m8rQU1QUo2d?QAm-kN;G`IOOHK)U=sj09! z!rDS(fz)TiIlta?C_gf;-ZIlT#ow&BU1!rw^AzdXcfa;54A+1Dt!Q0+sEzc=n>luq zb{|rjt?O1a{Wn`toc{C3qo*g%DR+Ix)tysjKWX=!@=3|pgsS;1JiKc1RW2KFjuzoI1Jl0T)*Qeb9u7*>lP7SS^MW|=NS}O#+Z3#fhew)m z`(zCsnHZ3~XRf>LZD5oq0IlJNCjt<|lpUN9%JYk|lk)Sk^(u06(B06+Y(4P`P^mE! h1A`QbX5YyRcr@if79jgU0!2;c$Zf@ge{K From 78995e4a0d3e85cece9059db9e2fbc7ab7e3ed82 Mon Sep 17 00:00:00 2001 From: harsha Date: Fri, 6 Oct 2023 17:17:51 +0530 Subject: [PATCH 07/21] Enhanced to write new sheet to existing file without clearing prev. sheets--issue 24 --- .../poi/ss/writer/SpreadsheetWriter.java | 381 +++++++++--------- .../java/io/github/millij/bean/Employee.java | 2 +- .../java/io/github/millij/dates/DateTest.java | 4 +- .../poi/ss/writer/SpreadsheetWriterTest.java | 8 +- .../write_formatted_date_sample.xls | Bin 3353 -> 3355 bytes 5 files changed, 199 insertions(+), 196 deletions(-) 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 af26299..7c24a31 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 @@ -6,9 +6,11 @@ import io.github.millij.poi.ss.reader.SpreadsheetReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -30,264 +32,263 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - @Deprecated public class SpreadsheetWriter { - private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); - // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; - - private final XSSFWorkbook workbook; - private final OutputStream outputStrem; - - - // Constructors - // ------------------------------------------------------------------------ - - public SpreadsheetWriter(String filepath) throws FileNotFoundException { - this(new File(filepath)); - } - - public SpreadsheetWriter(File file) throws FileNotFoundException { - this(new FileOutputStream(file)); - } - - public SpreadsheetWriter(OutputStream outputStream) { - super(); - - this.workbook = new XSSFWorkbook(); - this.outputStrem = outputStream; - } - - - // Methods - // ------------------------------------------------------------------------ - - - // Sheet :: Add - - public void addSheet(Class beanType, List rowObjects) { - // Sheet Headers - List headers = Spreadsheet.getColumnNames(beanType); + private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); + // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; + + private XSSFWorkbook workbook; + private OutputStream outputStrem; + //private String filepath; + + // Constructors + // ------------------------------------------------------------------------ - this.addSheet(beanType, rowObjects, headers); - } + public SpreadsheetWriter(String filepath) throws IOException { + this(filepath, new File(filepath)); - public void addSheet(Class beanType, List rowObjects, List headers) { - // SheetName - Sheet sheet = beanType.getAnnotation(Sheet.class); - String sheetName = sheet != null ? sheet.value() : null; + } - this.addSheet(beanType, rowObjects, headers, sheetName); - } + public SpreadsheetWriter(String filepath, File file) throws IOException { + this(filepath, new FileInputStream(file)); + } - public void addSheet(Class beanType, List rowObjects, String sheetName) { - // Sheet Headers - List headers = Spreadsheet.getColumnNames(beanType); + public SpreadsheetWriter(String filepath, InputStream inputStream) throws FileNotFoundException, IOException { + super(); + try { + this.workbook = new XSSFWorkbook(inputStream); + }catch(Exception ex) { + LOGGER.error("File in the specified path is empty. Created new Workbook."); + this.workbook = new XSSFWorkbook(); + } + + this.outputStrem = new FileOutputStream(new File(filepath)); + } - this.addSheet(beanType, rowObjects, headers, sheetName); - } + // Methods + // ------------------------------------------------------------------------ - 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"); - } + // Sheet :: Add - if (CollectionUtils.isEmpty(rowObjects)) { - LOGGER.error("Skipping excel sheet writing as the ExcelBean collection is empty"); - return; - } + public void addSheet(Class beanType, List rowObjects) { + // Sheet Headers + List headers = Spreadsheet.getColumnNames(beanType); - if (CollectionUtils.isEmpty(headers)) { - LOGGER.error("Skipping excel sheet writing as the headers collection is empty"); - return; - } + this.addSheet(beanType, rowObjects, headers); + } - try { - XSSFSheet exSheet = workbook.getSheet(sheetName); - if (exSheet != null) { - String errMsg = String.format("A Sheet with the passed name already exists : %s", sheetName); - throw new IllegalArgumentException(errMsg); - } + public void addSheet(Class beanType, List rowObjects, List headers) { + // SheetName + Sheet sheet = beanType.getAnnotation(Sheet.class); + String sheetName = sheet != null ? sheet.value() : null; + + this.addSheet(beanType, rowObjects, headers, sheetName); + } - XSSFSheet sheet = StringUtils.isEmpty(sheetName) ? workbook.createSheet() : workbook.createSheet(sheetName); - LOGGER.debug("Added new Sheet[name] to the workbook : {}", sheet.getSheetName()); + public void addSheet(Class beanType, List rowObjects, String sheetName) { + // Sheet Headers + List headers = Spreadsheet.getColumnNames(beanType); - // Header - XSSFRow headerRow = sheet.createRow(0); - for (int i = 0; i < headers.size(); i++) { - XSSFCell cell = headerRow.createCell(i); - cell.setCellValue(headers.get(i)); - } + this.addSheet(beanType, rowObjects, headers, sheetName); + } - // Data Rows - final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); - - final Map dateFormatsMap = this.getFormats(beanType); + 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"); + } - final List formulaCols = this.getFormulaCols(beanType); - - for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { - final XSSFRow row = sheet.createRow(rowNum); + if (CollectionUtils.isEmpty(rowObjects)) { + LOGGER.error("Skipping excel sheet writing as the ExcelBean collection is empty"); + return; + } - int cellNo = 0; - for (String key : rowsData.keySet()) { - Cell cell = row.createCell(cellNo); + if (CollectionUtils.isEmpty(headers)) { + LOGGER.error("Skipping excel sheet writing as the headers collection is empty"); + return; + } - String keyFormat = dateFormatsMap.get(key); - if (keyFormat != null) { + try { + XSSFSheet exSheet = workbook.getSheet(sheetName); + int sheetCount = workbook.getNumberOfSheets(); + if (exSheet != null) { + String errMsg = String.format("A Sheet with the passed name already exists : %s", sheetName); + LOGGER.info(errMsg); + sheetName = "Sheet" + Integer.toString(sheetCount + 1); + LOGGER.info("Created new Sheet named : " + sheetName); + } - try { + XSSFSheet sheet = StringUtils.isEmpty(sheetName) ? workbook.createSheet() : workbook.createSheet(sheetName); + LOGGER.debug("Added new Sheet[name] to the workbook : {}", sheet.getSheetName()); - String value = rowsData.get(key).get(i); + // Header + XSSFRow headerRow = sheet.createRow(0); + for (int i = 0; i < headers.size(); i++) { + XSSFCell cell = headerRow.createCell(i); + cell.setCellValue(headers.get(i)); + } - LocalDate localDate = LocalDate.parse(value, - DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); + // Data Rows + final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); - String formattedDateTime = localDate.format(formatter); + final Map dateFormatsMap = this.getFormats(beanType); - cell.setCellValue(formattedDateTime); - cellNo++; + final List formulaCols = this.getFormulaCols(beanType); - } catch (Exception ex) { - String errMsg = String.format("Error while preparing Date with passed date format : %s", ex.getMessage()); - LOGGER.error(errMsg, ex); - } + for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { + final XSSFRow row = sheet.createRow(rowNum); - } else if (formulaCols.contains(key)) { - String value = rowsData.get(key).get(i); - cell.setCellFormula(value); - cellNo++; + int cellNo = 0; + for (String key : rowsData.keySet()) { + Cell cell = row.createCell(cellNo); - } else { - String value = rowsData.get(key).get(i); - cell.setCellValue(value); - cellNo++; - } - } - } + String keyFormat = dateFormatsMap.get(key); + if (keyFormat != null) { - } catch (Exception ex) { - String errMsg = String.format("Error while preparing sheet with passed row objects : %s", ex.getMessage()); - LOGGER.error(errMsg, ex); - } - } + try { + String value = rowsData.get(key).get(i); - // Sheet :: Append to existing + LocalDate localDate = LocalDate.parse(value, + DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); + String formattedDateTime = localDate.format(formatter); + cell.setCellValue(formattedDateTime); + cellNo++; - // Write + } catch (Exception ex) { + String errMsg = String.format("Error while preparing Date with passed date format : %s", + ex.getMessage()); + LOGGER.error(errMsg, ex); + } - public void write() throws IOException { - workbook.write(outputStrem); - workbook.close(); - } + } else if (formulaCols.contains(key)) { + String value = rowsData.get(key).get(i); + cell.setCellFormula(value); + cellNo++; + } else { + String value = rowsData.get(key).get(i); + cell.setCellValue(value); + cellNo++; + } + } + } - // Private Methods - // ------------------------------------------------------------------------ + } catch (Exception ex) { + String errMsg = String.format("Error while preparing sheet with passed row objects : %s", ex.getMessage()); + LOGGER.error(errMsg, ex); + } + } - private Map> prepareSheetRowsData(List headers, List rowObjects) - throws Exception { + // Sheet :: Append to existing - final Map> sheetData = new LinkedHashMap>(); + // Write - // Iterate over Objects - for (EB excelBean : rowObjects) { - Map row = Spreadsheet.asRowDataMap(excelBean, headers); + public void write() throws IOException { + workbook.write(outputStrem); + workbook.close(); + } - for (String header : headers) { - List data = sheetData.containsKey(header) ? sheetData.get(header) : new ArrayList(); - String value = row.get(header) != null ? row.get(header) : ""; - data.add(value); + // Private Methods + // ------------------------------------------------------------------------ - sheetData.put(header, data); - } - } + private Map> prepareSheetRowsData(List headers, List rowObjects) + throws Exception { - return sheetData; - } + final Map> sheetData = new LinkedHashMap>(); + // Iterate over Objects + for (EB excelBean : rowObjects) { + Map row = Spreadsheet.asRowDataMap(excelBean, headers); - public static Map getFormats(Class beanType) { + for (String header : headers) { + List data = sheetData.containsKey(header) ? sheetData.get(header) : new ArrayList(); + String value = row.get(header) != null ? row.get(header) : ""; + data.add(value); - if (beanType == null) { - throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); - } + sheetData.put(header, data); + } + } - Map headFormatMap = new HashMap(); + return sheetData; + } - // Fields - final Field[] fields = beanType.getDeclaredFields(); + public static Map getFormats(Class beanType) { - for (Field f : fields) { + if (beanType == null) { + throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); + } - SheetColumn ec = f.getAnnotation(SheetColumn.class); + Map headFormatMap = new HashMap(); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); - } - } + // Fields + final Field[] fields = beanType.getDeclaredFields(); - // Methods - final Method[] methods = beanType.getDeclaredMethods(); + for (Field f : fields) { - for (Method m : methods) { + SheetColumn ec = f.getAnnotation(SheetColumn.class); - SheetColumn ec = m.getAnnotation(SheetColumn.class); + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); + } + } - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); - } - } + // Methods + final Method[] methods = beanType.getDeclaredMethods(); - return headFormatMap; - } + for (Method m : methods) { + SheetColumn ec = m.getAnnotation(SheetColumn.class); - public static List getFormulaCols(Class beanType) { - if (beanType == null) { - throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); - } + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); + } + } - List formulaCols = new ArrayList(); + return headFormatMap; + } - // Fields - final Field[] fields = beanType.getDeclaredFields(); + public static List getFormulaCols(Class beanType) { + if (beanType == null) { + throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); + } - for (Field f : fields) { + List formulaCols = new ArrayList(); - SheetColumn ec = f.getAnnotation(SheetColumn.class); + // Fields + final Field[] fields = beanType.getDeclaredFields(); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormula()) - formulaCols.add(ec.value()); - } - } + for (Field f : fields) { - // Methods - final Method[] methods = beanType.getDeclaredMethods(); + SheetColumn ec = f.getAnnotation(SheetColumn.class); - for (Method m : methods) { + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormula()) + formulaCols.add(ec.value()); + } + } - SheetColumn ec = m.getAnnotation(SheetColumn.class); + // Methods + final Method[] methods = beanType.getDeclaredMethods(); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormula()) - formulaCols.add(ec.value()); - } - } + for (Method m : methods) { - return formulaCols; + SheetColumn ec = m.getAnnotation(SheetColumn.class); - } + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormula()) + formulaCols.add(ec.value()); + } + } + return formulaCols; + } } diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java index cf66d61..4cf7937 100644 --- a/src/test/java/io/github/millij/bean/Employee.java +++ b/src/test/java/io/github/millij/bean/Employee.java @@ -4,7 +4,7 @@ import io.github.millij.poi.ss.model.annotations.SheetColumn; -@Sheet +@Sheet("Employee") public class Employee { // Note that Id and Name are annotated at name level diff --git a/src/test/java/io/github/millij/dates/DateTest.java b/src/test/java/io/github/millij/dates/DateTest.java index 8f3434a..cf712f2 100644 --- a/src/test/java/io/github/millij/dates/DateTest.java +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -25,8 +25,8 @@ public void writeDatesTest() throws IOException { SpreadsheetWriter gew = new SpreadsheetWriter(filepath_output_file); // Schedules - schedules.add(new Schedule("Friday", "02/11/2001")); - schedules.add(new Schedule("Saturday", "16/09/2023")); + schedules.add(new Schedule("Monday", "02/11/2001")); + schedules.add(new Schedule("Friday", "16/09/2023")); gew.addSheet(Schedule.class, schedules); gew.write(); 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 c52e8ce..1ed9d6f 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 @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.List; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -46,7 +47,7 @@ public void teardown() { // ------------------------------------------------------------------------ @Test - public void test_write_xlsx_single_sheet() throws IOException { + public void test_write_xlsx_single_sheet() throws IOException, InvalidFormatException { final String filepath_output_file = _path_test_output.concat("single_sheet.xlsx"); // Excel Writer @@ -61,11 +62,12 @@ public void test_write_xlsx_single_sheet() throws IOException { // Write gew.addSheet(Employee.class, employees); + gew.write(); } @Test - public void test_write_xlsx_single_sheet_custom_headers() throws IOException { + public void test_write_xlsx_single_sheet_custom_headers() throws IOException, InvalidFormatException { final String filepath_output_file = _path_test_output.concat("single_sheet_custom_headers.xlsx"); // Excel Writer @@ -89,7 +91,7 @@ public void test_write_xlsx_single_sheet_custom_headers() throws IOException { @Test - public void test_write_xlsx_multiple_sheets() throws IOException { + public void test_write_xlsx_multiple_sheets() throws IOException, InvalidFormatException { final String filepath_output_file = _path_test_output.concat("multiple_sheets.xlsx"); // Excel Writer diff --git a/src/test/resources/sample-files/write_formatted_date_sample.xls b/src/test/resources/sample-files/write_formatted_date_sample.xls index 82164be1d50d3c69fbf8dc125b60363258a8ed88..89f024e89666b4446413a6d360f8bcf21639c1e3 100644 GIT binary patch delta 762 zcmbO!HCu`|z?+#xgn@&DgW-Il+eY3>MrI(rxsy>6%$U5C=?q9tNo+wbn&;KL-T(|{-`xux38zQ#DnjhTi@9|NK2~_dnXYEAiQc6~W7{t#XpOERyl=%JJU?6=8d; zH=POU%~XCFvU*kTq33Pu%k|7VthaWo(PyyHld!#>>8kZ?Qqh+ngYyTn-RwU$X?*1B zy{79T?_ue2`e0;Xx_*Y^oYwe%r}upil$0`HE7@$G-?{Anud{+*IDK}TJM;0^YV_}t z2YIG7u6xE>1_lOEbkA&F%32Lc4a)4I5Qa4eBw1_@=Y%Ab$(On8!0AJT+YC(ma$9o% z(@Qugh$c_qHs=L#;8sk&!fgsx#=|4cIBT*7k4y|m-ZR(T_BPN72|y?C18D@1U}s>c z$k8v)FUn5J&(GGY$ju4xW@Hj!fG64THfHOISAaT6%$U5C=?q9XyCW*s({s!JfyLe%T4O&m%M=r}f|pr$j=!)_ zbo{o!^@MO@(2u0OVurD`?sF!rU&I_#A5i6G;#EUw`c!O{h4F%`MT$T;Bs4YD1qSqF+qE&>oO>LWAOm?B2>@)3+rpCTU zT!oJx*t){SkgZ(0@cYvmy>7E1gsBJ8P!0 z-rJ?nqn2*sHhXXCl>=^vXWQQ_mU_C7X{p1s;9`$;f3NFLSGc}l)k@1Kxy$F7KCOPn z3i68ET-LLz85kJE(Y>;HIcqf}EvT}KLKwCjkVLULk`t0lCST>U1E&r#ZZk0L&uz^C zOfBJ{0Gd3B+ng7~fm<>88n-D}86S@{13YPlw=r8!yaIHoF%tuW6p%&$J&wsf95R#l^YDPpI|nq~Yw{}|ZMGv^ GAVmP;;~(t+ From 8944d8736a19487b84f9c6e85bf46098b3d94b7b Mon Sep 17 00:00:00 2001 From: harsha Date: Fri, 6 Oct 2023 17:32:23 +0530 Subject: [PATCH 08/21] Revert "Enhanced to write new sheet to existing file without clearing prev. sheets--issue 24" This reverts commit 78995e4a0d3e85cece9059db9e2fbc7ab7e3ed82. reverting updates --- .../poi/ss/writer/SpreadsheetWriter.java | 381 +++++++++--------- .../java/io/github/millij/bean/Employee.java | 2 +- .../java/io/github/millij/dates/DateTest.java | 4 +- .../poi/ss/writer/SpreadsheetWriterTest.java | 8 +- .../write_formatted_date_sample.xls | Bin 3355 -> 3353 bytes 5 files changed, 196 insertions(+), 199 deletions(-) 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 7c24a31..af26299 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 @@ -6,11 +6,9 @@ import io.github.millij.poi.ss.reader.SpreadsheetReader; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -32,263 +30,264 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; + @Deprecated public class SpreadsheetWriter { - private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); - // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; - - private XSSFWorkbook workbook; - private OutputStream outputStrem; - //private String filepath; - - // Constructors - // ------------------------------------------------------------------------ + private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); + // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; + + private final XSSFWorkbook workbook; + private final OutputStream outputStrem; + + + // Constructors + // ------------------------------------------------------------------------ + + public SpreadsheetWriter(String filepath) throws FileNotFoundException { + this(new File(filepath)); + } + + public SpreadsheetWriter(File file) throws FileNotFoundException { + this(new FileOutputStream(file)); + } + + public SpreadsheetWriter(OutputStream outputStream) { + super(); + + this.workbook = new XSSFWorkbook(); + this.outputStrem = outputStream; + } + + + // Methods + // ------------------------------------------------------------------------ + + + // Sheet :: Add + + public void addSheet(Class beanType, List rowObjects) { + // Sheet Headers + List headers = Spreadsheet.getColumnNames(beanType); - public SpreadsheetWriter(String filepath) throws IOException { - this(filepath, new File(filepath)); + this.addSheet(beanType, rowObjects, headers); + } - } + public void addSheet(Class beanType, List rowObjects, List headers) { + // SheetName + Sheet sheet = beanType.getAnnotation(Sheet.class); + String sheetName = sheet != null ? sheet.value() : null; - public SpreadsheetWriter(String filepath, File file) throws IOException { - this(filepath, new FileInputStream(file)); - } + this.addSheet(beanType, rowObjects, headers, sheetName); + } - public SpreadsheetWriter(String filepath, InputStream inputStream) throws FileNotFoundException, IOException { - super(); - try { - this.workbook = new XSSFWorkbook(inputStream); - }catch(Exception ex) { - LOGGER.error("File in the specified path is empty. Created new Workbook."); - this.workbook = new XSSFWorkbook(); - } - - this.outputStrem = new FileOutputStream(new File(filepath)); - } + public void addSheet(Class beanType, List rowObjects, String sheetName) { + // Sheet Headers + List headers = Spreadsheet.getColumnNames(beanType); - // Methods - // ------------------------------------------------------------------------ + this.addSheet(beanType, rowObjects, headers, sheetName); + } - // Sheet :: Add + 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"); + } - public void addSheet(Class beanType, List rowObjects) { - // Sheet Headers - List headers = Spreadsheet.getColumnNames(beanType); + if (CollectionUtils.isEmpty(rowObjects)) { + LOGGER.error("Skipping excel sheet writing as the ExcelBean collection is empty"); + return; + } - this.addSheet(beanType, rowObjects, headers); - } + if (CollectionUtils.isEmpty(headers)) { + LOGGER.error("Skipping excel sheet writing as the headers collection is empty"); + return; + } - public void addSheet(Class beanType, List rowObjects, List headers) { - // SheetName - Sheet sheet = beanType.getAnnotation(Sheet.class); - String sheetName = sheet != null ? sheet.value() : null; - - this.addSheet(beanType, rowObjects, headers, sheetName); - } + try { + XSSFSheet exSheet = workbook.getSheet(sheetName); + if (exSheet != null) { + String errMsg = String.format("A Sheet with the passed name already exists : %s", sheetName); + throw new IllegalArgumentException(errMsg); + } - public void addSheet(Class beanType, List rowObjects, String sheetName) { - // Sheet Headers - List headers = Spreadsheet.getColumnNames(beanType); + XSSFSheet sheet = StringUtils.isEmpty(sheetName) ? workbook.createSheet() : workbook.createSheet(sheetName); + LOGGER.debug("Added new Sheet[name] to the workbook : {}", sheet.getSheetName()); - this.addSheet(beanType, rowObjects, headers, sheetName); - } + // Header + XSSFRow headerRow = sheet.createRow(0); + for (int i = 0; i < headers.size(); i++) { + XSSFCell cell = headerRow.createCell(i); + cell.setCellValue(headers.get(i)); + } - 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"); - } + // Data Rows + final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); + + final Map dateFormatsMap = this.getFormats(beanType); - if (CollectionUtils.isEmpty(rowObjects)) { - LOGGER.error("Skipping excel sheet writing as the ExcelBean collection is empty"); - return; - } + final List formulaCols = this.getFormulaCols(beanType); + + for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { + final XSSFRow row = sheet.createRow(rowNum); - if (CollectionUtils.isEmpty(headers)) { - LOGGER.error("Skipping excel sheet writing as the headers collection is empty"); - return; - } + int cellNo = 0; + for (String key : rowsData.keySet()) { + Cell cell = row.createCell(cellNo); - try { - XSSFSheet exSheet = workbook.getSheet(sheetName); - int sheetCount = workbook.getNumberOfSheets(); - if (exSheet != null) { - String errMsg = String.format("A Sheet with the passed name already exists : %s", sheetName); - LOGGER.info(errMsg); - sheetName = "Sheet" + Integer.toString(sheetCount + 1); - LOGGER.info("Created new Sheet named : " + sheetName); - } + String keyFormat = dateFormatsMap.get(key); + if (keyFormat != null) { - XSSFSheet sheet = StringUtils.isEmpty(sheetName) ? workbook.createSheet() : workbook.createSheet(sheetName); - LOGGER.debug("Added new Sheet[name] to the workbook : {}", sheet.getSheetName()); + try { - // Header - XSSFRow headerRow = sheet.createRow(0); - for (int i = 0; i < headers.size(); i++) { - XSSFCell cell = headerRow.createCell(i); - cell.setCellValue(headers.get(i)); - } + String value = rowsData.get(key).get(i); - // Data Rows - final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); + LocalDate localDate = LocalDate.parse(value, + DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); - final Map dateFormatsMap = this.getFormats(beanType); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); + String formattedDateTime = localDate.format(formatter); - final List formulaCols = this.getFormulaCols(beanType); + cell.setCellValue(formattedDateTime); + cellNo++; - for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { - final XSSFRow row = sheet.createRow(rowNum); + } catch (Exception ex) { + String errMsg = String.format("Error while preparing Date with passed date format : %s", ex.getMessage()); + LOGGER.error(errMsg, ex); + } - int cellNo = 0; - for (String key : rowsData.keySet()) { - Cell cell = row.createCell(cellNo); + } else if (formulaCols.contains(key)) { + String value = rowsData.get(key).get(i); + cell.setCellFormula(value); + cellNo++; - String keyFormat = dateFormatsMap.get(key); - if (keyFormat != null) { + } else { + String value = rowsData.get(key).get(i); + cell.setCellValue(value); + cellNo++; + } + } + } - try { + } catch (Exception ex) { + String errMsg = String.format("Error while preparing sheet with passed row objects : %s", ex.getMessage()); + LOGGER.error(errMsg, ex); + } + } - String value = rowsData.get(key).get(i); - LocalDate localDate = LocalDate.parse(value, - DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); + // Sheet :: Append to existing - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); - String formattedDateTime = localDate.format(formatter); - cell.setCellValue(formattedDateTime); - cellNo++; - } catch (Exception ex) { - String errMsg = String.format("Error while preparing Date with passed date format : %s", - ex.getMessage()); - LOGGER.error(errMsg, ex); - } + // Write - } else if (formulaCols.contains(key)) { - String value = rowsData.get(key).get(i); - cell.setCellFormula(value); - cellNo++; + public void write() throws IOException { + workbook.write(outputStrem); + workbook.close(); + } - } else { - String value = rowsData.get(key).get(i); - cell.setCellValue(value); - cellNo++; - } - } - } - } catch (Exception ex) { - String errMsg = String.format("Error while preparing sheet with passed row objects : %s", ex.getMessage()); - LOGGER.error(errMsg, ex); - } - } + // Private Methods + // ------------------------------------------------------------------------ - // Sheet :: Append to existing + private Map> prepareSheetRowsData(List headers, List rowObjects) + throws Exception { - // Write + final Map> sheetData = new LinkedHashMap>(); - public void write() throws IOException { - workbook.write(outputStrem); - workbook.close(); - } + // Iterate over Objects + for (EB excelBean : rowObjects) { + Map row = Spreadsheet.asRowDataMap(excelBean, headers); - // Private Methods - // ------------------------------------------------------------------------ + for (String header : headers) { + List data = sheetData.containsKey(header) ? sheetData.get(header) : new ArrayList(); + String value = row.get(header) != null ? row.get(header) : ""; + data.add(value); - private Map> prepareSheetRowsData(List headers, List rowObjects) - throws Exception { + sheetData.put(header, data); + } + } - final Map> sheetData = new LinkedHashMap>(); + return sheetData; + } - // Iterate over Objects - for (EB excelBean : rowObjects) { - Map row = Spreadsheet.asRowDataMap(excelBean, headers); - for (String header : headers) { - List data = sheetData.containsKey(header) ? sheetData.get(header) : new ArrayList(); - String value = row.get(header) != null ? row.get(header) : ""; - data.add(value); + public static Map getFormats(Class beanType) { - sheetData.put(header, data); - } - } + if (beanType == null) { + throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); + } - return sheetData; - } + Map headFormatMap = new HashMap(); - public static Map getFormats(Class beanType) { + // Fields + final Field[] fields = beanType.getDeclaredFields(); - if (beanType == null) { - throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); - } + for (Field f : fields) { - Map headFormatMap = new HashMap(); + SheetColumn ec = f.getAnnotation(SheetColumn.class); - // Fields - final Field[] fields = beanType.getDeclaredFields(); + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); + } + } - for (Field f : fields) { + // Methods + final Method[] methods = beanType.getDeclaredMethods(); - SheetColumn ec = f.getAnnotation(SheetColumn.class); + for (Method m : methods) { - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); - } - } + SheetColumn ec = m.getAnnotation(SheetColumn.class); - // Methods - final Method[] methods = beanType.getDeclaredMethods(); + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormatted()) + headFormatMap.put(ec.value(), ec.format()); + } + } - for (Method m : methods) { + return headFormatMap; + } - SheetColumn ec = m.getAnnotation(SheetColumn.class); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); - } - } + public static List getFormulaCols(Class beanType) { + if (beanType == null) { + throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); + } - return headFormatMap; - } + List formulaCols = new ArrayList(); - public static List getFormulaCols(Class beanType) { - if (beanType == null) { - throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); - } + // Fields + final Field[] fields = beanType.getDeclaredFields(); - List formulaCols = new ArrayList(); + for (Field f : fields) { - // Fields - final Field[] fields = beanType.getDeclaredFields(); + SheetColumn ec = f.getAnnotation(SheetColumn.class); - for (Field f : fields) { + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormula()) + formulaCols.add(ec.value()); + } + } - SheetColumn ec = f.getAnnotation(SheetColumn.class); + // Methods + final Method[] methods = beanType.getDeclaredMethods(); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormula()) - formulaCols.add(ec.value()); - } - } + for (Method m : methods) { - // Methods - final Method[] methods = beanType.getDeclaredMethods(); + SheetColumn ec = m.getAnnotation(SheetColumn.class); - for (Method m : methods) { + if (ec != null && StringUtils.isNotEmpty(ec.value())) { + if (ec.isFormula()) + formulaCols.add(ec.value()); + } + } - SheetColumn ec = m.getAnnotation(SheetColumn.class); + return formulaCols; - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormula()) - formulaCols.add(ec.value()); - } - } + } - return formulaCols; - } } diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java index 4cf7937..cf66d61 100644 --- a/src/test/java/io/github/millij/bean/Employee.java +++ b/src/test/java/io/github/millij/bean/Employee.java @@ -4,7 +4,7 @@ import io.github.millij.poi.ss.model.annotations.SheetColumn; -@Sheet("Employee") +@Sheet public class Employee { // Note that Id and Name are annotated at name level diff --git a/src/test/java/io/github/millij/dates/DateTest.java b/src/test/java/io/github/millij/dates/DateTest.java index cf712f2..8f3434a 100644 --- a/src/test/java/io/github/millij/dates/DateTest.java +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -25,8 +25,8 @@ public void writeDatesTest() throws IOException { SpreadsheetWriter gew = new SpreadsheetWriter(filepath_output_file); // Schedules - schedules.add(new Schedule("Monday", "02/11/2001")); - schedules.add(new Schedule("Friday", "16/09/2023")); + schedules.add(new Schedule("Friday", "02/11/2001")); + schedules.add(new Schedule("Saturday", "16/09/2023")); gew.addSheet(Schedule.class, schedules); gew.write(); 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 1ed9d6f..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 @@ -11,7 +11,6 @@ import java.util.Arrays; import java.util.List; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -47,7 +46,7 @@ public void teardown() { // ------------------------------------------------------------------------ @Test - public void test_write_xlsx_single_sheet() throws IOException, InvalidFormatException { + public void test_write_xlsx_single_sheet() throws IOException { final String filepath_output_file = _path_test_output.concat("single_sheet.xlsx"); // Excel Writer @@ -62,12 +61,11 @@ public void test_write_xlsx_single_sheet() throws IOException, InvalidFormatExce // Write gew.addSheet(Employee.class, employees); - gew.write(); } @Test - public void test_write_xlsx_single_sheet_custom_headers() throws IOException, InvalidFormatException { + public void test_write_xlsx_single_sheet_custom_headers() throws IOException { final String filepath_output_file = _path_test_output.concat("single_sheet_custom_headers.xlsx"); // Excel Writer @@ -91,7 +89,7 @@ public void test_write_xlsx_single_sheet_custom_headers() throws IOException, In @Test - public void test_write_xlsx_multiple_sheets() throws IOException, InvalidFormatException { + public void test_write_xlsx_multiple_sheets() throws IOException { final String filepath_output_file = _path_test_output.concat("multiple_sheets.xlsx"); // Excel Writer diff --git a/src/test/resources/sample-files/write_formatted_date_sample.xls b/src/test/resources/sample-files/write_formatted_date_sample.xls index 89f024e89666b4446413a6d360f8bcf21639c1e3..82164be1d50d3c69fbf8dc125b60363258a8ed88 100644 GIT binary patch delta 743 zcmbO&HB*W=z?+#xgn@&DgQ0M_%SPTxMrI(rxsy>6%$U5C=?q9XyCW*s({s!JfyLe%T4O&m%M=r}f|pr$j=!)_ zbo{o!^@MO@(2u0OVurD`?sF!rU&I_#A5i6G;#EUw`c!O{h4F%`MT$T;Bs4YD1qSqF+qE&>oO>LWAOm?B2>@)3+rpCTU zT!oJx*t){SkgZ(0@cYvmy>7E1gsBJ8P!0 z-rJ?nqn2*sHhXXCl>=^vXWQQ_mU_C7X{p1s;9`$;f3NFLSGc}l)k@1Kxy$F7KCOPn z3i68ET-LLz85kJE(Y>;HIcqf}EvT}KLKwCjkVLULk`t0lCST>U1E&r#ZZk0L&uz^C zOfBJ{0Gd3B+ng7~fm<>88n-D}86S@{13YPlw=r8!yaIHoF%tuW6p%&$J&wsf95R#l^YDPpI|nq~Yw{}|ZMGv^ GAVmP;;~(t+ delta 762 zcmbO!HCu`|z?+#xgn@&DgW-Il+eY3>MrI(rxsy>6%$U5C=?q9tNo+wbn&;KL-T(|{-`xux38zQ#DnjhTi@9|NK2~_dnXYEAiQc6~W7{t#XpOERyl=%JJU?6=8d; zH=POU%~XCFvU*kTq33Pu%k|7VthaWo(PyyHld!#>>8kZ?Qqh+ngYyTn-RwU$X?*1B zy{79T?_ue2`e0;Xx_*Y^oYwe%r}upil$0`HE7@$G-?{Anud{+*IDK}TJM;0^YV_}t z2YIG7u6xE>1_lOEbkA&F%32Lc4a)4I5Qa4eBw1_@=Y%Ab$(On8!0AJT+YC(ma$9o% z(@Qugh$c_qHs=L#;8sk&!fgsx#=|4cIBT*7k4y|m-ZR(T_BPN72|y?C18D@1U}s>c z$k8v)FUn5J&(GGY$ju4xW@Hj!fG64THfHOISAaT Date: Tue, 10 Oct 2023 13:53:18 +0530 Subject: [PATCH 09/21] [TestCase Update] updated test cases with Date format checks --- .../java/io/github/millij/bean/Employee.java | 4 +- .../java/io/github/millij/bean/Schedule.java | 35 +++++++++++++++--- .../java/io/github/millij/dates/DateTest.java | 21 ++++++++--- .../write_formatted_date_sample.xls | Bin 3353 -> 3378 bytes 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java index cf66d61..e1f6fdf 100644 --- a/src/test/java/io/github/millij/bean/Employee.java +++ b/src/test/java/io/github/millij/bean/Employee.java @@ -26,7 +26,7 @@ public class Employee { @SheetColumn(value = "Formula", isFormula = true) private String formula; - @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") + @SheetColumn(value = "Date", format = "yyyy/MM/dd") private String date; // Constructors @@ -125,7 +125,7 @@ public void setFormula(String formula) { @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + ", height=" + height - + ", date=" + date + ", Address =" + address + ", Formula=" + formula + "]"; + + ", 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 index 8e6e74e..1d1227c 100644 --- a/src/test/java/io/github/millij/bean/Schedule.java +++ b/src/test/java/io/github/millij/bean/Schedule.java @@ -1,5 +1,8 @@ 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; @@ -12,15 +15,25 @@ public class Schedule { @SheetColumn("Day") private String day; - @SheetColumn(value = "Date", isFormatted = true, format = "yyyy/MM/dd") - private String date; + @SheetColumn(value = "Date", format = "dd/MM/yyyy") + private Date date; + + @SheetColumn(value = "localDate", format = "dd/MM/yyyy") + private LocalDate localDate; - public Schedule(String day, String date) { + // Constructor + // ------------------------------------------------------------------------- + + 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; } @@ -29,17 +42,27 @@ public void setDay(String day) { this.day = day; } - public String getDate() { + public Date getDate() { return date; } - public void setDate(String 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 "Schedules [day=" + day + ", date=" + date + "]"; + 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 index 8f3434a..3c26038 100644 --- a/src/test/java/io/github/millij/dates/DateTest.java +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -1,9 +1,12 @@ package io.github.millij.dates; -import java.io.FileNotFoundException; - 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.Test; @@ -18,15 +21,23 @@ public class DateTest { @Test - public void writeDatesTest() throws IOException { + 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", "02/11/2001")); - schedules.add(new Schedule("Saturday", "16/09/2023")); + schedules.add(new Schedule("Friday", date1, ldate1)); + schedules.add(new Schedule("Saturday", date2, ldate2)); gew.addSheet(Schedule.class, schedules); gew.write(); diff --git a/src/test/resources/sample-files/write_formatted_date_sample.xls b/src/test/resources/sample-files/write_formatted_date_sample.xls index 82164be1d50d3c69fbf8dc125b60363258a8ed88..509a6f96b655bf236286b1e082739473487367de 100644 GIT binary patch delta 1193 zcmbO!wMmLMz?+#xgn@&DgFz_OYa?$ZBQucR+{q{jW=vknbOt0axrAAz{;t;%0|B>q z)hGMrmT<3b+19PW-SntQ^yuyhJ-HiyDt4CDR$tx~7N978vL>Bx^2#!I+ezhL5;rVc z=6X)UQF*PDPx$5bviWm^g%%lj^;}Ev?OnQi*`z-2*B>9Ob(Ux6QOWdqaOvun{)>eT z3e{JXo^%>$)@+RHo-uD9v-*?OF9hn%dU73;MZ8=XHyaeMo;Yuc*E+B7&yKq;PrF2 z51|h~9$s?WH~ILdPpj@;PCIOt8n&S%s_Yo|vD0shS@-`+e|Y`wuV+fSOWccg?4GxC zYs^8#`KIRc1H9Qeyl<}D#lpzIumOlsf^YH;7S;OF365Nc3;; zJb+)|)f1O?VaHW80@ots{o7~bfM54Z&lyNR;6Fw#!Abl|;M0r!T z!t^4xa}oMmLX=jEzV1y7IS_TQd49C8*X1vry*q3Djo2+~OODt3{>$BVG0b);=aR=& z-uj<|Z%Mv;}R)m70#+$n-p8|xfH!bI#e_mzE36`?r()T}lZ2QdS`<~TH z$XObC=I_kok}E>er)nkrtGjW3-4C^$omRPi+gKdjDpQl=l(uCn=0rIuzxCO^;Ka$T znJSY^S~sj^oXP9!tIKpgy2CB3OFb~G-gH5gg7JjoHLur~D~fxXq}Xe{SQETiuJ+2W zE8WX=o|!0~dMtfqg3<)H;AqL*1XnF`+4W*h-mm7G2^y16 zyy%lG$~dq^f16!nQl4kLkiL+((~|J__rCtQfA8Gari;QQ|2R0^JRYgv8Dzpa5 z$*?dm2m>Pt2~2*^r3B8UBHU(R+Lzm!6PRnm!6|j}L~b*A5Dz(eMUb>JFsz#Vj9VG3 zlZQu|anWQA9+?=B4$oY7+uJ~u2|#=KQFJJe!-*7c9#nz2mtMd%VPil delta 1093 zcmdlaHB*W=z?+#xgn@&DgQ0M_%SPTxMrI(rxsy>6%$U5C=?q9XyCW*s({s!JfyLe%T4O&m%M=r}f|pr$j=!)_ zbo{o!^@MO@(2u0OVurD`?sF!rU&I_#A5i6G;#EUw`c!O{h4F%`MT$T;SR7Sn^4Q;oPqD| zFK8EPG`OYwBk$w#T65peNs+8uZNB};I_CajmRROR)!bjwKNSMSW|}H*K60U9slJ&Z z>(e`ecA|l5ej4R zDa_|DnawTB$rtEdG+FQ6v^iIgDMa+2SiN-nY)5`mKdp0b&i`E|b++K$*XQ&1dwc}u zH+GJmPNOChU}%Rjfzl5nlL!Mm2Tp#&We3i1y4+@9I*r?!6PN+R!D(*tDsD4*5Dz)d zM1XOJ0IMhe=T-)*S!o#I;0&~75zrQ1gaROI#$-nx8L;UIJkpF}lWTb7z`VIYp5El0 YJepwr$gY$?(eE{xkyo4T2p32Y0OXRkbN~PV From 114501c1ee041254e6edaa2712f508f783170f15 Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 10 Oct 2023 13:54:43 +0530 Subject: [PATCH 10/21] [SheetColumn] removed 'isFormated' field from sheet column --- .../io/github/millij/poi/ss/model/annotations/SheetColumn.java | 2 -- 1 file changed, 2 deletions(-) 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 503fdc1..8dc274d 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,8 +26,6 @@ */ String value() default ""; - boolean isFormatted() default false; - String format() default "dd/MM/yyyy"; boolean isFormula() default false; From 1d48dcedd0203629ea06e3ade458aab23702700e Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 10 Oct 2023 13:56:31 +0530 Subject: [PATCH 11/21] [DateFormat] added support for localDate and Date --- .../millij/poi/ss/reader/XlsReader.java | 13 +- .../millij/poi/ss/reader/XlsxReader.java | 14 +-- .../poi/ss/writer/SpreadsheetWriter.java | 118 ++++++++++-------- 3 files changed, 71 insertions(+), 74 deletions(-) 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 3fb2032..815c6f2 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 @@ -199,19 +199,8 @@ private Map extractRowDataAsMap(Class beanClz, HSSFRow ro break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { - - final Map formats = SpreadsheetWriter.getFormats(beanClz); - final String cellFormat = formats.get(cellColName); - final Date date = cell.getDateCellValue(); - final LocalDateTime localDateTime = - LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); - - final DateTimeFormatter formatter = cellFormat != null ? DateTimeFormatter.ofPattern(cellFormat) - : DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); - - final String formattedDateTime = localDateTime.format(formatter); - rowDataMap.put(cellColName, formattedDateTime); + rowDataMap.put(cellColName, date); break; } else { diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index f766279..66c9038 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -218,20 +218,8 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { - - final Map formats = SpreadsheetWriter.getFormats(beanClz); - final String cellFormat = formats.get(cellColName); - final Date date = cell.getDateCellValue(); - final LocalDateTime localDateTime = - LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); - - final DateTimeFormatter formatter = cellFormat != null ? DateTimeFormatter.ofPattern(cellFormat) - : DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT); - - - final String formattedDateTime = localDateTime.format(formatter); - rowDataMap.put(cellColName, formattedDateTime); + rowDataMap.put(cellColName, date); break; } else { 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 af26299..0fcc0bc 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,10 +1,5 @@ package io.github.millij.poi.ss.writer; -import io.github.millij.poi.ss.model.annotations.Sheet; -import io.github.millij.poi.ss.model.annotations.SheetColumn; -import io.github.millij.poi.util.Spreadsheet; -import io.github.millij.poi.ss.reader.SpreadsheetReader; - import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -12,13 +7,16 @@ 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.time.format.DateTimeFormatter; 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; @@ -30,6 +28,11 @@ 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 { @@ -37,10 +40,13 @@ public class SpreadsheetWriter { private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; + // 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 // ------------------------------------------------------------------------ @@ -59,11 +65,9 @@ public SpreadsheetWriter(OutputStream outputStream) { this.outputStrem = outputStream; } - // Methods // ------------------------------------------------------------------------ - // Sheet :: Add public void addSheet(Class beanType, List rowObjects) { @@ -123,49 +127,63 @@ public void addSheet(Class beanType, List rowObjects, List // Data Rows final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); - + final Map dateFormatsMap = this.getFormats(beanType); final List formulaCols = this.getFormulaCols(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); - String keyFormat = dateFormatsMap.get(key); + final String keyFormat = dateFormatsMap.get(key); if (keyFormat != null) { - try { - - String value = rowsData.get(key).get(i); + final String value = rowsData.get(key).get(i); + Date date = null; - LocalDate localDate = LocalDate.parse(value, - DateTimeFormatter.ofPattern(SpreadsheetReader.DEFAULT_DATE_FORMAT)); + try { + // Date Check + final SimpleDateFormat formatter = new SimpleDateFormat(DATE_DEFAULT_FORMAT); + date = formatter.parse(value); + } catch (ParseException e) { + + try { + // Local Check + final SimpleDateFormat formatter = new SimpleDateFormat(LOCAL_DATE_DEFAULT_FORMAT); + date = formatter.parse(value); + } catch (ParseException ex) { + cell.setCellValue(value); + cellNo++; + continue; + } + } - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(keyFormat); - String formattedDateTime = localDate.format(formatter); + if (Objects.isNull(date)) { + continue; + } - cell.setCellValue(formattedDateTime); - cellNo++; + final SimpleDateFormat formatter = new SimpleDateFormat(keyFormat); + final String formattedDate = formatter.format(date); - } catch (Exception ex) { - String errMsg = String.format("Error while preparing Date with passed date format : %s", ex.getMessage()); - LOGGER.error(errMsg, ex); - } + cell.setCellValue(formattedDate); + cellNo++; + continue; + } - } else if (formulaCols.contains(key)) { + if (formulaCols.contains(key)) { String value = rowsData.get(key).get(i); cell.setCellFormula(value); cellNo++; + continue; - } else { - String value = rowsData.get(key).get(i); - cell.setCellValue(value); - cellNo++; } + String value = rowsData.get(key).get(i); + cell.setCellValue(value); + cellNo++; } } @@ -175,11 +193,8 @@ public void addSheet(Class beanType, List rowObjects, List } } - // Sheet :: Append to existing - - // Write public void write() throws IOException { @@ -187,7 +202,6 @@ public void write() throws IOException { workbook.close(); } - // Private Methods // ------------------------------------------------------------------------ @@ -212,25 +226,30 @@ private Map> prepareSheetRowsData(List headers return sheetData; } - public static Map getFormats(Class beanType) { if (beanType == null) { throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); } - Map headFormatMap = new HashMap(); + final Map headFormatMap = new HashMap(); // Fields final Field[] fields = beanType.getDeclaredFields(); for (Field f : fields) { + if (!f.isAnnotationPresent(SheetColumn.class)) { + continue; + } - SheetColumn ec = f.getAnnotation(SheetColumn.class); + final SheetColumn ec = f.getAnnotation(SheetColumn.class); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); + 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()); + } } } @@ -238,19 +257,22 @@ public static Map getFormats(Class beanType) { final Method[] methods = beanType.getDeclaredMethods(); for (Method m : methods) { + if (!m.isAnnotationPresent(SheetColumn.class)) { + continue; + } - SheetColumn ec = m.getAnnotation(SheetColumn.class); + final String fieldName = Beans.getFieldName(m); + final Class objType = m.getReturnType(); - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormatted()) - headFormatMap.put(ec.value(), ec.format()); + 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; } - public static List getFormulaCols(Class beanType) { if (beanType == null) { throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); @@ -288,6 +310,4 @@ public static List getFormulaCols(Class beanType) { } - - } From 6cd9cbbfde1454f279234dae61aa8288ebbbfb92 Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 10 Oct 2023 14:31:05 +0530 Subject: [PATCH 12/21] [RMVD-Formula part] Removed all the formula related code --- .../poi/ss/model/annotations/SheetColumn.java | 2 - .../millij/poi/ss/reader/XlsReader.java | 1 - .../millij/poi/ss/reader/XlsxReader.java | 1 - .../poi/ss/writer/SpreadsheetWriter.java | 50 +------------------ .../java/io/github/millij/bean/Employee.java | 2 +- 5 files changed, 2 insertions(+), 54 deletions(-) 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 8dc274d..3cc1703 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 @@ -28,8 +28,6 @@ String format() default "dd/MM/yyyy"; - boolean isFormula() default false; - /** * 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/XlsReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java index 815c6f2..f5310f0 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 @@ -212,7 +212,6 @@ private Map extractRowDataAsMap(Class beanClz, HSSFRow ro rowDataMap.put(cellColName, cell.getBooleanCellValue()); break; case FORMULA: - rowDataMap.put(cellColName, cell.getCellFormula()); case BLANK: case ERROR: break; diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index 66c9038..b92064e 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -231,7 +231,6 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, rowDataMap.put(cellColName, cell.getBooleanCellValue()); break; case FORMULA: - rowDataMap.put(cellColName, cell.getCellFormula()); case BLANK: case ERROR: break; 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 0fcc0bc..2952a39 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 @@ -130,8 +130,6 @@ public void addSheet(Class beanType, List rowObjects, List final Map dateFormatsMap = this.getFormats(beanType); - final List formulaCols = this.getFormulaCols(beanType); - for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { final XSSFRow row = sheet.createRow(rowNum); @@ -143,7 +141,7 @@ public void addSheet(Class beanType, List rowObjects, List if (keyFormat != null) { final String value = rowsData.get(key).get(i); - Date date = null; + Date date; try { // Date Check @@ -173,14 +171,6 @@ public void addSheet(Class beanType, List rowObjects, List cellNo++; continue; } - - if (formulaCols.contains(key)) { - String value = rowsData.get(key).get(i); - cell.setCellFormula(value); - cellNo++; - continue; - - } String value = rowsData.get(key).get(i); cell.setCellValue(value); cellNo++; @@ -272,42 +262,4 @@ public static Map getFormats(Class beanType) { } return headFormatMap; } - - public static List getFormulaCols(Class beanType) { - if (beanType == null) { - throw new IllegalArgumentException("getColumnToPropertyMap :: Invalid ExcelBean type - " + beanType); - } - - List formulaCols = new ArrayList(); - - // Fields - final Field[] fields = beanType.getDeclaredFields(); - - for (Field f : fields) { - - SheetColumn ec = f.getAnnotation(SheetColumn.class); - - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormula()) - formulaCols.add(ec.value()); - } - } - - // Methods - final Method[] methods = beanType.getDeclaredMethods(); - - for (Method m : methods) { - - SheetColumn ec = m.getAnnotation(SheetColumn.class); - - if (ec != null && StringUtils.isNotEmpty(ec.value())) { - if (ec.isFormula()) - formulaCols.add(ec.value()); - } - } - - return formulaCols; - - } - } diff --git a/src/test/java/io/github/millij/bean/Employee.java b/src/test/java/io/github/millij/bean/Employee.java index e1f6fdf..33579e2 100644 --- a/src/test/java/io/github/millij/bean/Employee.java +++ b/src/test/java/io/github/millij/bean/Employee.java @@ -23,7 +23,7 @@ public class Employee { @SheetColumn("Address") private String address; - @SheetColumn(value = "Formula", isFormula = true) + @SheetColumn(value = "Formula") private String formula; @SheetColumn(value = "Date", format = "yyyy/MM/dd") From b45ad038908bf4c2da103c865bd12232716eed09 Mon Sep 17 00:00:00 2001 From: harsha Date: Tue, 10 Oct 2023 14:48:01 +0530 Subject: [PATCH 13/21] [Final keyword] Added final keyword at necessary lines --- .../io/github/millij/poi/ss/reader/XlsReader.java | 14 +++++++------- .../io/github/millij/poi/ss/reader/XlsxReader.java | 10 +++++----- .../millij/poi/ss/writer/SpreadsheetWriter.java | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) 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 f5310f0..f947e8c 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 @@ -88,7 +88,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 @@ -109,11 +109,11 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener< 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()) { @@ -151,7 +151,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()) { @@ -189,8 +189,8 @@ private Map extractRowDataAsMap(Class beanClz, HSSFRow ro while (cells.hasNext()) { HSSFCell cell = (HSSFCell) cells.next(); - int cellCol = cell.getColumnIndex(); - String cellColName = columnHeaderMap.get(cellCol); + final int cellCol = cell.getColumnIndex(); + final String cellColName = columnHeaderMap.get(cellCol); // Process cell value switch (cell.getCellTypeEnum()) { diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index b92064e..0e522ba 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -106,7 +106,7 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener< } try { - XSSFWorkbook wb = new XSSFWorkbook(is); + final XSSFWorkbook wb = new XSSFWorkbook(is); final XSSFSheet sheet = wb.getSheetAt(sheetNo); // Process Sheet @@ -136,7 +136,7 @@ protected void processSheet(Class beanClz, XSSFSheet sheet, int headerRow while (rows.hasNext()) { // Process Row Data XSSFRow row = (XSSFRow) rows.next(); - int rowNum = row.getRowNum(); + final int rowNum = row.getRowNum(); if (rowNum == 0) { continue; // Skip Header row } @@ -167,7 +167,7 @@ private Map extractCellHeaderMap(XSSFRow headerRow) { while (cells.hasNext()) { XSSFCell cell = (XSSFCell) cells.next(); - int cellCol = cell.getColumnIndex(); + final int cellCol = cell.getColumnIndex(); // Process cell value switch (cell.getCellTypeEnum()) { @@ -208,8 +208,8 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, while (cells.hasNext()) { XSSFCell cell = (XSSFCell) cells.next(); - int cellCol = cell.getColumnIndex(); - String cellColName = columnHeaderMap.get(cellCol); + final int cellCol = cell.getColumnIndex(); + final String cellColName = columnHeaderMap.get(cellCol); // Process cell value switch (cell.getCellTypeEnum()) { 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 2952a39..ae89561 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 @@ -119,7 +119,7 @@ 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)); @@ -202,7 +202,7 @@ private Map> prepareSheetRowsData(List headers // 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(); From fdfb8a5553c1e5accd1031de7ddf2f5e278f3d9f Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 09:56:28 +0530 Subject: [PATCH 14/21] [LocalDate read] Modified code to support LocalDate --- .../ss/reader/AbstractSpreadsheetReader.java | 43 ++++++++++++++++++ .../millij/poi/ss/reader/XlsReader.java | 30 +++++++++--- .../millij/poi/ss/reader/XlsxReader.java | 37 +++++++++++---- .../poi/ss/writer/SpreadsheetWriter.java | 17 ++++--- .../github/millij/poi/util/Spreadsheet.java | 8 ++-- ...e.xls => write_formatted_date_sample.xlsx} | Bin 6 files changed, 111 insertions(+), 24 deletions(-) rename src/test/resources/sample-files/{write_formatted_date_sample.xls => write_formatted_date_sample.xlsx} (100%) 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/XlsReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsReader.java index f947e8c..4d85e90 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 @@ -8,8 +8,11 @@ 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; @@ -199,15 +202,28 @@ private Map extractRowDataAsMap(Class beanClz, HSSFRow ro break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { - final Date date = cell.getDateCellValue(); - rowDataMap.put(cellColName, date); - break; - } else { - rowDataMap.put(cellColName, cell.getNumericCellValue()); - break; + // 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 + Instant instant = ldate.toInstant(); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = instant.atZone(zoneId); + LocalDate localDate = zonedDateTime.toLocalDate(); + + rowDataMap.put(cellColName, localDate); + break; + } } - case BOOLEAN: rowDataMap.put(cellColName, cell.getBooleanCellValue()); break; diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index 0e522ba..a0fe894 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -7,18 +7,26 @@ import io.github.millij.poi.SpreadsheetReadException; import io.github.millij.poi.ss.handler.RowContentsHandler; import io.github.millij.poi.ss.handler.RowListener; +import io.github.millij.poi.ss.model.annotations.SheetColumn; import io.github.millij.poi.ss.writer.SpreadsheetWriter; +import io.github.millij.poi.util.Beans; import io.github.millij.poi.util.Spreadsheet; import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +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.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; @@ -218,15 +226,29 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { - final Date date = cell.getDateCellValue(); - rowDataMap.put(cellColName, date); - break; - } else { - rowDataMap.put(cellColName, cell.getNumericCellValue()); - break; - } + // 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 + Instant instant = ldate.toInstant(); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime zonedDateTime = instant.atZone(zoneId); + LocalDate localDate = zonedDateTime.toLocalDate(); + + rowDataMap.put(cellColName, localDate); + break; + } + } case BOOLEAN: rowDataMap.put(cellColName, cell.getBooleanCellValue()); break; @@ -242,5 +264,4 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, 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 ae89561..e37e497 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 @@ -21,6 +21,8 @@ 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; @@ -110,6 +112,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); @@ -126,9 +130,9 @@ public void addSheet(Class beanType, List rowObjects, List } // Data Rows - final Map> rowsData = this.prepareSheetRowsData(headers, rowObjects); + final Map> rowsData = prepareSheetRowsData(headers, rowObjects); - final Map dateFormatsMap = this.getFormats(beanType); + final Map dateFormatsMap = getFormats(beanType); for (int i = 0, rowNum = 1; i < rowObjects.size(); i++, rowNum++) { final XSSFRow row = sheet.createRow(rowNum); @@ -147,10 +151,11 @@ public void addSheet(Class beanType, List rowObjects, List // Date Check final SimpleDateFormat formatter = new SimpleDateFormat(DATE_DEFAULT_FORMAT); date = formatter.parse(value); + } catch (ParseException e) { try { - // Local Check + // LocalDate Check final SimpleDateFormat formatter = new SimpleDateFormat(LOCAL_DATE_DEFAULT_FORMAT); date = formatter.parse(value); } catch (ParseException ex) { @@ -164,10 +169,10 @@ public void addSheet(Class beanType, List rowObjects, List continue; } - final SimpleDateFormat formatter = new SimpleDateFormat(keyFormat); - final String formattedDate = formatter.format(date); + cellStyle.setDataFormat(createHelper.createDataFormat().getFormat(keyFormat)); + cell.setCellStyle(cellStyle); - cell.setCellValue(formattedDate); + cell.setCellValue(date); cellNo++; continue; } 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 3080727..6b4b85e 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,23 @@ 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. @@ -181,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/resources/sample-files/write_formatted_date_sample.xls b/src/test/resources/sample-files/write_formatted_date_sample.xlsx similarity index 100% rename from src/test/resources/sample-files/write_formatted_date_sample.xls rename to src/test/resources/sample-files/write_formatted_date_sample.xlsx From 0819f0b002212e2b58a13cd1a9a21880182e2202 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 09:57:59 +0530 Subject: [PATCH 15/21] [Test Cases] Added and modified files for Dates TestCases --- .../java/io/github/millij/bean/Schedule.java | 9 +++- .../java/io/github/millij/dates/DateTest.java | 49 ++++++++++++++++++ .../millij/poi/ss/reader/XlsReaderTest.java | 1 + .../write_formatted_date_sample.xlsx | Bin 3378 -> 4844 bytes .../sample-files/xls_sample_read_dates.xls | Bin 0 -> 5632 bytes 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/sample-files/xls_sample_read_dates.xls diff --git a/src/test/java/io/github/millij/bean/Schedule.java b/src/test/java/io/github/millij/bean/Schedule.java index 1d1227c..fb5ebd4 100644 --- a/src/test/java/io/github/millij/bean/Schedule.java +++ b/src/test/java/io/github/millij/bean/Schedule.java @@ -18,12 +18,16 @@ public class Schedule { @SheetColumn(value = "Date", format = "dd/MM/yyyy") private Date date; - @SheetColumn(value = "localDate", format = "dd/MM/yyyy") + @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; @@ -34,6 +38,7 @@ public Schedule(String day, Date date, LocalDate localDate) { // Getters and Setters // ------------------------------------------------------------------------- + public String getDay() { return day; } @@ -62,7 +67,7 @@ public void setLocalDate(LocalDate localDate) { // ------------------------------------------------------------------------ @Override public String toString() { - return "Schedule [day=" + day + ", date=" + date + ", localDate=" + localDate + "]"; + 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 index 3c26038..71b989c 100644 --- a/src/test/java/io/github/millij/dates/DateTest.java +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -1,5 +1,6 @@ package io.github.millij.dates; +import java.io.File; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -9,9 +10,17 @@ 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.Employee; 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.XlsReaderTest; +import io.github.millij.poi.ss.reader.XlsxReader; // import io.github.millij.bean.Schedules; import io.github.millij.poi.ss.writer.SpreadsheetWriter; @@ -20,6 +29,8 @@ public class DateTest { + private static final Logger LOGGER = LoggerFactory.getLogger(DateTest.class); + @Test public void writeDatesTest() throws IOException, ParseException { @@ -43,4 +54,42 @@ public void writeDatesTest() throws IOException, ParseException { 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/resources/sample-files/write_formatted_date_sample.xlsx b/src/test/resources/sample-files/write_formatted_date_sample.xlsx index 509a6f96b655bf236286b1e082739473487367de..bb0246114ac2254649f09437bbacf75f295bbc22 100644 GIT binary patch literal 4844 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 literal 3378 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 Date: Wed, 11 Oct 2023 10:07:33 +0530 Subject: [PATCH 16/21] [Finla keyword]Added final keyword at necessary lines --- .../java/io/github/millij/poi/ss/reader/XlsReader.java | 8 ++++---- .../java/io/github/millij/poi/ss/reader/XlsxReader.java | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) 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 4d85e90..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 @@ -215,10 +215,10 @@ private Map extractRowDataAsMap(Class beanClz, HSSFRow ro final Date ldate = cell.getDateCellValue(); // Convert Date to LocalDate - Instant instant = ldate.toInstant(); - ZoneId zoneId = ZoneId.systemDefault(); - ZonedDateTime zonedDateTime = instant.atZone(zoneId); - LocalDate localDate = zonedDateTime.toLocalDate(); + 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; diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index a0fe894..ef7ceba 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -240,10 +240,10 @@ private Map extractRowDataAsMap(Class beanClz, XSSFRow row, final Date ldate = cell.getDateCellValue(); // Convert Date to LocalDate - Instant instant = ldate.toInstant(); - ZoneId zoneId = ZoneId.systemDefault(); - ZonedDateTime zonedDateTime = instant.atZone(zoneId); - LocalDate localDate = zonedDateTime.toLocalDate(); + 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; From fba7611e50a8c42c46c77ba82c4a638caf8e7a92 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 10:30:26 +0530 Subject: [PATCH 17/21] [Unused imports] Removed unused imports --- .../millij/poi/ss/reader/XlsxReader.java | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index ef7ceba..3e891d4 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -2,55 +2,31 @@ import static io.github.millij.poi.util.Beans.isInstantiableType; - - import io.github.millij.poi.SpreadsheetReadException; -import io.github.millij.poi.ss.handler.RowContentsHandler; import io.github.millij.poi.ss.handler.RowListener; -import io.github.millij.poi.ss.model.annotations.SheetColumn; -import io.github.millij.poi.ss.writer.SpreadsheetWriter; -import io.github.millij.poi.util.Beans; import io.github.millij.poi.util.Spreadsheet; import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; 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.commons.lang3.StringUtils; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Workbook; -// import org.apache.poi.util.SAXHelper; -import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; -import org.apache.poi.xssf.eventusermodel.XSSFReader; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler; -import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler; -import org.apache.poi.xssf.model.StylesTable; + import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; /** @@ -110,7 +86,7 @@ public void read(Class beanClz, InputStream is, int sheetNo, RowListener< throws SpreadsheetReadException { // Sanity checks if (!isInstantiableType(beanClz)) { - throw new IllegalArgumentException("XlsReader :: Invalid bean type passed !"); + throw new IllegalArgumentException("XlsxReader :: Invalid bean type passed !"); } try { From 851936ed81112d372dd0bf1bae966e49e94bcc75 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 10:46:49 +0530 Subject: [PATCH 18/21] [Revert] reverted sheet and rowListeners file from develop branch --- .../io/github/millij/poi/ss/handler/RowListener.java | 2 +- .../io/github/millij/poi/ss/model/annotations/Sheet.java | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/github/millij/poi/ss/handler/RowListener.java b/src/main/java/io/github/millij/poi/ss/handler/RowListener.java index 423e668..29de1a2 100644 --- a/src/main/java/io/github/millij/poi/ss/handler/RowListener.java +++ b/src/main/java/io/github/millij/poi/ss/handler/RowListener.java @@ -12,7 +12,7 @@ public interface RowListener { * This method will be called after every row by the {@link SpreadsheetReader} implementation. * * @param rowNum the Row Number in the sheet. (indexed from 0) - * @param rowObj the java bean constructed using the Row data. + * @param rowObj the java bean constructed using the Row data. */ void row(int rowNum, T rowObj); diff --git a/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java b/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java index 7a8becd..103a0f6 100644 --- a/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java +++ b/src/main/java/io/github/millij/poi/ss/model/annotations/Sheet.java @@ -8,12 +8,12 @@ /** - * Marker annotation that can be used to define a "type" for a sheet. The value of this annotation will be used to map - * the sheet of the workbook to this bean definition. + * Marker annotation that can be used to define a "type" for a sheet. The value of this annotation + * will be used to map the sheet of the workbook to this bean definition. * *

- * Default value ("") indicates that the default sheet name to be used without any modifications, but it can be - * specified to non-empty value to specify different name. + * Default value ("") indicates that the default sheet name to be used without any modifications, + * but it can be specified to non-empty value to specify different name. *

* *

@@ -26,7 +26,6 @@ /** * Name of the sheet. - * * @return the Sheet name */ String value() default ""; From 2e4484850cf4d761ddf68be6a73efd7660c9f7c3 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 11:01:27 +0530 Subject: [PATCH 19/21] [Code refactor] Replaced SheetColumn,SSReader,Beans,XlsxReader files from develop branch --- .../poi/ss/model/annotations/SheetColumn.java | 14 ++- .../poi/ss/reader/SpreadsheetReader.java | 86 +++++++++---------- .../java/io/github/millij/poi/util/Beans.java | 7 +- .../millij/poi/ss/reader/XlsxReaderTest.java | 14 +-- 4 files changed, 59 insertions(+), 62 deletions(-) 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 3cc1703..e014a65 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 @@ -7,12 +7,12 @@ /** - * Marker annotation that can be used to define a non-static method as a "setter" or "getter" for a column, or - * non-static field to be used as a column. + * Marker annotation that can be used to define a non-static method as a "setter" or "getter" for a + * column, or non-static field to be used as a column. * *

- * Default value ("") indicates that the field name is used as the column name without any modifications, but it can be - * specified to non-empty value to specify different name. + * Default value ("") indicates that the field name is used as the column name without any + * modifications, but it can be specified to non-empty value to specify different name. *

*/ @Retention(RetentionPolicy.RUNTIME) @@ -26,11 +26,9 @@ */ 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. + * Setting this to false will enable the null check on the Column values, to ensure + * non-null values for the field. * * default is true. i.e., null values are allowed. * 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 66df117..7761f3f 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 @@ -9,24 +9,22 @@ /** - * An Abstract representation of a Spreadsheet Reader. Any reader implementation (HSSF or XSSF) is expected to implement - * and provide the below APIs. + * An Abstract representation of a Spreadsheet Reader. Any reader implementation (HSSF or XSSF) is + * expected to implement and provide the below APIs. * */ public interface SpreadsheetReader { - public static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; - // Read with Custom RowListener /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets - * of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all + * the available sheets of the file and creates the objects of the passed type. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading - * Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best + * Suited for reading Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -34,19 +32,19 @@ public interface SpreadsheetReader { * @param file {@link File} object of the spreadsheet file * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data - * to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not + * readable or row data to bean mapping failed. */ void read(Class beanClz, File file, RowListener listener) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets - * of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all + * the available sheets of the file and creates the objects of the passed type. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading - * Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best + * Suited for reading Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -54,19 +52,19 @@ public interface SpreadsheetReader { * @param is {@link InputStream} of the spreadsheet file * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data - * to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not + * readable or row data to bean mapping failed. */ void read(Class beanClz, InputStream is, RowListener listener) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are - * indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet + * (sheet numbers are indexed from 0) will be read. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading - * Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best + * Suited for reading Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -75,19 +73,19 @@ public interface SpreadsheetReader { * @param sheetNo index of the Sheet to be read (index starts from 0) * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data - * to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not + * readable or row data to bean mapping failed. */ void read(Class beanClz, File file, int sheetNo, RowListener listener) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are - * indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet + * (sheet numbers are indexed from 0) will be read. * *

- * The {@link RowListener} implementation callback gets triggered after reading each Row. Best Suited for reading - * Large files in restricted memory environments. + * The {@link RowListener} implementation callback gets triggered after reading each Row. Best + * Suited for reading Large files in restricted memory environments. *

* * @param The Parameterized bean Class. @@ -96,8 +94,8 @@ public interface SpreadsheetReader { * @param sheetNo index of the Sheet to be read (index starts from 0) * @param listener Custom {@link RowListener} implementation for row data callbacks. * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data - * to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not + * readable or row data to bean mapping failed. */ void read(Class beanClz, InputStream is, int sheetNo, RowListener listener) throws SpreadsheetReadException; @@ -107,8 +105,8 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list // Read with default RowListener /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets - * of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all + * the available sheets of the file and creates the objects of the passed type. * * @param The Parameterized bean Class. * @param beanClz The Class type to deserialize the rows data @@ -116,15 +114,15 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data - * to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not + * readable or row data to bean mapping failed. */ List read(Class beanClz, File file) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. This method will attempt to read all the available sheets - * of the file and creates the objects of the passed type. + * Reads the spreadsheet file to beans of the given type. This method will attempt to read all + * the available sheets of the file and creates the objects of the passed type. * * @param The Parameterized bean Class. * @param beanClz The Class type to deserialize the rows data @@ -132,15 +130,15 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not readable or row data - * to bean mapping failed. + * @throws SpreadsheetReadException an exception is thrown in cases where the file data is not + * readable or row data to bean mapping failed. */ List read(Class beanClz, InputStream is) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are - * indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet + * (sheet numbers are indexed from 0) will be read. * * @param The Parameterized bean Class. * @param beanClz beanClz The Class type to deserialize the rows data @@ -149,15 +147,15 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases where the file data is - * not readable or row data to bean mapping failed. + * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases + * where the file data is not readable or row data to bean mapping failed. */ List read(Class beanClz, File file, int sheetNo) throws SpreadsheetReadException; /** - * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet (sheet numbers are - * indexed from 0) will be read. + * Reads the spreadsheet file to beans of the given type. Note that only the requested sheet + * (sheet numbers are indexed from 0) will be read. * * @param The Parameterized bean Class. * @param beanClz beanClz The Class type to deserialize the rows data @@ -166,8 +164,8 @@ void read(Class beanClz, InputStream is, int sheetNo, RowListener list * * @return a {@link List} of objects of the parameterized type * - * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases where the file data is - * not readable or row data to bean mapping failed. + * @throws SpreadsheetReadException SpreadsheetReadException an exception is thrown in cases + * where the file data is not readable or row data to bean mapping failed. */ List read(Class beanClz, InputStream is, int sheetNo) throws SpreadsheetReadException; diff --git a/src/main/java/io/github/millij/poi/util/Beans.java b/src/main/java/io/github/millij/poi/util/Beans.java index 94267b3..288e611 100644 --- a/src/main/java/io/github/millij/poi/util/Beans.java +++ b/src/main/java/io/github/millij/poi/util/Beans.java @@ -28,7 +28,6 @@ private Beans() { * Extrats the name of the field from its accessor method. * * @param method any accessor {@link Method} of the field. - * * @return the name of the field. */ public static String getFieldName(Method method) { @@ -41,13 +40,12 @@ public static String getFieldName(Method method) { * Given a Bean and a field of it, returns the value of the field converted to String. * *
    - *
  • null is returned if the value of the field itself is null.
  • - *
  • In the case of an Object type, its String representation will be returned.
  • + *
  • null is returned if the value of the field itself is null.
  • + *
  • In the case of an Object type, its String representation will be returned.
  • *
* * @param beanObj bean of which the field value to be extracted. * @param fieldName Name of the property/field of the object. - * * @return the field value converted to String. * * @throws Exception if the bean or the fields accessor methods are not accessible. @@ -68,7 +66,6 @@ public static String getFieldValueAsString(Object beanObj, String fieldName) thr * Check whether a class is instantiable of not. * * @param clz the {@link Class} which needs to verified. - * * @return false if the class in primitive/abstract/interface/array */ public static boolean isInstantiableType(Class clz) { diff --git a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java index e500c7f..f33df25 100644 --- a/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java +++ b/src/test/java/io/github/millij/poi/ss/reader/XlsxReaderTest.java @@ -4,6 +4,7 @@ import io.github.millij.bean.Employee; import io.github.millij.poi.SpreadsheetReadException; import io.github.millij.poi.ss.handler.RowListener; +import io.github.millij.poi.ss.reader.XlsxReader; import java.io.File; import java.io.FileInputStream; @@ -190,11 +191,14 @@ public void test_read_xlsx_as_Map() throws FileNotFoundException { // Read /* - * List> employees = ger.readAsMap(new File(_filepath_xlsx_single_sheet), 1); - * Assert.assertNotNull(employees); Assert.assertTrue(employees.size() > 0); - * - * for (Map emp : employees) { LOGGER.info("test_read_xlsx_single_sheet :: Output - {}", emp); } - */ + List> employees = ger.readAsMap(new File(_filepath_xlsx_single_sheet), 1); + Assert.assertNotNull(employees); + Assert.assertTrue(employees.size() > 0); + + for (Map emp : employees) { + LOGGER.info("test_read_xlsx_single_sheet :: Output - {}", emp); + } + */ } From 5f44494c8c783dd44783902646d4d7c9ceb57748 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 11:15:21 +0530 Subject: [PATCH 20/21] [Code Refactor] Added minor changes to replaced files in prev commit --- .../github/millij/poi/ss/model/annotations/SheetColumn.java | 2 ++ .../io/github/millij/poi/ss/reader/SpreadsheetReader.java | 1 + src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java | 2 +- .../io/github/millij/poi/ss/writer/SpreadsheetWriter.java | 1 - src/test/java/io/github/millij/dates/DateTest.java | 5 ----- 5 files changed, 4 insertions(+), 7 deletions(-) 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/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/XlsxReader.java b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java index 3e891d4..4b7fc40 100644 --- a/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java +++ b/src/main/java/io/github/millij/poi/ss/reader/XlsxReader.java @@ -53,7 +53,7 @@ public XlsxReader() { public void read(Class beanClz, InputStream is, RowListener listener) throws SpreadsheetReadException { // Sanity checks if (!isInstantiableType(beanClz)) { - throw new IllegalArgumentException("XlsxReader_ftDate :: Invalid bean type passed !"); + throw new IllegalArgumentException("XlsxReader :: Invalid bean type passed !"); } try { 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 e37e497..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 @@ -40,7 +40,6 @@ public class SpreadsheetWriter { private static final Logger LOGGER = LoggerFactory.getLogger(SpreadsheetWriter.class); - // private static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy"; // Default Formats private static final String DATE_DEFAULT_FORMAT = "EEE MMM dd HH:mm:ss zzz yyyy"; diff --git a/src/test/java/io/github/millij/dates/DateTest.java b/src/test/java/io/github/millij/dates/DateTest.java index 71b989c..629f7a3 100644 --- a/src/test/java/io/github/millij/dates/DateTest.java +++ b/src/test/java/io/github/millij/dates/DateTest.java @@ -15,17 +15,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.github.millij.bean.Employee; 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.XlsReaderTest; import io.github.millij.poi.ss.reader.XlsxReader; -// import io.github.millij.bean.Schedules; import io.github.millij.poi.ss.writer.SpreadsheetWriter; -// import io.github.millij.bean.Schedules; - public class DateTest { From d59ac276e868033184874781c5fe3d4d63f03587 Mon Sep 17 00:00:00 2001 From: harsha Date: Wed, 11 Oct 2023 11:23:23 +0530 Subject: [PATCH 21/21] [Final] Added final keyword --- src/main/java/io/github/millij/poi/util/Spreadsheet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 6b4b85e..7a98bb6 100644 --- a/src/main/java/io/github/millij/poi/util/Spreadsheet.java +++ b/src/main/java/io/github/millij/poi/util/Spreadsheet.java @@ -62,12 +62,12 @@ public static Map getPropertyToColumnNameMap(Class beanType) // Fields final Field[] fields = beanType.getDeclaredFields(); for (Field f : fields) { - String fieldName = f.getName(); + final String fieldName = f.getName(); SheetColumn ec = f.getAnnotation(SheetColumn.class); if (ec != null) { - String value = StringUtils.isNotEmpty(ec.value()) ? ec.value() : fieldName; + final String value = StringUtils.isNotEmpty(ec.value()) ? ec.value() : fieldName; mapping.put(fieldName, value); } }