# LDP框架Excel导入导出使用

使用Excel导入/导出功能，第一步需要添加maven依赖：

```xml
<dependency>
    <groupId>com.sinra.ldp</groupId>
    <artifactId>common-excel</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
```

之后根据需求选择合适的方式完成功能，通过注解方式，可以快速完成标准化导入、导出，也可以自己构建ExcelOptions或者调用全参数接口来实现导入导出。具体案例可以参照ldp-app-example工程example-biz模块中的ExampleExcel相关业务代码。

## 一、使用注解

**1、注解包添加依赖**

使用注解需要额外依赖common-biz-annotation包

```xml
<dependency>
    <groupId>com.sinra.ldp</groupId>
    <artifactId>common-biz-annotation</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
```

**2、实现导入**

Service层实现，在导入方法加上注解 **@ExcelImport** ，并给targetClass赋值。

```java

    @Override
    @ExcelImport(targetClass = ExampleUserInfo.class)
    public void importExcelByAnnotation(MultipartFile file, ExcelOptions excelOptions) {
        excelService.importExcel(excelOptions);
    }
```

Rest层调用方式

```java
exampleExcelService.importExcelByAnnotation(file, null);
```

这样就完成了一个导入功能。 另外可以通过注解的属性修改一些配置：

| 属性          | 类型     | 说明                                                |
| ------------- | -------- | --------------------------------------------------- |
| upload        | boolean  | 是否上传文件到资料库                                |
| useLocalDao   | boolean  | 是否使用本地Dao                                     |
| requireFields | String[] | 必填列数组(数据库字段名/实体类属性名/数据库COMMENT) |
| excludeFields | String[] | 排除列数组(数据库字段名/实体类属性名/数据库COMMENT) |

**3、实现导出**

Service层实现，只需要在导出方法加上注解 **@ExcelExport**，并给sourceClass赋值。

```java

    @Override
    @ExcelExport(sourceClass = ExampleUserInfo.class)
    public void exportExcelByAnnotation(OutputStream outputStream, ExcelOptions excelOptions) {
        excelService.exportExcel(excelOptions);
    }
```

Rest层调用方式

```java
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=export" + fileName + ".xlsx");
exampleExcelService.exportExcelByAnnotation(response.getOutputStream(), null);
```

这样就完成了一个导出功能。 另外可以通过注解的属性修改一些配置：

| 属性          | 类型     | 说明                                                |
| ------------- | -------- | --------------------------------------------------- |
| useLocalDao   | boolean  | 是否是用本地Dao                                     |
| excludeFields | String[] | 排除列数组(数据库字段名/实体类属性名/数据库COMMENT) |

## 二、构建ExcelOptions

如果不想通过注解，可以自己构建ExcelOptions来实现导入导出功能，不需要额外导包。

**1、实现导入**

导入时构建ExcelOptions，必要参数是clazz（实体类类型）、fileInputStream（输入流）、tableColumnMeta（表元数据）、readFinishListener（读取数据后的回调）

```java
/**
 * 构建ExcelOptions 导入Excel
 *
 * @param file
 */
@Override
public void importExcelByOptions(MultipartFile file) {
        List<TableColumnMeta> tableColumnMeta = jdbcDaoService.getTableColumnMeta(ExampleUserInfo.class);
        String[] requiredList = new String[]{"userAccount", "密码"};
        String[] excludeList = new String[]{"id"};
        try {
            ExcelOptions excelOptions = ExcelOptions.builder()
                    // 实体类类型
                    .clazz(ExampleUserInfo.class)
                    // 文件流
                    .fileInputStream(file.getInputStream())
                    // 数据库表元数据
                    .tableColumnMeta(tableColumnMeta)
                    // 必填字段数组
                    .requiredFields(requiredList)
                    // 排除字段数组
                    .excludeFields(excludeList)
                    // 读取数据完毕后的操作
                    .readFinishListener(list -> {
                        //遍历所有数据并执行自动填充
                        for (Object o : list) {
                            try {
                                AutoComputedUtil.autoComputedField(o);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        // 将数据插入到数据库中
                        genericDaoService.insertList(list);
                    })
                    .build();
            excelService.importExcel(excelOptions);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
```

**2、实现导出**

导出时构建ExcelOptions，必要参数是clazz（实体类类型）、fileOutputStream（输出流）、tableColumnMeta（表元数据）、exportData（导出数据）

```java
/**
 * 构建ExcelOptions 导出Excel
 *
 * @param outputStream
 */
@Override
public void exportExcelByOptions(OutputStream outputStream) {
    // 获取数据
    List<ExampleUserInfo> userInfoList = genericDaoService.findALL(ExampleUserInfo.class);
    // 获取实体类对应的元数据	
    List<TableColumnMeta> tableColumnMeta = jdbcDaoService.getTableColumnMeta(ExampleUserInfo.class);
    // 排除列数组
    String[] excludeList = new String[]{};
    ExcelOptions excelOptions = ExcelOptions.builder()
        // 设置实体类
         .clazz(ExampleUserInfo.class)
        // 设置文件输出流
        .fileOutputStream(outputStream)
        // 数据库表元素据
        .tableColumnMeta(tableColumnMeta)
        // 导出数据
        .exportData(userInfoList)
        // 排除字段
        .excludeFields(excludeList)
        .build();
    excelService.exportExcel(excelOptions);
}
```

## 三、直接调用全参数接口

**1、实现导入**

ExcelService中的导入接口定义如下：

```java
void importExcel(InputStream fileInputStream, Class clazz, List<TableColumnMeta> tableColumnMeta, String[] excludeFields, ExcelReadFinishListener listener, String[] requiredFields);
```

必要参数是clazz（实体类类型）、fileInputStream（输入流）、tableColumnMeta（表元数据）、readFinishListener（读取数据后的回调），调用方式：

```java
/**
 * 调用全参数接口导入Excel
 *
 * @param file
 */
@Override
public void importExcelByParam(MultipartFile file) {
    try {
        List<TableColumnMeta> tableColumnMeta = jdbcDaoService.getTableColumnMeta(ExampleUserInfo.class);
        String[] requiredList = new String[]{"userAccount", "密码"};
        String[] excludeList = new String[]{"id"};
        excelService.importExcel(file.getInputStream(), ExampleUserInfo.class, tableColumnMeta,
                                 requiredList, list -> {
                                     for (Object o : list) {
                                         try {
                                             AutoComputedUtil.autoComputedField(o);
                                         } catch (Exception e) {
                                             e.printStackTrace();
                                         }
                                     }
                                     genericDaoService.insertList(list);
                                 }, excludeList);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
```

**2、实现导出**

ExcelService中的导入接口定义如下：

```java
void exportExcel(OutputStream outputStream, Class clazz, String[] headList, List data, List<TableColumnMeta> tableColumnMeta, String[] excludeFields);
```

必要参数是clazz（实体类类型）、fileOutputStream（输出流）、tableColumnMeta（表元数据）、exportData（导出数据），调用方式：

```java
/**
 * 直接调用全参数接口导出Excel
 *
 * @param outputStream
 */
@Override
public void exportExcelByPram(OutputStream outputStream) {
    Map<String, Object> param = new HashMap<>();
    param.put("userType", 1);
    List<ExampleUserInfo> userInfoList = genericDaoService.findByHql(ExampleUserInfo.class, param);
    List<TableColumnMeta> tableColumnMeta = jdbcDaoService.getTableColumnMeta(ExampleUserInfo.class);
    excelService.exportExcel(outputStream, ExampleUserInfo.class, userInfoList, tableColumnMeta, null);
}
```



