Skip to content

Commit f6b4a25

Browse files
authored
Merge pull request #5 from MBenincasa/develop
Develop
2 parents 73f31d7 + 55e049f commit f6b4a25

33 files changed

+1479
-2417
lines changed

CHANGELOG.MD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# v0.3.0
2+
### Deprecations
3+
* The WorkbookUtility and SheetUtility classes have been deprecated
4+
* Several ExcelUtility methods have been deprecated
5+
### Features
6+
* The ExcelWorkbook, ExcelSheet, ExcelRow and ExceCell classes have been added. These classes wrap the Apache POI classes
7+
### Fixes
8+
* Several bugs have been fixed
9+
### Removed
10+
* Classes that have been deprecated since v0.2.0 have been removed
11+
112
# v0.2.1
213
### Features
314
* New services for writing to an existing Excel file that take different input parameters

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ Java 17 or above.
4545
<dependency>
4646
<groupId>org.junit.jupiter</groupId>
4747
<artifactId>junit-jupiter</artifactId>
48-
<version>RELEASE</version>
48+
<version>5.9.2</version>
49+
<scope>test</scope>
50+
</dependency>
51+
<dependency>
52+
<groupId>org.junit.platform</groupId>
53+
<artifactId>junit-platform-suite-engine</artifactId>
54+
<version>1.9.2</version>
4955
<scope>test</scope>
5056
</dependency>
5157
</dependencies>

