Skip to content

Added Support for JPA Entities export. #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -2,3 +2,5 @@
/target
/.classpath
/.project
.~users.xlsx
users.xlsx
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -238,3 +238,22 @@ Add xcelite as a dependency:
<version>1.0.4</version>
</dependency>
```
### OR
Add this repository as dependency, if you want support for Jpa data export.
```xml
<repositories>
<repository>
<id>Github</id>
<name>Github repository</name>
<url>https://raw.github.com/boriswaguia/xcelite/release</url>
</repository>
</repositories>
```

```xml
<dependency>
<groupId>com.ebay</groupId>
<artifactId>xcelite</artifactId>
<version>1.0.5-SNAPSHOT</version>
</dependency>
```
18 changes: 17 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.ebay</groupId>
<artifactId>xcelite</artifactId>
<version>1.0.5-SNAPSHOT</version>
<version>1.0.8-SNAPSHOT</version>
<packaging>jar</packaging>
<name>xcelite</name>
<description>Xcelite is an ORM like Java library which allows you to easily serialize and deserialize Java beans to/from Excel spreadsheets</description>
@@ -74,6 +74,9 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
@@ -120,5 +123,18 @@
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.0-api -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
8 changes: 7 additions & 1 deletion src/main/java/com/ebay/xcelite/column/Col.java
Original file line number Diff line number Diff line change
@@ -38,10 +38,16 @@ public Col(String name) {
}

public Col(String name, String fieldName) {
this(name, fieldName, String.class);
}


public Col(String name, String fieldName, Class<?> type) {
this.name = name;
this.fieldName = fieldName;
type = String.class;
this.type = type;
}


@Override
public String toString() {
49 changes: 47 additions & 2 deletions src/main/java/com/ebay/xcelite/column/ColumnsExtractor.java
Original file line number Diff line number Diff line change
@@ -22,6 +22,9 @@
import java.util.Map;
import java.util.Set;

import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.reflections.ReflectionUtils;

import com.ebay.xcelite.annotate.NoConverterClass;
@@ -79,7 +82,7 @@ public void extract() {
col.setConverter(annotation.converter());
}
columns.add(col);
}
}

if (colsOrdering != null) {
orderColumns();
@@ -88,6 +91,48 @@ public void extract() {
extractAnyColumn();
}


@SuppressWarnings("unchecked")
public void extractJpa() {
Set<Field> idFields = ReflectionUtils.getAllFields(type, withAnnotation(javax.persistence.Id.class));
Set<Field> columnFields = ReflectionUtils.getAllFields(type, withAnnotation(javax.persistence.Column.class));
Set<Field> manyToOneFields = ReflectionUtils.getAllFields(type, withAnnotation(javax.persistence.ManyToOne.class));

for (Field columnField : idFields) {
javax.persistence.Id annotation = columnField.getAnnotation(javax.persistence.Id.class);
if(annotation == null) continue;
Col col = null;
col = new Col(columnField.getName(), columnField.getName(), columnField.getType());
columns.add(col);
}

for (Field columnField : columnFields) {
javax.persistence.Column annotation = columnField.getAnnotation(javax.persistence.Column.class);
if(annotation == null) continue;
Col col = null;
if (annotation.name().isEmpty()) {
col = new Col(columnField.getName(), columnField.getName(), columnField.getType());
} else {
col = new Col(annotation.name(), columnField.getName(), columnField.getType());
}
columns.add(col);
}

for (Field columnField : manyToOneFields) {
ManyToOne annotation = columnField.getAnnotation(javax.persistence.ManyToOne.class);
Col col = null;
if(annotation == null) continue;
JoinColumn joinColumn = columnField.getAnnotation(javax.persistence.JoinColumn.class);
if (joinColumn.name().isEmpty()) {
col = new Col(columnField.getName(), columnField.getName(), columnField.getType());
} else {
col = new Col(joinColumn.name(), columnField.getName(), columnField.getType());
}
columns.add(col);
}
}


@SuppressWarnings("unchecked")
private void extractAnyColumn() {
Set<Field> anyColumnFields = ReflectionUtils.getAllFields(type, withAnnotation(AnyColumn.class));
@@ -108,7 +153,7 @@ private void extractAnyColumn() {
if (annotation.converter() != NoConverterClass.class) {
anyColumn.setConverter(annotation.converter());
}
}
}
}

private void orderColumns() {
38 changes: 33 additions & 5 deletions src/main/java/com/ebay/xcelite/reader/BeanSheetReader.java
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
import java.util.Map;
import java.util.Set;

import org.apache.poi.ss.format.CellFormatType;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
@@ -63,6 +64,7 @@ public BeanSheetReader(XceliteSheet sheet, Class<T> type) {
this.type = type;
ColumnsExtractor extractor = new ColumnsExtractor(type);
extractor.extract();
extractor.extractJpa();
columns = extractor.getColumns();
anyColumn = extractor.getAnyColumn();
mapper = new ColumnsMapper(columns);
@@ -164,18 +166,41 @@ private void writeToAnyColumnField(Field field, T object, Cell cell, String colu
@SuppressWarnings("unchecked")
private void writeToField(Field field, T object, Cell cell, Col column) {
try {
Object cellValue = readValueFromCell(cell);
Object cellValue = readValueFromCell(cell);
if(cellValue == null && (field.getType() == Boolean.class || field.getType() == boolean.class)) {
cellValue = Boolean.FALSE;
}
if (cellValue != null) {
if (column.getConverter() != null) {
ColumnValueConverter<Object, ?> converter = (ColumnValueConverter<Object, ?>) column.getConverter()
.newInstance();
cellValue = converter.deserialize(cellValue);
} else {
cellValue = convertToFieldType(cellValue, field.getType());
cellValue = convertToFieldType(cellValue, field.getType(), column);
}
}
field.setAccessible(true);
field.set(object, cellValue);
boolean annotationPresent = field.isAnnotationPresent(javax.persistence.ManyToOne.class);
if(!annotationPresent) {
field.setAccessible(true);
field.set(object, cellValue);
} else {
Object instance = field.getType().newInstance();
Field[] declaredFields = instance.getClass().getDeclaredFields();
Field idField = null;
for (Field f : declaredFields) {
if(f.isAnnotationPresent(javax.persistence.Id.class)) {
idField = f;
break;
}
}
if(idField == null) idField = declaredFields[0];
// Set the id field in the instance
idField.setAccessible(true);
idField.set(instance, cellValue);
// Set the object value
field.setAccessible(true);
field.set(object, instance);
}
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
@@ -184,7 +209,7 @@ private void writeToField(Field field, T object, Cell cell, Col column) {
}
}

private Object convertToFieldType(Object cellValue, Class<?> fieldType) {
private Object convertToFieldType(Object cellValue, Class<?> fieldType, Col column) {
String value = String.valueOf(cellValue);
if (fieldType == Double.class || fieldType == double.class) {
return Double.valueOf(value);
@@ -207,6 +232,9 @@ private Object convertToFieldType(Object cellValue, Class<?> fieldType) {
if (fieldType == Date.class) {
return DateUtil.getJavaDate(Double.valueOf(value));
}
if(fieldType == Boolean.class || fieldType == boolean.class) {
return Boolean.valueOf(value);
}
return value;
}

3 changes: 2 additions & 1 deletion src/main/java/com/ebay/xcelite/styles/CellStyles.java
Original file line number Diff line number Diff line change
@@ -22,7 +22,8 @@

public final class CellStyles {

private final String DEFAULT_DATE_FORMAT = "ddd mmm dd hh:mm:ss yyy";
// private final String DEFAULT_DATE_FORMAT = "ddd mmm dd hh:mm:ss yyy";
private final String DEFAULT_DATE_FORMAT = "dd/mm/yyyy hh:mm:ss";

private final Workbook wb;
private CellStyle boldStyle;
7 changes: 5 additions & 2 deletions src/main/java/com/ebay/xcelite/writer/BeanSheetWriter.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.reflections.ReflectionUtils;

import com.ebay.xcelite.annotate.NoConverterClass;
@@ -46,6 +47,7 @@ public BeanSheetWriter(XceliteSheet sheet, Class<T> type) {
super(sheet, true);
ColumnsExtractor extractor = new ColumnsExtractor(type);
extractor.extract();
extractor.extractJpa();
columns = extractor.getColumns();
anyColumn = extractor.getAnyColumn();
}
@@ -119,8 +121,9 @@ private void writeToCell(Cell cell, Col col, Object fieldValueObj) {
}

if (col.getType() == Date.class) {
if (col.getDataFormat() == null) {
cell.setCellStyle(CellStylesBank.get(sheet.getNativeSheet().getWorkbook()).getDateStyle());
if (col.getDataFormat() == null) {
CellStyle dateStyle = CellStylesBank.get(sheet.getNativeSheet().getWorkbook()).getDateStyle();
cell.setCellStyle(dateStyle);
}
}

62 changes: 60 additions & 2 deletions src/main/java/com/ebay/xcelite/writer/SheetWriterAbs.java
Original file line number Diff line number Diff line change
@@ -15,8 +15,11 @@
*/
package com.ebay.xcelite.writer;

import java.lang.reflect.Field;
import java.util.Date;

import javax.persistence.Entity;

import org.apache.poi.ss.usermodel.Cell;

import com.ebay.xcelite.sheet.XceliteSheet;
@@ -30,6 +33,7 @@
*/
public abstract class SheetWriterAbs<T> implements SheetWriter<T> {

private static final int MAX_EXCEL_CELL_CARACTERS = 32767;
protected XceliteSheet sheet;
protected boolean writeHeader;

@@ -52,11 +56,65 @@ protected void writeToCell(Cell cell, Object fieldValueObj, Class<?> dataType) {
|| type == Short.class || type == short.class) {
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(Double.valueOf(fieldValueObj.toString()));
} else {
} else if (type == String.class) {
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue(fieldValueObj.toString());
String cellValue = extractStringValue(fieldValueObj);
cell.setCellValue(cellValue);
} else {
Entity entity = type.getAnnotation(javax.persistence.Entity.class);
if(entity != null) {
try {
Field[] fields = type.getDeclaredFields();
Field idField = getIdField(fields);
Object value = null;
// If no Id field
if(idField == null && fields.length > 0) {
// TODO : Maybe We should sorts field by name and pick the first one. So that the reverse operation can be easy.
idField = fields[0]; // Pick a random field
}
try {
idField.setAccessible(true);
value = idField.get(fieldValueObj);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
if(value == null) value = "NOREF";
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue(value.toString());
} catch (SecurityException e) {
throw new RuntimeException(e);
}
}
}
}

/**
* Extract the String value, and shrink it to fix excell string size.
* @param fieldValueObj
* @return
*/
private String extractStringValue(Object fieldValueObj) {
String cellValue = fieldValueObj.toString();
if(cellValue == null) cellValue = "";
if(cellValue.length() > MAX_EXCEL_CELL_CARACTERS) {
cellValue = cellValue.substring(0, 32764);
cellValue += "...";
}
return cellValue;
}

private Field getIdField(Field[] fields) {
Field idField = null;
for (Field field : fields) {
if(field.getAnnotation(javax.persistence.Id.class) != null) {
idField = field;
break;
}
}
return idField;
}

@Override
public void generateHeaderRow(boolean generateHeaderRow) {
Empty file removed src/test/java/tmp
Empty file.