| @@ -47,6 +47,7 @@ public @interface Excel { | |||
| * 导入的时间格式,以这个是否为空来判断是否需要格式化日期 | |||
| */ | |||
| public String importFormat() default ""; | |||
| /** | |||
| * 文字后缀,如% 90 变成90% | |||
| */ | |||
| @@ -104,4 +105,11 @@ public @interface Excel { | |||
| * 性别列4【男女占1,但是列标题两个汉字】 限制1-255 | |||
| */ | |||
| 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 | |||
| */ | |||
| public class ExcelBaseParams { | |||
| /** | |||
| * 03版本Excel | |||
| */ | |||
| public static final String HSSF = "HSSF"; | |||
| /** | |||
| * 07版本Excel | |||
| */ | |||
| public static final String XSSF = "XSSF"; | |||
| /** | |||
| * 数据处理接口,以此为主,replace,format都在这后面 | |||
| */ | |||
| @@ -54,6 +54,10 @@ public class ExcelExportEntity extends ExcelBaseEntity { | |||
| * 后缀 | |||
| */ | |||
| private String suffix; | |||
| /** | |||
| * 统计 | |||
| */ | |||
| private boolean isStatistics; | |||
| private List<ExcelExportEntity> list; | |||
| @@ -172,4 +176,12 @@ public class ExcelExportEntity extends ExcelBaseEntity { | |||
| 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.remove(); | |||
| } | |||
| // 创建合计信息 | |||
| addStatisticsRow(styles.get("one"),sheet); | |||
| // 发现还有剩余list 继续循环创建Sheet | |||
| if (dataSet.size() > 0) { | |||
| createSheet(workbook, entity, pojoClass, dataSet, type); | |||
| } | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| logger.error(e.getMessage(), e.fillInStackTrace()); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| @@ -4,6 +4,7 @@ import java.awt.image.BufferedImage; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.text.DecimalFormat; | |||
| import java.util.ArrayList; | |||
| import java.util.Collection; | |||
| import java.util.HashMap; | |||
| @@ -40,9 +41,13 @@ import org.jeecgframework.poi.util.POIPublicUtil; | |||
| */ | |||
| 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, | |||
| int[] delys, int rowNum) { | |||
| @@ -259,6 +264,43 @@ public abstract class ExcelExportBase extends ExportBase { | |||
| if (style != null) { | |||
| 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.setFormat(StringUtils.isNotEmpty(excel.exportFormat()) ? excel.exportFormat() | |||
| : excel.format()); | |||
| excelEntity.setStatistics(excel.isStatistics()); | |||
| String fieldname = field.getName(); | |||
| excelEntity.setMethod(POIPublicUtil.getMethod(fieldname, pojoClass)); | |||
| } | |||
| @@ -22,17 +22,17 @@ public class CourseEntity implements java.io.Serializable { | |||
| /** 主键 */ | |||
| private String id; | |||
| /** 课程名称 */ | |||
| @Excel(name = "课程名称", orderNum = "1", needMerge = true) | |||
| @Excel(name = "课程名称", orderNum = "1", width = 15, needMerge = true) | |||
| private String name; | |||
| /** 老师主键 */ | |||
| @ExcelEntity(id = "yuwen") | |||
| @ExcelVerify() | |||
| private TeacherEntity teacher; | |||
| /** 老师主键 */ | |||
| @ExcelEntity(id = "shuxue") | |||
| //@ExcelEntity(id = "shuxue") | |||
| private TeacherEntity shuxueteacher; | |||
| @ExcelCollection(name = "选课学生", orderNum = "4") | |||
| //@ExcelCollection(name = "选课学生", orderNum = "4") | |||
| 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; | |||
| @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 CourseEntity course; | |||
| public Date getBirthday() { | |||
| return birthday; | |||
| } | |||
| public CourseEntity getCourse() { | |||
| return course; | |||
| } | |||
| @@ -70,10 +66,6 @@ public class StudentEntity implements java.io.Serializable { | |||
| return this.sex; | |||
| } | |||
| public void setBirthday(Date birthday) { | |||
| this.birthday = birthday; | |||
| } | |||
| public void setCourse(CourseEntity course) { | |||
| this.course = course; | |||
| } | |||
| @@ -104,4 +96,13 @@ public class StudentEntity implements java.io.Serializable { | |||
| public void setSex(int 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) | |||
| private String id; | |||
| /** name */ | |||
| @Excel(name = "语文老师_yuwen,数学老师_shuxue", orderNum = "2", needMerge = true) | |||
| @Excel(name = "语文老师_yuwen,数学老师_shuxue", orderNum = "2", mergeVertical = true) | |||
| 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 | |||
| public void oneHundredThousandRowTest() throws Exception { | |||
| for (int i = 0; i < 250; i++) { | |||
| list.add(courseEntity); | |||
| } | |||
| 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()); | |||
| File savefile = new File("d:/"); | |||
| if (!savefile.exists()) { | |||
| @@ -59,31 +56,31 @@ public class ExcelExportUtilTest { | |||
| @Before | |||
| 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); | |||
| } | |||
| } | |||
| @@ -96,8 +93,8 @@ public class ExcelExportUtilTest { | |||
| //@Test | |||
| public void testExportExcel() throws Exception { | |||
| 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()); | |||
| File savefile = new File("d:/"); | |||
| if (!savefile.exists()) { | |||