# 导出相关函数

> 导出是本插件的核心功能，用于将接口中的数据/界面上的数据以生成excel文件的方式给用户下载，在设计函数的时候尽量接近实际场景，开发了诸如 filterExportData 辅助梳理数据，setCellStyle 辅助添加样式，setRoundBorder 用于调整边框等。

#### exportExcel参数配置

> 核心方法，用于将 data 数据依次导出，如果需要调整导出后的文件字段顺序或者过滤多余数据，请查看 filterExportData 方法

| 参数名称 | 描述                                             | 默认值 |
| -------- | ------------------------------------------------ | ------ |
| data     | 数据列表（需要指定表名）                         | 必填   |
| filename | 文件名称（带后缀）                               | 必填   |
| type     | 导出类型，支持 xlsx、csv、ods、xlsb、fods、biff2 | xlsx   |
| opt      | 其他可选配置                                     | null   |

##### data样例：

```javascript
{
    "sheet1": [
        {name: '111', sex: 'male'},
        {name: '222', sex: 'female'},
    ]
}
```

##### opt支持的配置项

| 参数名称        | 描述                                                         | 默认值 |
| --------------- | ------------------------------------------------------------ | ------ |
| opt.Props       | 配置文档基础属性，支持Title、Subject、Author、Manager、Company、Category、Keywords、Comments、LastAuthor、CreatedData | null   |
| opt.extend      | 表格配置参数，支持 `!merge` (合并单元格信息)、`!cols`(行数)、`!protect`(写保护)等，[原生配置请参考](https://github.com/SheetJS/js-xlsx#worksheet-object)，其中 `!merge` 配置支持辅助方法生成，详见 `makeMergeConfig(origin)`！ | null   |
| opt.compression | 是否压缩，压缩效果比较明显，建议开启（9列9w行有较多重复的数据，从 30M 缩小到 3M） | true   |

> 如果想指定某个 sheet 的opt.extend，请按照 'sheet名称' => {单独配置}，如：

```javascript
excel.exportExcel({
    sheet1: data,
    sheet2: data
}, '测试导出复杂表头.xlsx', 'xlsx', {
    extend: {
        // extend 中可以指定某个 sheet 的属性，如果不指定 sheet 则所有 sheet 套用同一套属性
        sheet1: {
            // 以下配置仅 sheet1 有效
            '!merges': mergeConf
            ,'!cols': colConf
            ,'!rows': rowConf
        }
    }
});
```

#### downloadExl参数配置

> 兼容旧用法，用于快速导出数据，无需指定 sheet_name，无需指定后缀名，其余跟 `exportExcel` 用法相同。

| 参数名称 | 描述                             | 默认值 |
| -------- | -------------------------------- | ------ |
| data     | 导出的数据                       |        |
| filename | 不带后缀名的文件名               |        |
| type     | 导出类型（自动拼接在filename后） |        |

#### filterExportData参数配置

> 辅助方法，梳理导出的数据，包括字段排序和多余数据过滤

| 参数名称 | 描述                                             | 默认值 |
| -------- | ------------------------------------------------ | ------ |
| data     | 需要梳理的数据                                   | 必填   |
| fields   | 支持数组、对象和回调函数，用于映射关系和字段排序 | 必填   |

> fields参数设计

在实际使用的过程中，后端给的参数多了，或者字段数据不符合导出要求，这都是很常见的情况。为了导出数据的顺序正确和数据映射正确，于是新增了这个方法。

fields 用于表示对象中的属性顺序和映射关系，支持『数组』和『对象』两种方式

假如后台给出了这样的数据：

```json
{
    "code":0,
    "msg":"",
    "count":3,
    "data":[
        {
            "id":10000,
            "username":"user-0",
            "sex":"女",
            "city":"城市-0",
            "sign":"签名-0",
            "experience":255,
            "logins":24,
            "wealth":82830700,
            "classify":"作家",
            "score":57,
            "start": "2018-12-29",
            "end": "2018-12-30"
        }
    ]
}
```

**数组方式：**

仅用于排序、字段过滤，比如我希望的导出顺序和字段是：

`id`、`sex`、`username`、`city`

那么，我可以这样写：

```javascript
var data = [];// 假设的后台的数据
data = excel.filterExportData(data, ['id', 'sex', 'username', 'city']);
excel.exportExcel(data, '导出测试.xlsx', 'xlsx');
```

**对象方式：**

> 巧记：对象左侧是新名称，右侧是老名称或者回调函数（左新右旧）

可以用于排序、重命名字段、字段过滤，比如我希望 `username` 字段重命名为 `name`，保留 `sex` 和 `city` 字段

那么，我可以这样写：

```javascript
var data = [];// 假设的后台的数据
data = excel.filterExportData(data, {
    name: 'username',
    sex:'sex',
    city: 'city'
});
excel.exportExcel(data, '导出测试.xlsx', 'xlsx');
```

##### 回调方式：

> 口诀：左新右旧

可以用于排序、重命名字段、字段过滤、自定义列、批量渲染样式，比如我希望 `range` 由 `start` `end` 聚合并以 `~` 分割；修改 `score` 为原有值的 10倍，并且 `username` 字段重命名为 `name`，保留 `sex` 和 `city`  字段，`city` 所有单元格变为**加粗+居中+红底白字**（可用样式请参见『样式设置专区』）。

那么，我可以这样写：

```javascript
var data = [];// 假设的后台的数据
data = excel.filterExportData(data, {
    name: 'username',
    sex:'sex',
    city: function(value, line, data) {
        return {
            v: value,// v 代表单元格的值
            s:{// s 代表样式
                alignment: {
                    horizontal: 'center',
                    vertical: 'center',
                },
                font: { sz: 14, bold: true, color: { rgb: "FFFFFF" } },
                fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FF0000" }}
            },
        };
    },
    range: function(value, line, data) {
        return line['start'] + '~' + line['end'];
    },
    score: function(value, line, data) {
        return value * 10;
    }
});
excel.exportExcel(data, '导出测试.xlsx', 'xlsx');
```

##### 单元格属性含义

| Key  | Description                                                  |
| ---- | ------------------------------------------------------------ |
| `v`  | 单元格的值                                                   |
| `w`  | 格式化文本（如果适用）                                       |
| `t`  | 单元格类型: `b` 布尔值, `n` 数字, `e` 错误, `s` 字符, `d` 日期 |
| `f`  | 单元格公式（如果适用）                                       |
| `r`  | 富文本编码（如果适用）                                       |
| `h`  | 富文本的HTML呈现（如果适用）                                 |
| `c`  | 与单元格相关的注释                                           |
| `z`  | 与单元格关联的数字格式字符串（如果需要）                     |
| `l`  | 单元格超链接对象（目标链接，.tooltip是提示）                 |
| `s`  | 单元格的样式/主题（如果适用）                                |

##### 公式设置样例：

> 注意：网页导出的xlsx，在 Microsoft Excel 呈保护模式打开，导致公式的值不显示，此时将受保护模式关掉即可！

对于复杂的公式，楼主也不甚了解，以普通公式 `=SUM(A1, A10)`  为例，在插件中只需要将单元格的属性设置为：`{t: 'n', f: 'SUM(A1:A10)'}`，比如我想加一个总览行就可以这样追加数据：

```javascript
// 4. 公式的用法
data.push({
    id: '',
    username: '总年龄',
    age: {t: 'n', f: 'SUM(C4:C10)'},
    sex: '总分',
    score: {t: 'n', f: 'SUM(E4:E10)'},
    classify: ''
});
```

官方公式相关文档：[https://github.com/SheetJS/js-xlsx#formulae](https://github.com/SheetJS/js-xlsx#formulae)

#### tableToJson参数配置

> 辅助方法：将原生DOM的表格转换为JSON形式的数据

##### 传入参数

| 参数名称 | 描述                            | 默认值 |
| -------- | ------------------------------- | ------ |
| dom      | 原生表格的DOM对象或者jQuery对象 | null   |

##### 返回参数

| 参数名称 | 类型  | 描述               |
| -------- | ----- | ------------------ |
| head     | array | 表格头部的数组数据 |
| body     | array | 表格body的数组数据 |

##### 使用样例

> head是头部数据，body是尾部数据，使用 arr1.push.apply(arr, arr2) 可以合并数组

```javascript
// 获取头部和body
var data = LAY_EXCEL.tableToJson(document.getElementById('LAY-EXPORT-TEST')) // 或者 $('#LAY-EXPORT-TEST')
// console.log(data)
var exportData = []
exportData.push.apply(exportData, data.head)
exportData.push.apply(exportData, data.body)
// console.log(exportData)

LAY_EXCEL.exportExcel(exportData, '表格导出.xlsx', 'xlsx')
```