pom.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.mbenincasa</groupId>
88
<artifactId>java-excel-utils</artifactId>
9-
<version>0.2.1</version>
9+
<version>0.3.0</version>
1010
<packaging>jar</packaging>
1111
<name>Java library with tools for Excel files</name>
1212
<description>Java library that collects tools and methods to speed up development with Excel sheets</description>
@@ -136,7 +136,13 @@
136136
<dependency>
137137
<groupId>org.junit.jupiter</groupId>
138138
<artifactId>junit-jupiter</artifactId>
139-
<version>RELEASE</version>
139+
<version>5.9.2</version>
140+
<scope>test</scope>
141+
</dependency>
142+
<dependency>
143+
<groupId>org.junit.platform</groupId>
144+
<artifactId>junit-platform-suite-engine</artifactId>
145+
<version>1.9.2</version>
140146
<scope>test</scope>
141147
</dependency>
142148
</dependencies>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package exceptions;
2+
3+
/**
4+
* This exception signals that there was an error reading a cell value
5+
* @author Mirko Benincasa
6+
* @since 0.3.0
7+
*/
8+
public class ReadValueException extends Exception {
9+
10+
/**
11+
* Constructs an {@code ReadValueException} with {@code null}
12+
* as its error detail message.
13+
*/
14+
public ReadValueException() {
15+
super();
16+
}
17+
18+
/**
19+
* Constructs an {@code ReadValueException} with the specified detail message.
20+
*
21+
* @param message
22+
* The detail message (which is saved for later retrieval
23+
* by the {@link #getMessage()} method)
24+
*/
25+
public ReadValueException(String message) {
26+
super(message);
27+
}
28+
29+
/**
30+
* Constructs an {@code ReadValueException} with the specified detail message
31+
* and cause.
32+
*
33+
* <p> Note that the detail message associated with {@code cause} is
34+
* <i>not</i> automatically incorporated into this exception's detail
35+
* message.
36+
*
37+
* @param message
38+
* The detail message (which is saved for later retrieval
39+
* by the {@link #getMessage()} method)
40+
*
41+
* @param cause
42+
* The cause (which is saved for later retrieval by the
43+
* {@link #getCause()} method). (A null value is permitted,
44+
* and indicates that the cause is nonexistent or unknown.)
45+
*/
46+
public ReadValueException(String message, Throwable cause) {
47+
super(message, cause);
48+
}
49+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package exceptions;
2+
3+
/**
4+
* This exception signals that you are trying to insert a sheet into a workbook that already contains that name
5+
* @author Mirko Benincasa
6+
* @since 0.3.0
7+
*/
8+
public class SheetAlreadyExistsException extends Exception {
9+
10+
/**
11+
* Constructs an {@code SheetAlreadyExistsException} with {@code null}
12+
* as its error detail message.
13+
*/
14+
public SheetAlreadyExistsException() {
15+
super();
16+
}
17+
18+
/**
19+
* Constructs an {@code SheetAlreadyExistsException} with the specified detail message.
20+
*
21+
* @param message
22+
* The detail message (which is saved for later retrieval
23+
* by the {@link #getMessage()} method)
24+
*/
25+
public SheetAlreadyExistsException(String message) {
26+
super(message);
27+
}
28+
29+
/**
30+
* Constructs an {@code SheetAlreadyExistsException} with the specified detail message
31+
* and cause.
32+
*
33+
* <p> Note that the detail message associated with {@code cause} is
34+
* <i>not</i> automatically incorporated into this exception's detail
35+
* message.
36+
*
37+
* @param message
38+
* The detail message (which is saved for later retrieval
39+
* by the {@link #getMessage()} method)
40+
*
41+
* @param cause
42+
* The cause (which is saved for later retrieval by the
43+
* {@link #getCause()} method). (A null value is permitted,
44+
* and indicates that the cause is nonexistent or unknown.)
45+
*/
46+
public SheetAlreadyExistsException(String message, Throwable cause) {
47+
super(message, cause);
48+
}
49+
}

src/main/java/model/ExcelCell.java

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package model;
2+
3+
import exceptions.ReadValueException;
4+
import lombok.AllArgsConstructor;
5+
import lombok.EqualsAndHashCode;
6+
import lombok.Getter;
7+
import org.apache.poi.ss.usermodel.Cell;
8+
import org.apache.poi.ss.usermodel.CellStyle;
9+
import org.apache.poi.ss.usermodel.FormulaEvaluator;
10+
import org.apache.poi.ss.usermodel.Row;
11+
12+
import java.time.LocalDate;
13+
import java.time.LocalDateTime;
14+
import java.util.Date;
15+
16+
/**
17+
* {@code ExcelCell} is the {@code Cell} wrapper class of the Apache POI library
18+
* @author Mirko Benincasa
19+
* @since 0.3.0
20+
*/
21+
@AllArgsConstructor
22+
@Getter
23+
@EqualsAndHashCode
24+
public class ExcelCell {
25+
26+
/**
27+
* This object refers to the Apache POI Library {@code Cell}
28+
*/
29+
private Cell cell;
30+
31+
/**
32+
* The index of the Cell in the Row
33+
*/
34+
private Integer index;
35+
36+
/**
37+
* Returns the Row to which it belongs
38+
* @return A ExcelRow
39+
*/
40+
public ExcelRow getRow() {
41+
Row row = this.cell.getRow();
42+
return new ExcelRow(row, row.getRowNum());
43+
}
44+
45+
/**
46+
* Read the value written inside the Cell
47+
* @param type The class type of the object written to the Cell
48+
* @return The value written in the Cell
49+
* @throws ReadValueException If an error occurs while reading
50+
*/
51+
public Object readValue(Class<?> type) throws ReadValueException {
52+
Object val;
53+
switch (this.cell.getCellType()) {
54+
case BOOLEAN -> val = this.cell.getBooleanCellValue();
55+
case STRING -> val = this.cell.getStringCellValue();
56+
case NUMERIC -> {
57+
if (Integer.class.equals(type)) {
58+
val = (int) this.cell.getNumericCellValue();
59+
} else if (Double.class.equals(type)) {
60+
val = this.cell.getNumericCellValue();
61+
} else if (Long.class.equals(type)) {
62+
val = (long) this.cell.getNumericCellValue();
63+
} else if (Date.class.equals(type)) {
64+
val = this.cell.getDateCellValue();
65+
} else if (LocalDateTime.class.equals(type)) {
66+
val = this.cell.getLocalDateTimeCellValue();
67+
} else if (LocalDate.class.equals(type)) {
68+
val = this.cell.getLocalDateTimeCellValue().toLocalDate();
69+
} else {
70+
throw new ReadValueException("This numeric type is not supported: " + type);
71+
}
72+
}
73+
case FORMULA -> {
74+
ExcelWorkbook excelWorkbook = this.getRow().getSheet().getWorkbook();
75+
FormulaEvaluator formulaEvaluator = excelWorkbook.getFormulaEvaluator();
76+
if (Boolean.class.equals(type)) {
77+
val = formulaEvaluator.evaluate(this.cell).getBooleanValue();
78+
} else {
79+
val = this.cell.getCellFormula();
80+
}
81+
}
82+
default -> throw new ReadValueException("Cell type not supported");
83+
}
84+
85+
return val;
86+
}
87+
88+
/**
89+
* Writes inside the cell
90+
* @param val The value to write in the Cell
91+
*/
92+
public void writeValue(Object val) {
93+
if (val instanceof Integer || val instanceof Long) {
94+
this.formatStyle((short) 1);
95+
this.cell.setCellValue(Integer.parseInt(String.valueOf(val)));
96+
} else if (val instanceof Double) {
97+
this.formatStyle((short) 4);
98+
this.cell.setCellValue(Double.parseDouble(String.valueOf(val)));
99+
} else if (val instanceof Date) {
100+
this.formatStyle((short) 22);
101+
this.cell.setCellValue((Date) val);
102+
} else if (val instanceof LocalDate) {
103+
this.formatStyle((short) 14);
104+
this.cell.setCellValue((LocalDate) val);
105+
} else if (val instanceof LocalDateTime) {
106+
this.formatStyle((short) 22);
107+
this.cell.setCellValue((LocalDateTime) val);
108+
} else if (val instanceof Boolean) {
109+
cell.setCellValue((Boolean) val);
110+
} else {
111+
cell.setCellValue(String.valueOf(val));
112+
}
113+
}
114+
115+
/**
116+
* Format text according to the pattern provided
117+
* @param dataFormat The Apache POI library CellStyle dataFormat
118+
*/
119+
public void formatStyle(short dataFormat) {
120+
ExcelWorkbook excelWorkbook = this.getRow().getSheet().getWorkbook();
121+
CellStyle newCellStyle = excelWorkbook.getWorkbook().createCellStyle();
122+
newCellStyle.cloneStyleFrom(this.cell.getCellStyle());
123+
newCellStyle.setDataFormat(dataFormat);
124+
this.cell.setCellStyle(newCellStyle);
125+
}
126+
}

src/main/java/model/ExcelRow.java

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package model;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.Getter;
6+
import lombok.SneakyThrows;
7+
import org.apache.poi.ss.usermodel.Cell;
8+
import org.apache.poi.ss.usermodel.Row;
9+
import org.apache.poi.ss.usermodel.Sheet;
10+
11+
import java.util.LinkedList;
12+
import java.util.List;
13+
14+
/**
15+
* {@code ExcelRow} is the {@code Row} wrapper class of the Apache POI library
16+
* @author Mirko Benincasa
17+
* @since 0.3.0
18+
*/
19+
@AllArgsConstructor
20+
@Getter
21+
@EqualsAndHashCode
22+
public class ExcelRow {
23+
24+
/**
25+
* This object refers to the Apache POI Library {@code Row}
26+
*/
27+
private Row row;
28+
29+
/**
30+
* The index of the Row in the Sheet
31+
*/
32+
private Integer index;
33+
34+
/**
35+
* The list of Cells related to the Row
36+
* @return A list of Cells
37+
*/
38+
public List<ExcelCell> getCells() {
39+
List<ExcelCell> excelCells = new LinkedList<>();
40+
for (Cell cell : this.row) {
41+
excelCells.add(new ExcelCell(cell, cell.getColumnIndex()));
42+
}
43+
44+
return excelCells;
45+
}
46+
47+
/**
48+
* Returns the Sheet to which it belongs
49+
* @return A ExcelSheet
50+
*/
51+
@SneakyThrows
52+
public ExcelSheet getSheet() {
53+
Sheet sheet = this.row.getSheet();
54+
ExcelWorkbook excelWorkbook = new ExcelWorkbook(sheet.getWorkbook());
55+
String sheetName = sheet.getSheetName();
56+
return new ExcelSheet(sheet, excelWorkbook.getSheet(sheetName).getIndex(), sheetName);
57+
}
58+
59+
/**
60+
* Create a new Cell in the Row
61+
* @param index The index in the Row
62+
* @return A Cell
63+
*/
64+
public ExcelCell createCell(Integer index) {
65+
return new ExcelCell(this.row.createCell(index), index);
66+
}
67+
68+
/**
69+
* Retrieves the index of the last Cell
70+
* @return The index of the last Cell
71+
*/
72+
public Integer getLastColumnIndex() {
73+
return this.row.getLastCellNum() - 1;
74+
}
75+
76+
/**
77+
* Counts how many Cells are compiled
78+
* @param alsoEmpty {@code true} if you want to count Cells empty
79+
* @return The number of Cells compiled
80+
*/
81+
public Integer countAllColumns(Boolean alsoEmpty) {
82+
Integer count = this.getLastColumnIndex() + 1;
83+
if (alsoEmpty)
84+
return count;
85+
86+
for (int i = 0; i < this.row.getPhysicalNumberOfCells(); i++) {
87+
Cell cell = this.row.getCell(i);
88+
if (cell == null) {
89+
count--;
90+
continue;
91+
}
92+
93+
Object val;
94+
switch (cell.getCellType()) {
95+
case NUMERIC -> val = cell.getNumericCellValue();
96+
case BOOLEAN -> val = cell.getBooleanCellValue();
97+
default -> val = cell.getStringCellValue();
98+
}
99+
100+
if (val == null) {
101+
count--;
102+
}
103+
}
104+
105+
return count;
106+
}
107+
}

0 commit comments

Comments
 (0)