@@ -47,6 +47,7 @@ public @interface Excel { | |||||
* 导入的时间格式,以这个是否为空来判断是否需要格式化日期 | * 导入的时间格式,以这个是否为空来判断是否需要格式化日期 | ||||
*/ | */ | ||||
public String importFormat() default ""; | public String importFormat() default ""; | ||||
/** | /** | ||||
* 文字后缀,如% 90 变成90% | * 文字后缀,如% 90 变成90% | ||||
*/ | */ | ||||
@@ -104,4 +105,11 @@ public @interface Excel { | |||||
* 性别列4【男女占1,但是列标题两个汉字】 限制1-255 | * 性别列4【男女占1,但是列标题两个汉字】 限制1-255 | ||||
*/ | */ | ||||
public int width() default 10; | public int width() default 10; | ||||
/** | |||||
* 是否自动统计数据,如果是统计,true的话在最后追加一行统计,把所有数据都和 | |||||
* 这个处理会吞没异常,请注意这一点 | |||||
* @return | |||||
*/ | |||||
public boolean isStatistics() default false; | |||||
} | } |
@@ -8,6 +8,15 @@ import org.jeecgframework.poi.handler.inter.IExcelDataHandler; | |||||
* @date 2014年6月20日 下午1:56:52 | * @date 2014年6月20日 下午1:56:52 | ||||
*/ | */ | ||||
public class ExcelBaseParams { | public class ExcelBaseParams { | ||||
/** | |||||
* 03版本Excel | |||||
*/ | |||||
public static final String HSSF = "HSSF"; | |||||
/** | |||||
* 07版本Excel | |||||
*/ | |||||
public static final String XSSF = "XSSF"; | |||||
/** | /** | ||||
* 数据处理接口,以此为主,replace,format都在这后面 | * 数据处理接口,以此为主,replace,format都在这后面 | ||||
*/ | */ | ||||
@@ -54,6 +54,10 @@ public class ExcelExportEntity extends ExcelBaseEntity { | |||||
* 后缀 | * 后缀 | ||||
*/ | */ | ||||
private String suffix; | private String suffix; | ||||
/** | |||||
* 统计 | |||||
*/ | |||||
private boolean isStatistics; | |||||
private List<ExcelExportEntity> list; | private List<ExcelExportEntity> list; | ||||
@@ -172,4 +176,12 @@ public class ExcelExportEntity extends ExcelBaseEntity { | |||||
this.suffix = suffix; | this.suffix = suffix; | ||||
} | } | ||||
public boolean isStatistics() { | |||||
return isStatistics; | |||||
} | |||||
public void setStatistics(boolean isStatistics) { | |||||
this.isStatistics = isStatistics; | |||||
} | |||||
} | } |
@@ -139,12 +139,16 @@ public class ExcelExportServer extends ExcelExportBase { | |||||
its.next(); | its.next(); | ||||
its.remove(); | its.remove(); | ||||
} | } | ||||
// 创建合计信息 | |||||
addStatisticsRow(styles.get("one"),sheet); | |||||
// 发现还有剩余list 继续循环创建Sheet | // 发现还有剩余list 继续循环创建Sheet | ||||
if (dataSet.size() > 0) { | if (dataSet.size() > 0) { | ||||
createSheet(workbook, entity, pojoClass, dataSet, type); | createSheet(workbook, entity, pojoClass, dataSet, type); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
e.printStackTrace(); | |||||
logger.error(e.getMessage(), e.fillInStackTrace()); | logger.error(e.getMessage(), e.fillInStackTrace()); | ||||
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | ||||
} | } | ||||
@@ -4,6 +4,7 @@ import java.awt.image.BufferedImage; | |||||
import java.io.ByteArrayOutputStream; | import java.io.ByteArrayOutputStream; | ||||
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.text.DecimalFormat; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Collection; | import java.util.Collection; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
@@ -40,9 +41,13 @@ import org.jeecgframework.poi.util.POIPublicUtil; | |||||
*/ | */ | ||||
public abstract class ExcelExportBase extends ExportBase { | public abstract class ExcelExportBase extends ExportBase { | ||||
private int currentIndex = 0; | |||||
private int currentIndex = 0; | |||||
protected String type = PoiBaseConstants.HSSF; | |||||
protected String type = PoiBaseConstants.HSSF; | |||||
private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); | |||||
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); | |||||
private boolean checkIsEqualByCellContents(MergeEntity mergeEntity, String text, Cell cell, | private boolean checkIsEqualByCellContents(MergeEntity mergeEntity, String text, Cell cell, | ||||
int[] delys, int rowNum) { | int[] delys, int rowNum) { | ||||
@@ -259,6 +264,43 @@ public abstract class ExcelExportBase extends ExportBase { | |||||
if (style != null) { | if (style != null) { | ||||
cell.setCellStyle(style); | cell.setCellStyle(style); | ||||
} | } | ||||
addStatisticsData(index, text, entity); | |||||
} | |||||
/** | |||||
* 创建统计行 | |||||
* @param styles | |||||
* @param sheet | |||||
*/ | |||||
public void addStatisticsRow(CellStyle styles, Sheet sheet) { | |||||
Row row = sheet.createRow(sheet.getLastRowNum() + 1); | |||||
Set<Integer> keys = statistics.keySet(); | |||||
createStringCell(row, 0, "合计", styles, null); | |||||
for (Integer key : keys) { | |||||
createStringCell(row, key, DOUBLE_FORMAT.format(statistics.get(key)), styles, null); | |||||
} | |||||
statistics.clear(); | |||||
} | |||||
/** | |||||
* 合计统计信息 | |||||
* @param index | |||||
* @param text | |||||
* @param entity | |||||
*/ | |||||
private void addStatisticsData(Integer index, String text, ExcelExportEntity entity) { | |||||
if (entity != null && entity.isStatistics()) { | |||||
Double temp = 0D; | |||||
if (!statistics.containsKey(index)) { | |||||
statistics.put(index, temp); | |||||
} | |||||
try { | |||||
temp = Double.valueOf(text); | |||||
} catch (NumberFormatException e) { | |||||
} | |||||
statistics.put(index, statistics.get(index) + temp); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -203,6 +203,7 @@ public class ExportBase { | |||||
excelEntity.setDatabaseFormat(excel.databaseFormat()); | excelEntity.setDatabaseFormat(excel.databaseFormat()); | ||||
excelEntity.setFormat(StringUtils.isNotEmpty(excel.exportFormat()) ? excel.exportFormat() | excelEntity.setFormat(StringUtils.isNotEmpty(excel.exportFormat()) ? excel.exportFormat() | ||||
: excel.format()); | : excel.format()); | ||||
excelEntity.setStatistics(excel.isStatistics()); | |||||
String fieldname = field.getName(); | String fieldname = field.getName(); | ||||
excelEntity.setMethod(POIPublicUtil.getMethod(fieldname, pojoClass)); | excelEntity.setMethod(POIPublicUtil.getMethod(fieldname, pojoClass)); | ||||
} | } | ||||
@@ -22,17 +22,17 @@ public class CourseEntity implements java.io.Serializable { | |||||
/** 主键 */ | /** 主键 */ | ||||
private String id; | private String id; | ||||
/** 课程名称 */ | /** 课程名称 */ | ||||
@Excel(name = "课程名称", orderNum = "1", needMerge = true) | |||||
@Excel(name = "课程名称", orderNum = "1", width = 15, needMerge = true) | |||||
private String name; | private String name; | ||||
/** 老师主键 */ | /** 老师主键 */ | ||||
@ExcelEntity(id = "yuwen") | @ExcelEntity(id = "yuwen") | ||||
@ExcelVerify() | @ExcelVerify() | ||||
private TeacherEntity teacher; | private TeacherEntity teacher; | ||||
/** 老师主键 */ | /** 老师主键 */ | ||||
@ExcelEntity(id = "shuxue") | |||||
//@ExcelEntity(id = "shuxue") | |||||
private TeacherEntity shuxueteacher; | private TeacherEntity shuxueteacher; | ||||
@ExcelCollection(name = "选课学生", orderNum = "4") | |||||
//@ExcelCollection(name = "选课学生", orderNum = "4") | |||||
private List<StudentEntity> students; | private List<StudentEntity> students; | ||||
/** | /** | ||||
@@ -25,20 +25,16 @@ public class StudentEntity implements java.io.Serializable { | |||||
/** | /** | ||||
* 学生性别 | * 学生性别 | ||||
*/ | */ | ||||
@Excel(name = "学生性别", replace = { "男_1", "女_2" },suffix = "生") | |||||
@Excel(name = "学生性别", replace = { "男_1", "女_2" }, suffix = "生", mergeVertical = true) | |||||
private int sex; | private int sex; | ||||
@Excel(name = "出生日期", format = "yyyy-MM-dd HH:mm:ss", mergeVertical = true) | |||||
@Excel(name = "出生日期", databaseFormat = "yyyyMMddHHmmss", exportFormat = "yyyy-MM-dd", mergeVertical = true) | |||||
private Date birthday; | private Date birthday; | ||||
/** | /** | ||||
* 课程主键 | * 课程主键 | ||||
*/ | */ | ||||
private CourseEntity course; | private CourseEntity course; | ||||
public Date getBirthday() { | |||||
return birthday; | |||||
} | |||||
public CourseEntity getCourse() { | public CourseEntity getCourse() { | ||||
return course; | return course; | ||||
} | } | ||||
@@ -70,10 +66,6 @@ public class StudentEntity implements java.io.Serializable { | |||||
return this.sex; | return this.sex; | ||||
} | } | ||||
public void setBirthday(Date birthday) { | |||||
this.birthday = birthday; | |||||
} | |||||
public void setCourse(CourseEntity course) { | public void setCourse(CourseEntity course) { | ||||
this.course = course; | this.course = course; | ||||
} | } | ||||
@@ -104,4 +96,13 @@ public class StudentEntity implements java.io.Serializable { | |||||
public void setSex(int sex) { | public void setSex(int sex) { | ||||
this.sex = sex; | this.sex = sex; | ||||
} | } | ||||
public Date getBirthday() { | |||||
return birthday; | |||||
} | |||||
public void setBirthday(Date birthday) { | |||||
this.birthday = birthday; | |||||
} | |||||
} | } |
@@ -18,7 +18,7 @@ public class TeacherEntity implements java.io.Serializable { | |||||
@Excel(name = "老师ID_teacherEntity,老师属性_courseEntity", orderNum = "2", needMerge = false) | @Excel(name = "老师ID_teacherEntity,老师属性_courseEntity", orderNum = "2", needMerge = false) | ||||
private String id; | private String id; | ||||
/** name */ | /** name */ | ||||
@Excel(name = "语文老师_yuwen,数学老师_shuxue", orderNum = "2", needMerge = true) | |||||
@Excel(name = "语文老师_yuwen,数学老师_shuxue", orderNum = "2", mergeVertical = true) | |||||
private String name; | private String name; | ||||
/* | /* | ||||
@@ -0,0 +1,80 @@ | |||||
package org.jeecgframework.poi.entity.statistics; | |||||
import java.math.BigDecimal; | |||||
import org.jeecgframework.poi.excel.annotation.Excel; | |||||
/** | |||||
* 统计测试类 | |||||
* @author JueYue | |||||
* @date 2014年12月17日 上午11:51:10 | |||||
*/ | |||||
public class StatisticEntity { | |||||
@Excel(name = "名称") | |||||
private String name; | |||||
@Excel(name = "int 测试", width = 15, isStatistics = true) | |||||
private int intTest; | |||||
@Excel(name = "long 测试", width = 15, isStatistics = true) | |||||
private long longTest; | |||||
@Excel(name = "double 测试", width = 15, isStatistics = true) | |||||
private double doubleTest; | |||||
@Excel(name = "string 测试", width = 15, isStatistics = true) | |||||
private String stringTest; | |||||
@Excel(name = "BigDecimal 测试", width = 15, isStatistics = true) | |||||
private BigDecimal bigDecimalTest; | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public int getIntTest() { | |||||
return intTest; | |||||
} | |||||
public void setIntTest(int intTest) { | |||||
this.intTest = intTest; | |||||
} | |||||
public long getLongTest() { | |||||
return longTest; | |||||
} | |||||
public void setLongTest(long longTest) { | |||||
this.longTest = longTest; | |||||
} | |||||
public double getDoubleTest() { | |||||
return doubleTest; | |||||
} | |||||
public void setDoubleTest(double doubleTest) { | |||||
this.doubleTest = doubleTest; | |||||
} | |||||
public String getStringTest() { | |||||
return stringTest; | |||||
} | |||||
public void setStringTest(String stringTest) { | |||||
this.stringTest = stringTest; | |||||
} | |||||
public BigDecimal getBigDecimalTest() { | |||||
return bigDecimalTest; | |||||
} | |||||
public void setBigDecimalTest(BigDecimal bigDecimalTest) { | |||||
this.bigDecimalTest = bigDecimalTest; | |||||
} | |||||
} |
@@ -0,0 +1,45 @@ | |||||
package org.jeecgframework.poi.excel.test; | |||||
import java.io.File; | |||||
import java.io.FileOutputStream; | |||||
import java.math.BigDecimal; | |||||
import java.util.ArrayList; | |||||
import java.util.Date; | |||||
import java.util.List; | |||||
import org.apache.poi.ss.usermodel.Workbook; | |||||
import org.jeecgframework.poi.entity.statistics.StatisticEntity; | |||||
import org.jeecgframework.poi.excel.ExcelExportUtil; | |||||
import org.jeecgframework.poi.excel.entity.ExportParams; | |||||
import org.jeecgframework.poi.excel.entity.vo.PoiBaseConstants; | |||||
import org.junit.Test; | |||||
public class ExcelExportStatisticTest { | |||||
@Test | |||||
public void test() throws Exception { | |||||
List<StatisticEntity> list = new ArrayList<StatisticEntity>(); | |||||
for (int i = 0; i < 250000; i++) { | |||||
StatisticEntity client = new StatisticEntity(); | |||||
client.setName("index" + i); | |||||
client.setIntTest(1 + i); | |||||
client.setLongTest(1 + i); | |||||
client.setDoubleTest(1.2D + i); | |||||
client.setBigDecimalTest(new BigDecimal(1.2 + i)); | |||||
client.setStringTest("12" + i); | |||||
list.add(client); | |||||
} | |||||
Date start = new Date(); | |||||
ExportParams params = new ExportParams("2412312", "测试"); | |||||
params.setType(ExportParams.XSSF); | |||||
Workbook workbook = ExcelExportUtil.exportExcel(params, StatisticEntity.class, list); | |||||
System.out.println(new Date().getTime() - start.getTime()); | |||||
File savefile = new File("d:/"); | |||||
if (!savefile.exists()) { | |||||
savefile.mkdirs(); | |||||
} | |||||
FileOutputStream fos = new FileOutputStream("d:/tt.xlsx"); | |||||
workbook.write(fos); | |||||
fos.close(); | |||||
} | |||||
} |
@@ -33,12 +33,9 @@ public class ExcelExportUtilTest { | |||||
@Test | @Test | ||||
public void oneHundredThousandRowTest() throws Exception { | public void oneHundredThousandRowTest() throws Exception { | ||||
for (int i = 0; i < 250; i++) { | |||||
list.add(courseEntity); | |||||
} | |||||
Date start = new Date(); | Date start = new Date(); | ||||
Workbook workbook = ExcelExportUtil.exportExcel( | |||||
new ExportParams("2412312", "测试", "测试"), CourseEntity.class, list); | |||||
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("2412312", "测试"), | |||||
CourseEntity.class, list); | |||||
System.out.println(new Date().getTime() - start.getTime()); | System.out.println(new Date().getTime() - start.getTime()); | ||||
File savefile = new File("d:/"); | File savefile = new File("d:/"); | ||||
if (!savefile.exists()) { | if (!savefile.exists()) { | ||||
@@ -59,31 +56,31 @@ public class ExcelExportUtilTest { | |||||
@Before | @Before | ||||
public void testBefore() { | public void testBefore() { | ||||
courseEntity = new CourseEntity(); | |||||
courseEntity.setId("1131"); | |||||
courseEntity.setName("小白"); | |||||
TeacherEntity teacherEntity = new TeacherEntity(); | |||||
teacherEntity.setId("12131231"); | |||||
teacherEntity.setName("你们"); | |||||
courseEntity.setTeacher(teacherEntity); | |||||
for (int i = 0; i < 2; i++) { | |||||
courseEntity = new CourseEntity(); | |||||
courseEntity.setId("1131"); | |||||
courseEntity.setName("海贼王必修(" + (i + 1) + ")"); | |||||
teacherEntity = new TeacherEntity(); | |||||
teacherEntity.setId("121312314312421131"); | |||||
teacherEntity.setName("老王"); | |||||
courseEntity.setShuxueteacher(teacherEntity); | |||||
TeacherEntity teacherEntity = new TeacherEntity(); | |||||
teacherEntity.setId("12131231"); | |||||
teacherEntity.setName("路飞"); | |||||
courseEntity.setTeacher(teacherEntity); | |||||
StudentEntity studentEntity = new StudentEntity(); | |||||
studentEntity.setId("11231"); | |||||
studentEntity.setName("撒旦法司法局"); | |||||
studentEntity.setBirthday(new Date()); | |||||
studentEntity.setSex(1); | |||||
List<StudentEntity> studentList = new ArrayList<StudentEntity>(); | |||||
studentList.add(studentEntity); | |||||
studentList.add(studentEntity); | |||||
courseEntity.setStudents(studentList); | |||||
teacherEntity = new TeacherEntity(); | |||||
teacherEntity.setId("121312314312421131"); | |||||
teacherEntity.setName("老王"); | |||||
courseEntity.setShuxueteacher(teacherEntity); | |||||
for (int i = 0; i < 3; i++) { | |||||
StudentEntity studentEntity = new StudentEntity(); | |||||
studentEntity.setId("11231"); | |||||
studentEntity.setName("撒旦法司法局"); | |||||
studentEntity.setBirthday(new Date()); | |||||
studentEntity.setSex(1); | |||||
List<StudentEntity> studentList = new ArrayList<StudentEntity>(); | |||||
studentList.add(studentEntity); | |||||
studentList.add(studentEntity); | |||||
courseEntity.setStudents(studentList); | |||||
list.add(courseEntity); | list.add(courseEntity); | ||||
} | } | ||||
} | } | ||||
@@ -96,8 +93,8 @@ public class ExcelExportUtilTest { | |||||
//@Test | //@Test | ||||
public void testExportExcel() throws Exception { | public void testExportExcel() throws Exception { | ||||
Date start = new Date(); | Date start = new Date(); | ||||
Workbook workbook = ExcelExportUtil.exportExcel( | |||||
new ExportParams("2412312", "测试", "测试"), CourseEntity.class, list); | |||||
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("2412312", "测试", "测试"), | |||||
CourseEntity.class, list); | |||||
System.out.println(new Date().getTime() - start.getTime()); | System.out.println(new Date().getTime() - start.getTime()); | ||||
File savefile = new File("d:/"); | File savefile = new File("d:/"); | ||||
if (!savefile.exists()) { | if (!savefile.exists()) { | ||||