Skip to content

Commit

Permalink
Merge f75f2f9 into 12283d9
Browse files Browse the repository at this point in the history
  • Loading branch information
vaa25 committed Feb 2, 2020
2 parents 12283d9 + f75f2f9 commit d2333b9
Show file tree
Hide file tree
Showing 15 changed files with 824 additions and 9 deletions.
9 changes: 9 additions & 0 deletions src/main/java/com/poiji/annotation/ExcelCellName.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@
@Documented
public @interface ExcelCellName {

int ABSENT_ORDER = -1;

/**
* Specifies the column name where the corresponding value is mapped from the excel data
*
* @return column name
*/
String value();

/**
* Specifies the column order in saved file
*
* @return column order
*/
int order() default ABSENT_ORDER;
}
20 changes: 14 additions & 6 deletions src/main/java/com/poiji/bind/Poiji.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import com.poiji.exception.PoijiException;
import com.poiji.option.PoijiOptions;
import com.poiji.option.PoijiOptions.PoijiOptionsBuilder;
import com.poiji.save.FileSaverFactory;
import com.poiji.util.Files;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
Expand Down Expand Up @@ -207,17 +207,25 @@ public static synchronized <T> List<T> fromExcel(final InputStream inputStream,
* language access control and the underlying field is either inaccessible or final.
* @see Poiji#fromExcel(File, Class)
*/
public static synchronized <T> void fromExcel(final InputStream inputStream,
final PoijiExcelType excelType,
final Class<T> type,
final PoijiOptions options,
final Consumer<? super T> consumer) {
public static synchronized <T> void fromExcel(final InputStream inputStream, final PoijiExcelType excelType,
final Class<T> type, final PoijiOptions options, final Consumer<? super T> consumer
) {
Objects.requireNonNull(excelType);

final Unmarshaller unmarshaller = deserializer(inputStream, excelType, options);
unmarshaller.unmarshal(type, consumer);
}

public static <T> void toExcel(final File file, final Class<T> clazz, final List<T> data) {
toExcel(file, clazz, data, PoijiOptionsBuilder.settings().build());
}

public static <T> void toExcel(
final File file, final Class<T> clazz, final List<T> data, final PoijiOptions options
) {
new FileSaverFactory<>(clazz, options).toFile(file).save(data);
}

private static Unmarshaller deserializer(final File file, final PoijiOptions options) {
final PoijiFile<?> poijiFile = new PoijiFile<>(file);

Expand Down
27 changes: 26 additions & 1 deletion src/main/java/com/poiji/option/PoijiOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static com.poiji.util.PoijiConstants.DEFAULT_DATE_FORMATTER;
import static com.poiji.util.PoijiConstants.DEFAULT_DATE_PATTERN;
import static com.poiji.util.PoijiConstants.DEFAULT_DATE_TIME_FORMATTER;
import static com.poiji.util.PoijiConstants.DEFAULT_DATE_TIME_PATTERN;

/**
* Created by hakan on 17/01/2017.
Expand All @@ -24,6 +25,7 @@ public final class PoijiOptions {
private String dateRegex;
private String dateTimeRegex;
private String datePattern;
private String dateTimePattern;
private boolean dateLenient;
private boolean trimCellValue;
private boolean ignoreHiddenSheets;
Expand Down Expand Up @@ -58,6 +60,11 @@ private PoijiOptions setDatePattern(String datePattern) {
return this;
}

public PoijiOptions setDateTimePattern(final String dateTimePattern) {
this.dateTimePattern = dateTimePattern;
return this;
}

private PoijiOptions setDateFormatter(DateTimeFormatter dateFormatter) {
this.dateFormatter = dateFormatter;
return this;
Expand Down Expand Up @@ -86,6 +93,10 @@ public String datePattern() {
return datePattern;
}

public String getDateTimePattern() {
return dateTimePattern;
}

public DateTimeFormatter dateFormatter() {
return dateFormatter;
}
Expand Down Expand Up @@ -209,6 +220,7 @@ public static class PoijiOptionsBuilder {
private boolean preferNullOverDefault;
private String datePattern = DEFAULT_DATE_PATTERN;
private DateTimeFormatter dateFormatter = DEFAULT_DATE_FORMATTER;
private String dateTimePattern = DEFAULT_DATE_TIME_PATTERN;
private DateTimeFormatter dateTimeFormatter = DEFAULT_DATE_TIME_FORMATTER;
private Casting casting = new DefaultCasting();
private int headerStart = 0;
Expand Down Expand Up @@ -269,14 +281,26 @@ public PoijiOptionsBuilder dateTimeFormatter(DateTimeFormatter dateTimeFormatter
* set date pattern, default date format is "dd/M/yyyy" for
* java.util.Date
*
* @param datePattern date time formatter
* @param datePattern date pattern
* @return this
*/
public PoijiOptionsBuilder datePattern(String datePattern) {
this.datePattern = datePattern;
return this;
}

/**
* set date time pattern, default date time format is "dd/M/yyyy HH:mm:ss" for
* java.util.Date
*
* @param dateTimePattern date time pattern
* @return this
*/
public PoijiOptionsBuilder dateTimePattern(String dateTimePattern) {
this.dateTimePattern = dateTimePattern;
return this;
}

/**
* set whether or not to use null instead of default values for Integer,
* Double, Float, Long, String and java.util.Date types.
Expand All @@ -295,6 +319,7 @@ public PoijiOptions build() {
.setPassword(password)
.setPreferNullOverDefault(preferNullOverDefault)
.setDatePattern(datePattern)
.setDateTimePattern(dateTimePattern)
.setDateFormatter(dateFormatter)
.setDateTimeFormatter(dateTimeFormatter)
.setSheetIndex(sheetIndex)
Expand Down
138 changes: 138 additions & 0 deletions src/main/java/com/poiji/save/CellDataProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package com.poiji.save;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import org.apache.poi.hpsf.CustomProperties;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import static com.poiji.util.PoijiConstants.DATE_CELL_STYLE_INDEX_PROPERTY_NAME;
import static com.poiji.util.PoijiConstants.DATE_TIME_CELL_STYLE_INDEX_PROPERTY_NAME;

public final class CellDataProvider {

private final Map<Class<?>, BiConsumer<Cell, Object>> consumers;

public CellDataProvider() {
consumers = new ConcurrentHashMap<>();
consumers.put(Boolean.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((boolean) fieldValue);
}
});
consumers.put(boolean.class, (Cell cell, Object fieldValue) -> cell.setCellValue((boolean) fieldValue));
consumers.put(Double.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((double) fieldValue);
}
});
consumers.put(double.class, (Cell cell, Object fieldValue) -> cell.setCellValue((double) fieldValue));
consumers.put(Long.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((long) fieldValue);
}
});
consumers.put(long.class, (Cell cell, Object fieldValue) -> cell.setCellValue((long) fieldValue));
consumers.put(Integer.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((int) fieldValue);
}
});
consumers.put(int.class, (Cell cell, Object fieldValue) -> cell.setCellValue((int) fieldValue));
consumers.put(Byte.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((byte) fieldValue);
}
});
consumers.put(byte.class, (Cell cell, Object fieldValue) -> cell.setCellValue((byte) fieldValue));
consumers.put(Short.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((short) fieldValue);
}
});
consumers.put(short.class, (Cell cell, Object fieldValue) -> cell.setCellValue((short) fieldValue));
consumers.put(Float.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((float) fieldValue);
}
});
consumers.put(float.class, (Cell cell, Object fieldValue) -> cell.setCellValue((float) fieldValue));
consumers.put(java.util.Date.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((java.util.Date) fieldValue);
setStyleInCell(cell, DATE_TIME_CELL_STYLE_INDEX_PROPERTY_NAME);
}
});
consumers.put(java.sql.Date.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((java.util.Date) fieldValue);
setStyleInCell(cell, DATE_TIME_CELL_STYLE_INDEX_PROPERTY_NAME);
}
});
consumers.put(Calendar.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue((Calendar) fieldValue);
setStyleInCell(cell, DATE_TIME_CELL_STYLE_INDEX_PROPERTY_NAME);
}
});
consumers.put(LocalDateTime.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue(java.sql.Timestamp.valueOf((LocalDateTime) fieldValue));
setStyleInCell(cell, DATE_TIME_CELL_STYLE_INDEX_PROPERTY_NAME);
}
});
consumers.put(ZonedDateTime.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue(Date.from(Instant.from((TemporalAccessor) fieldValue)));
setStyleInCell(cell, DATE_TIME_CELL_STYLE_INDEX_PROPERTY_NAME);
}
});
consumers.put(LocalDate.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue(java.sql.Date.valueOf((LocalDate) fieldValue));
setStyleInCell(cell, DATE_CELL_STYLE_INDEX_PROPERTY_NAME);
}
});
consumers.put(Object.class, (Cell cell, Object fieldValue) -> {
if (fieldValue != null) {
cell.setCellValue(fieldValue.toString());
}
});
}

private void setStyleInCell(final Cell cell, final String propertyName) {
final Workbook workbook = cell.getSheet().getWorkbook();
if (workbook instanceof SXSSFWorkbook) {
final POIXMLProperties.CustomProperties properties = ((SXSSFWorkbook) workbook)
.getXSSFWorkbook()
.getProperties()
.getCustomProperties();
final int dateTimeCellStyleIndex = properties.getProperty(propertyName).getI4();
cell.setCellStyle(workbook.getCellStyleAt(dateTimeCellStyleIndex));
} else if (workbook instanceof HSSFWorkbook) {
final CustomProperties properties = ((HSSFWorkbook) workbook)
.getDocumentSummaryInformation()
.getCustomProperties();
final Short dateTimeCellStyleIndex = (Short) properties.get(propertyName);
cell.setCellStyle(workbook.getCellStyleAt(dateTimeCellStyleIndex));
} else {
throw new UnsupportedOperationException(workbook.getClass() + " is not supported");
}
}

public BiConsumer<Cell, Object> forType(final Class<?> type) {
return consumers.getOrDefault(type, consumers.get(Object.class));
}

}
8 changes: 8 additions & 0 deletions src/main/java/com/poiji/save/FileSaver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.poiji.save;

import java.util.List;

public interface FileSaver {

<T> void save(List<T> data);
}
31 changes: 31 additions & 0 deletions src/main/java/com/poiji/save/FileSaverFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.poiji.save;

import com.poiji.exception.InvalidExcelFileExtension;
import com.poiji.option.PoijiOptions;
import java.io.File;

import static com.poiji.util.PoijiConstants.XLSX_EXTENSION;
import static com.poiji.util.PoijiConstants.XLS_EXTENSION;

public final class FileSaverFactory<T> {

private final Class<T> entity;
private final PoijiOptions options;

public FileSaverFactory(final Class<T> entity, final PoijiOptions options) {
this.entity = entity;
this.options = options;
}

public FileSaver toFile(final File file) {
final MappedFields mappedFields = new MappedFields(entity).parseEntity();
if (file.toString().endsWith(XLSX_EXTENSION)) {
return new XlsxFileSaver(file, mappedFields, options);
} else if (file.toString().endsWith(XLS_EXTENSION)) {
return new XlsFileSaver(file, mappedFields, options);
} else {
throw new InvalidExcelFileExtension(file.getName() + " has unsupported extension. 'xlsx' and 'xls' are supported only.");
}
}

}
48 changes: 48 additions & 0 deletions src/main/java/com/poiji/save/FileWorkbookSaver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.poiji.save;

import com.poiji.exception.PoijiException;
import com.poiji.option.PoijiOptions;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.apache.poi.ss.usermodel.Workbook;

public class FileWorkbookSaver extends WorkbookSaver {

private final File file;

public FileWorkbookSaver(
final File file, final MappedFields mappedFields, final PoijiOptions options
) {
super(mappedFields, options);
this.file = file;
}

protected <T> void save(final List<T> data, final Workbook workbook) {
createFile();
writeInFile(data, workbook);
}

private <T> void writeInFile(final List<T> data, final Workbook workbook) {
try (final FileOutputStream outputStream = new FileOutputStream(file)) {
save(data, workbook, outputStream);
} catch (IOException e) {
throw new PoijiException(e.getMessage(), e);
}
}

private void createFile() {
final Path absolutePath = file.toPath().toAbsolutePath();
try {
Files.createDirectories(absolutePath.getParent());
Files.deleteIfExists(absolutePath);
Files.createFile(absolutePath);
} catch (IOException e) {
throw new PoijiException(e.getMessage(), e);
}
}

}
Loading

0 comments on commit d2333b9

Please sign in to comment.