## Bingexcel User Guide
### 使用maven进行项目开发
1. **引用jar包**
目前项目的maven仓库是在github上,浏览地址为 [https://github.com/bingyulei007/mvn-repo/tree/master/repository/com/bing/excel](https://github.com/bingyulei007/mvn-repo/tree/master/repository/com/bing/excel),在使用时候,你只要加上一下远程仓库:
```
<repositories>
<repository>
<id>bingyulei-mvn-repo</id>
<url>https://raw.github.com/bingyulei007/mvn-repo/master/repository</url>
</repository>
</repositories>
```
然后加入jar包的引用,就可以轻松读写excel了。
```
<dependency>
<groupId>com.bing</groupId>
<artifactId>excel</artifactId>
<version>1.2-SNAPSHOT</version>
</dependency>
```
2. **简单读取实例**
可以[从这里下载person](https://git.oschina.net/bingyulei007/resource/tree/master/excel)表格,数据如图:
![person表数据](https://git.oschina.net/bingyulei007/resource/raw/master/pic/person.jpg "在这里输入图片标题"),
然后你需要创建一个java的实体对象与表格内容对应:
```java
public class Person {
@CellConfig(index = 1)
private int age;
//@CellConfig(index = 0,readRequired=true)
@CellConfig(index = 0)
private String name;
@CellConfig(index = 3)
private Double salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public Double getSalary() {
return salary;
}
public String toString() {
return MoreObjects.toStringHelper(this.getClass()).omitNullValues()
.add("name", name).add("age", age).add("salary", salary)
.toString();
}
}
```
其中的 __@CellConfig__是关键配置,用于对应映射关系。这里面下标从0开始。
然后,你就可以开始你的读写了。这里是介绍数据量不大的普通模式:
```java
File f = new File("person.xls");
BingExcel bing = BingExcelBuilder.toBuilder().builder();
try {
SheetVo<Person> vo = bing.readFile(f, Person.class, 1);
//1代表从第一行读取,这个方法默认的是第一个工作表
System.out.println(vo.getSheetIndex());//打印对应的sheet的顺序
System.out.println(vo.getSheetName());//对应sheet工作表的名称
System.out.println(vo.getObjectList());//数据对象
} catch (Exception e) {
e.printStackTrace();
}
```
就这样,你就完成了excel到java实体的转换
3. **java类说明**
对应的java实体类,其属性必须要有__@CellConfig__注解,此注解必须的值为index属性,起始值是0;如果你要限定实体类的某一个属性必须有值的话,可以这样定义:
```java
@CellConfig(index = 0,readRequired=true)
private String a;
```
一旦你加上了 *readRequired* 这个属性,当你的excel对应属性不存在时候,就会抛出异常 *illegalValueException* ;如果你想在属性不存在时候做一些其他业务逻辑,那你不应该加上 *readRequired* 这个属性,而是自己去定义一个这个属性的转换器(在后面会讲到转化器的定义)。
当然你也会有需求,比如我确实需要定义一个属性,他在excel中确实不存在。那么你可以把这个属性定义为 *transient* 的:
```java
//与excel不对应的属性。
private transient String test;
```
另外关键的操作类是 **BingExcel** ,这个类必须由 *BingExcelBuilder* 来构建(补充一点:因为不可能在转换中将一个百万级的数据直接转换到内存中list对象,这里也提供了 **BingExcelEvent** 来进行大数据的读取)
4. **自定义转化器**
前面讲到的 *Person* 对象,属性的转换是靠默认的转化器( **FieldValueConverter** )来进行的,默认的转换器包括数组,列表(List),枚举等。如下面例子:
![员工表](https://git.oschina.net/bingyulei007/resource/raw/master/pic/salary.jpg)
员工表-salary.xlsx(可以从 [这里下载](https://git.oschina.net/bingyulei007/resource/tree/master/excel)),
里面有个字段-部门,在java中是个枚举对象;另外里面还有一些日期字段(入职时间等),但是是用字符串形式存储的日期,这样自定义的转换器就不能去处理了。
```java
public class Salary {
@CellConfig(index = 1)
private String employNum;
@CellConfig(index = 0)
private String id;
//默认的boolean类型只支持"TRUE", "FALSE"字符的转换,但是它自带了传参数的构造方法,具体可以参考源码,
@CellConfig(index = 8)
@BingConvertor(value = BooleanFieldConverter.class, strings = { "1","0" }, booleans = { false })
private boolean allDay;
@CellConfig(index=7)
private Department department;//枚举类型
@CellConfig(index = 13)
@BingConvertor(DateTestConverter.class)
// 自定义转换器
private Date atypiaDate;
@CellConfig(index = 14)
private Date entryTime;//用默认的转换器
// 与excel无对应关系的属性定义
private transient String test;
public String toString() {
return MoreObjects.toStringHelper(this.getClass()).omitNullValues()
.add("id", id).add("employNum", employNum)
.add("allDay", allDay)
.add("atypiaDate", atypiaDate)
.add("department", department)
.add("entryTime", entryTime).toString();
}
//省略了 getter与setter方法。
}
```
部门枚举的定义:当然你可以把他定义到 *Salary* 中,作为一个内部类
```java
enum Department {
develop, personnel, product;
}
```
定义自己的日期转换器,可以通过实现 FieldValueConverter 或者继承 AbstractFieldConvertor
```java
public class DateTestConverter extends AbstractFieldConvertor {
@Override
public boolean canConvert(Class<?> clz) {
return clz.equals(Date.class);
}
@Override
public Object fromString(String cell, ConverterHandler converterHandler,Type type) {
if (StringUtils.isBlank(cell)) {
return null;
}
try {
SimpleDateFormat format=new SimpleDateFormat("yyyy.MM.dd");
Date date = format.parse(cell);
return date;
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
```
然后,你就可以进行读入了:
```java
URL url = Salary.class.getResource("/salary.xlsx");
File f = new File(url.toURI());
BingExcel bing = BingExcelBuilder.toBuilder().builder();
try {
SheetVo<Salary> vo = bing.readFile(f, Salary.class, 1);
System.out.println(vo.getSheetIndex());
System.out.println(vo.getSheetName());
List<Salary> objectList = vo.getObjectList();
for (Salary salary : objectList) {
System.out.println(salary);
}
} catch (Exception e) {
e.printStackTrace();
}
```
对于 *BingExcel* 类,它有多个方法:具体可以查相关api或者代码。
```java
<T> SheetVo<T> readFile(File file, ReaderCondition<T> condition) throws Exception ;
/**
* 读取所condition 对应 sheet表格,到list
* @param file
* @param conditions 每个表格对应的condition,注:对于返回的条数,取conditions中 endNum的最小值
* @return sheetVo的list对象,如果没有符合conditions的结果,返回empetyList对象
* @throws Exception
*/
List<SheetVo> readFileToList(File file,ReaderCondition[] conditions) throws Exception ;
```
其中 *ReaderCondition* 提供了更为精细的读取控制
更多内容可以关注:项目地址https://git.oschina.net/bingyulei007/bingExcel,也可以去项目页留言。提出宝贵的改进意见