diff --git a/poi-util/src/main/java/de/muehlencord/shared/poi/PoiException.java b/poi-util/src/main/java/de/muehlencord/shared/poi/PoiException.java
new file mode 100644
index 0000000..d81e532
--- /dev/null
+++ b/poi-util/src/main/java/de/muehlencord/shared/poi/PoiException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019 joern.muehlencord.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.muehlencord.shared.poi;
+
+/**
+ *
+ * @author joern.muehlencord
+ */
+public class PoiException extends Exception {
+
+ /**
+ * Creates a new instance of PoiException without detail
+ * message.
+ */
+ public PoiException() {
+ }
+
+ /**
+ * Constructs an instance of PoiException with the specified
+ * detail message.
+ *
+ * @param msg the detail message.
+ */
+ public PoiException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs an instance of PoiException with the specified
+ * detail message.
+ *
+ * @param msg the detail message.
+ * @param th the root cause of this exception
+ */
+ public PoiException(String msg, Throwable th) {
+ super(msg, th);
+ }
+}
diff --git a/poi-util/src/main/java/de/muehlencord/shared/poi/PoiUtil.java b/poi-util/src/main/java/de/muehlencord/shared/poi/PoiUtil.java
index 1898de4..08c92ad 100644
--- a/poi-util/src/main/java/de/muehlencord/shared/poi/PoiUtil.java
+++ b/poi-util/src/main/java/de/muehlencord/shared/poi/PoiUtil.java
@@ -15,8 +15,23 @@
*/
package de.muehlencord.shared.poi;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.Date;
import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.CreationHelper;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.RichTextString;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
*
@@ -24,21 +39,212 @@ import org.apache.poi.ss.usermodel.CellType;
*/
public abstract class PoiUtil {
+ private static final Logger LOGGER = LoggerFactory.getLogger(PoiUtil.class);
+
private PoiUtil() {
// hide constructor of abstract classes
}
-
+
public static boolean cellEmpty(Cell cell) {
- if (cell == null)
+ if (cell == null) {
return true;
- if (cell.getCellType() == CellType.BLANK)
- return true;
- if (cell.getCellType() == CellType.STRING) {
- return cell.getStringCellValue().equals ("");
}
- return false;
+ if (cell.getCellType() == CellType.BLANK) {
+ return true;
+ }
+ if (cell.getCellType() == CellType.STRING) {
+ return cell.getStringCellValue().equals("");
+ }
+ return false;
}
-
-
-
+
+ public static Cell createOrGetCell(Row row, int cellNumber, CellStyle cellStyle) {
+ Cell currentCell = row.getCell(cellNumber);
+ if (currentCell == null) {
+ currentCell = row.createCell(cellNumber);
+ }
+ if (cellStyle != null) {
+ currentCell.setCellStyle(cellStyle);
+ }
+ return currentCell;
+ }
+
+ public static Cell setStringValue(Row row, int cellNumber, String stringValue, CellStyle cellStyle) {
+ Cell currentCell = createOrGetCell(row, cellNumber, cellStyle);
+ if (stringValue != null) {
+ currentCell.setCellValue(stringValue);
+ }
+ return currentCell;
+ }
+
+ public static void addCellComment(XSSFWorkbook wb, Row row, int cellNumber, String cellComment) {
+ addCellComment(wb, row, cellNumber, cellComment, 3, 1);
+ }
+
+ public static void addCellComment(XSSFWorkbook wb, Row row, int cellNumber, String cellComment, int rowCount, int columnCount) {
+ Drawing drawing = row.getSheet().createDrawingPatriarch();
+ CreationHelper factory = wb.getCreationHelper();
+
+ Cell cell = createOrGetCell(row, cellNumber, null);
+
+ // When the comment box is visible, have it show in a 1x3 space
+ ClientAnchor anchor = factory.createClientAnchor();
+ anchor.setCol1(cell.getColumnIndex());
+ anchor.setCol2(cell.getColumnIndex() + columnCount);
+ anchor.setRow1(row.getRowNum());
+ anchor.setRow2(row.getRowNum() + rowCount);
+
+ // Create the comment and set the text+author
+ Comment comment = drawing.createCellComment(anchor);
+ RichTextString str = factory.createRichTextString(cellComment);
+ comment.setString(str);
+ comment.setAuthor("PCD");
+
+ // Assign the comment to the cell
+ cell.setCellComment(comment);
+ }
+
+ public static void setDateValue(Row row, int cellNumber, Date date, CellStyle cellStyle) {
+ Cell currentCell = createOrGetCell(row, cellNumber, cellStyle);
+ if (date != null) {
+ currentCell.setCellValue(date);
+ }
+ }
+
+ public static void setDoubleValue(Row row, int cellNumber, Double value, CellStyle cellStyle) {
+ Cell currentCell = createOrGetCell(row, cellNumber, cellStyle);
+ if (value != null) {
+ currentCell.setCellValue(value);
+ }
+ }
+
+ public static void setBooleanValue(Row row, int cellNumber, boolean value, CellStyle cellStyle) {
+ Cell currentCell = createOrGetCell(row, cellNumber, cellStyle);
+ currentCell.setCellValue(value);
+ }
+
+ public static void setDateValue(Row row, int cellNumber, String dateString, String dateFormat, CellStyle cellStyle) {
+ Cell currentCell = createOrGetCell(row, cellNumber, cellStyle);
+ SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
+ Date date;
+ try {
+ date = sdf.parse(dateString);
+ } catch (ParseException ex) {
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace(ex.toString(), ex);
+ }
+ date = null;
+ }
+ currentCell.setCellValue(date);
+ }
+
+ public static String getStringValue(Row row, int cellNumber) throws PoiException {
+ return getStringValue(row, cellNumber, false, null);
+ }
+
+ public static String getStringValue(Row row, int cellNumber, boolean returnDefaultValue, String defaultValue) throws PoiException {
+ if (row == null) {
+ throw new PoiException("Current row must not be null");
+ }
+ Cell cell = row.getCell(cellNumber);
+ if ((PoiUtil.cellEmpty(cell)) && !returnDefaultValue) {
+ throw new PoiException("Cannot read cell " + cellNumber + " from row " + row.getRowNum());
+ } else {
+ if (PoiUtil.cellEmpty(cell)) {
+ return defaultValue;
+ } else {
+ if (cell.getCellType() == CellType.NUMERIC) {
+ Double doubleValue = cell.getNumericCellValue();
+ return Integer.toString(doubleValue.intValue());
+ } else {
+ String returnValue = cell.getStringCellValue();
+ if (returnValue != null) {
+ returnValue = returnValue.trim();
+ returnValue = replaceProblematicCharacters(returnValue);
+ }
+ return returnValue;
+ }
+ }
+ }
+ }
+
+ public static LocalDate getDateValue(Row row, int cellNumber) throws PoiException {
+ return getDateValue(row, cellNumber, false, null);
+ }
+
+ public static LocalDate getDateValue(Row row, int cellNumber, boolean returnDefaultValue, LocalDate defaultValue) throws PoiException {
+ if (row == null) {
+ throw new PoiException("Current row must not be null");
+ }
+ Cell cell = row.getCell(cellNumber);
+ if ((PoiUtil.cellEmpty(cell)) && !returnDefaultValue) {
+ throw new PoiException("Cannot read cell " + cellNumber + " from row " + row.getRowNum());
+ } else {
+ if (PoiUtil.cellEmpty(cell)) {
+ return defaultValue;
+ } else {
+ Date date = cell.getDateCellValue();
+ if (date == null) {
+ if (returnDefaultValue) {
+ return defaultValue;
+ } else {
+ throw new PoiException("Cell contains null value but not default value shall be returned");
+ }
+ }
+ return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+ }
+ }
+ }
+
+ public static boolean getBooleanValue(Row currentRow, int cellNumber, boolean returnDefaultValue, boolean defaultValue) throws PoiException {
+ if (currentRow == null) {
+ throw new PoiException("Current row must not be null");
+ }
+ Cell cell = currentRow.getCell(cellNumber);
+ if ((PoiUtil.cellEmpty(cell)) && !returnDefaultValue) {
+ throw new PoiException("Cannot read cell " + cellNumber + " from row " + currentRow.getRowNum());
+ } else {
+ if (PoiUtil.cellEmpty(cell)) {
+ return defaultValue;
+ } else {
+ return cell.getBooleanCellValue();
+ }
+ }
+ }
+
+ public static double getDoubleValue(Row currentRow, int cellNumber) throws PoiException {
+ return getDoubleValue(currentRow, cellNumber, false, 0D);
+ }
+
+ public static Double getDoubleValue(Row currentRow, int cellNumber, boolean returnDefaultValue, Double defaultValue) throws PoiException {
+ if (currentRow == null) {
+ throw new PoiException("Current row must not be null");
+ }
+ Cell cell = currentRow.getCell(cellNumber);
+ if ((PoiUtil.cellEmpty(cell)) && !returnDefaultValue) {
+ throw new PoiException("Cannot read cell " + cellNumber + " from row " + currentRow.getRowNum());
+ } else {
+ if (PoiUtil.cellEmpty(cell)) {
+ return defaultValue;
+ } else {
+ return cell.getNumericCellValue();
+ }
+ }
+ }
+
+ /**
+ * remove charecters which often cause troubles in other applications - e.g. em dash (long dash) is created by Excel automatically
+ * @param sourceValue the input string to execute the replacement
+ * @return sourceValue with replaced characters
+ */
+ protected static String replaceProblematicCharacters(final String sourceValue) {
+ String returnValue = sourceValue;
+ returnValue = returnValue.replace("\u2011", "-");
+ returnValue = returnValue.replace("\u2012", "-");
+ returnValue = returnValue.replace("\u2013", "-");
+ returnValue = returnValue.replace("\u2014", "-");
+
+ return returnValue;
+ }
+
}
diff --git a/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java b/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java
index 974f2c4..4f9f5a1 100644
--- a/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java
+++ b/poi-util/src/main/java/de/muehlencord/shared/poi/WorkbookApp.java
@@ -315,5 +315,5 @@ public class WorkbookApp {
sheet.autoSizeColumn(currentColumn);
}
}
-
+
}