From 36866c09f79be1e1bc8bb2bf2782b7eab5c9ab7c Mon Sep 17 00:00:00 2001 From: Olsi Seferi <72546616+olsiseferi@users.noreply.github.com> Date: Wed, 1 Dec 2021 19:19:19 +0100 Subject: [PATCH] ExcelUtility Jira issue BAEL-5198 (#11503) * CODE REFACTOR AND ADDED UNIT TEST * SMALL CHANGE * FIXED TESTS TIMEZONE ISSUES Co-authored-by: Olsi Seferi --- .../com/baeldung/poi/excel/ExcelUtility.java | 66 ++++++++++++++++++ .../poi/excel/ExcelUtilityUnitTest.java | 54 ++++++++++++++ apache-poi/src/test/resources/baeldung.xlsx | Bin 0 -> 16777 bytes 3 files changed, 120 insertions(+) create mode 100644 apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java create mode 100644 apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java create mode 100644 apache-poi/src/test/resources/baeldung.xlsx diff --git a/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java new file mode 100644 index 0000000000..e4a5b791c9 --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/excel/ExcelUtility.java @@ -0,0 +1,66 @@ +package com.baeldung.poi.excel; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.DateUtil; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +public class ExcelUtility { + private static final String ENDLINE = System.getProperty("line.separator"); + + public static String readExcel(String filePath) throws IOException { + File file = new File(filePath); + FileInputStream inputStream = null; + StringBuilder toReturn = new StringBuilder(); + try { + inputStream = new FileInputStream(file); + Workbook baeuldungWorkBook = new XSSFWorkbook(inputStream); + for (Sheet sheet : baeuldungWorkBook) { + toReturn.append("--------------------------------------------------------------------").append(ENDLINE); + toReturn.append("Worksheet :").append(sheet.getSheetName()).append(ENDLINE); + toReturn.append("--------------------------------------------------------------------").append(ENDLINE); + int firstRow = sheet.getFirstRowNum(); + int lastRow = sheet.getLastRowNum(); + for (int index = firstRow + 1; index <= lastRow; index++) { + Row row = sheet.getRow(index); + toReturn.append("|| "); + for (int cellIndex = row.getFirstCellNum(); cellIndex < row.getLastCellNum(); cellIndex++) { + Cell cell = row.getCell(cellIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); + printCellValue(cell, toReturn); + } + toReturn.append(" ||").append(ENDLINE); + } + } + inputStream.close(); + + } catch (IOException e) { + throw e; + } + return toReturn.toString(); + } + + public static void printCellValue(Cell cell, StringBuilder toReturn) { + CellType cellType = cell.getCellType().equals(CellType.FORMULA) ? cell.getCachedFormulaResultType() + : cell.getCellType(); + if (cellType.equals(CellType.STRING)) { + toReturn.append(cell.getStringCellValue()).append(" | "); + } + if (cellType.equals(CellType.NUMERIC)) { + if (DateUtil.isCellDateFormatted(cell)) { + toReturn.append(cell.getDateCellValue()).append(" | "); + } else { + toReturn.append(cell.getNumericCellValue()).append(" | "); + } + } + if (cellType.equals(CellType.BOOLEAN)) { + toReturn.append(cell.getBooleanCellValue()).append(" | "); + } + } +} \ No newline at end of file diff --git a/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java new file mode 100644 index 0000000000..6638d77066 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/excel/ExcelUtilityUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.poi.excel; + +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import org.junit.Before; +import org.junit.Test; + +public class ExcelUtilityUnitTest { + private static final String FILE_NAME = "baeldung.xlsx"; + private String fileLocation; + private static final String ENDLINE = System.getProperty("line.separator"); + private StringBuilder output; + + @Before + public void setupUnitTest() throws IOException, URISyntaxException, ParseException { + output = new StringBuilder(); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("Worksheet :Sheet1").append(ENDLINE); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("|| Name1 | Surname1 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | ‡ | ||") + .append(ENDLINE); + output.append("|| Name2 | Surname2 | 5.646513512E9 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/12/2021").toString()).append(" | false | ||") + .append(ENDLINE); + output.append("|| Name3 | Surname3 | 3.55696564113E11 | ").append(new SimpleDateFormat("dd/MM/yyyy").parse("4/11/2021").toString()).append(" | 7.17039641738E11 | ||") + .append(ENDLINE); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("Worksheet :Sheet2").append(ENDLINE); + output.append("--------------------------------------------------------------------").append(ENDLINE); + output.append("|| Name4 | Surname4 | 3.55675623232E11 | 13/04/2021 | ||").append(ENDLINE); + + fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString(); + } + + @Test + public void givenStringPath_whenReadExcel_thenReturnStringValue() throws IOException { + assertEquals(output.toString(), ExcelUtility.readExcel(fileLocation)); + + } + + @Test + public void givenStringPath_whenReadExcel_thenThrowException() { + assertThrows(IOException.class, () -> { + ExcelUtility.readExcel("baeldung"); + }); + } + +} diff --git a/apache-poi/src/test/resources/baeldung.xlsx b/apache-poi/src/test/resources/baeldung.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a6ed6c4e6ac8b0d3bd39dd4bb114bf5e0ab56479 GIT binary patch literal 16777 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