Octopus
是一個簡單的java excel導入導出工具.java
下面是一個excel文件中sheet的數據,有四個學生信息.git
studentId | name | sex | inTime | score |
---|---|---|---|---|
20134123 | John | M | 2013-9-1 | 89 |
20124524 | Joyce | F | 20123-8-31 | 79 |
20156243 | P | 2015-5-15 | 94 | |
20116522 | Nemo | F | 2011-2-26 |
一個學生類,用來保存從excel中讀取的學生信息.github
//lombok annotations @Getter @Setter @NoArgsConstructor @ToString public class Student { @ModelLineNumber private int lineNum; @ModelProperty(value = "id",blankable = false) private String studentId; @ModelProperty(value = "name",defaultValue = "anonymous") private String name; @ModelProperty(value = "sex",wrongMsg = "sex must be M or F",pattern = "^M|F$") private String sex; @ModelProperty(value = "admission",wrongMsg = "admission must be a date") private LocalDate inTime; @ModelProperty(value = "score",wrongMsg = "score must be numeric",defaultValue = "100") private Double score; }
用代碼讀取excel,並輸出學生信息:json
InputStream is = getClass().getResourceAsStream("/test.xlsx"); Workbook workbook = WorkbookFactory.create(is); Sheet sheet = workbook.getSheetAt(0); //read students with ReusableSheetReader SheetReader<ModelEntity<Student>> students = new ReusableSheetReader<>(sheet,1,0,Student.class); //print students information for (ModelEntity<Student> student:students) { System.out.println(student.toString()); }
輸出的學生信息工具
SimpleModelEntity(entity=Student(lineNum=2, studentId=20134123, name=John, sex=M, inTime=2013-09-01, score=89.0, gradeAndClazz=null), exceptions=[]) SimpleModelEntity(entity=Student(lineNum=3, studentId=20124524, name=Joyce, sex=F, inTime=null, score=79.0, gradeAndClazz=null), exceptions=[cn.chenhuanming.octopus.exception.DataFormatException: in cell (3,4) ,20123-8-31 can not be formatted to class java.time.LocalDate]) SimpleModelEntity(entity=Student(lineNum=4, studentId=20156243, name=anonymous, sex=null, inTime=2015-05-15, score=94.0, gradeAndClazz=null), exceptions=[cn.chenhuanming.octopus.exception.PatternNotMatchException: P and ^M|F$ don't match!]) SimpleModelEntity(entity=Student(lineNum=5, studentId=20116522, name=Nemo, sex=F, inTime=2011-02-26, score=100.0, gradeAndClazz=null), exceptions=[])
經過ModelEntity<Student>
,能夠獲取更多異常信息,例如@ModelProperty
的配置信息和所發生的異常.測試
完整的測試用例:src/test/cn/chenhuanming/octopus/core/SheetReaderTest
this
爲了說明導出的特性,咱們給Student
類增長一個屬性GradeAndClazz
用來表示年級和班級.下面是最終的Student
類,能夠用來導入導出.excel
@Getter @Setter @NoArgsConstructor @ToString public class Student { @ModelLineNumber private int lineNum; @ModelProperty(value = "id",blankable = false) private String studentId; @ModelProperty(value = "name",defaultValue = "anonymous") private String name; @ModelProperty(value = "sex",wrongMsg = "sex must be M or F",pattern = "^M|F$") private String sex; //jackson annotation to format output @JsonFormat(pattern = "yyyy-MM-dd") @ModelProperty(value = "admission",wrongMsg = "admission must be a date") private LocalDate inTime; @ModelProperty(value = "score",wrongMsg = "score must be numeric",defaultValue = "100") private Double score; @ModelIgnore private GradeAndClazz gradeAndClazz; public Student(String studentId, String name, String sex, LocalDate inTime, Double score,GradeAndClazz gradeAndClazz) { this.studentId = studentId; this.name = name; this.sex = sex; this.inTime = inTime; this.score = score; this.gradeAndClazz = gradeAndClazz; } }
GradeAndClazz
類,只有年級和班級兩個信息.code
@Getter @Setter @AllArgsConstructor public class GradeAndClazz{ private String grade; private String clazz; }
須要一個xml來配置導出的屬性和屬性描述做爲表頭orm
<?xml version="1.0" encoding="UTF-8"?> <ExportModel class="entity.Student"> <Field name="studentId" description="id"></Field> <Field name="name" description="name"></Field> <Field name="sex" description="sex"></Field> <Field name="inTime" description="admission"></Field> <Field name="score" description="score"></Field> <Field name="gradeAndClazz" description="class info"> <Field name="grade" description="grade"></Field> <Field name="clazz" description="class"></Field> </Field> </ExportModel>
用代碼導出學生信息
//prepare workbook and stuednts objects Workbook workbook = new XSSFWorkbook(); String rootPath = this.getClass().getClassLoader().getResource("").getPath(); FileOutputStream os = new FileOutputStream(rootPath+"/export.xlsx"); GradeAndClazz gradeAndClazz = new GradeAndClazz("2014","R6"); Student student1 = new Student("201223","John","M", LocalDate.now(),98.00,gradeAndClazz); Student student2 = new Student("204354","Tony","M", LocalDate.now(),87.00,gradeAndClazz); Student student3 = new Student("202432","Joyce","F", LocalDate.now(),90.00,gradeAndClazz); //write excel with OneSheetExcelWriter ExcelWriter<Student> studentExcelWriter = new OneSheetExcelWriter<>(getClass().getClassLoader().getResourceAsStream("studentExport.xml")); studentExcelWriter.write(workbook,Arrays.asList(student1,student2,student3)); workbook.write(os);
導出結果
| class info | id name M admission score |---------|----------| | grade | class | ---------------------------------------------------------------| 201223 John M 2017-07-06 98.0 | 2014 | R6 | 204354 Tony M 2017-07-06 87.0 | 2014 | R6 | 202432 Joyce F 2017-07-06 90.0 | 2014 | R6 |
能夠看到,對於gradeAndClazz屬性,會用一個合併單元格來表示.admission由於被@JsonFormat
標記,所以會格式化輸出日期。事實上Octopus
會調用jackson
來格式化json後再寫入excel.
詳細例子在 src/test/cn/chenhuanming/octopus/core/OneSheetExcelWriterTest