| @@ -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()) { | ||||