# informat.word word操作相关

## 概述
使用`informat.word`对象可以使用一个Docx格式的Word文档和数据生成一个新的word文件，这在例如生成合同、报告、证书等场景下是非常有用的。

> 文件路径必须是在本地的沙盒路径中，关于文件路径可参考 [informat.file](/guide/script/file.md)

所有的标签都是以`{{`开头，以`}}`结尾，标签可以出现在任何位置，包括页眉，页脚，表格内部，文本框等，表格布局可以设计出很多优秀专业的文档，推荐使用表格布局。模板遵循“所见即所得”的设计，模板和标签的样式会被完全保留。

标签由前后两个大括号组成，`{{title}}`是标签，`{{?title}}`也是标签，title是这个标签的名称，问号标识了标签类型。
## 文本标签
文本标签的格式为`{{text}}` 渲染后的内容为 `text`变量的内容
## 图片标签
图片标签的格式为`{{@pic}}` 渲染后的内容为 `pic`中描述的图片，`pic`对象需要使用informat.word.createPicture()方法生成
示例数据
```javascript
{
    pic:informat.word.createPicture({
        path:'logo.png'
    })
}
```
模板
```
{{@pic}}
```

## 列表标签
列表标签的格式为`{{*var}}` 渲染后的内容为 列表
## 区块对
区块对由前后两个标签组成，开始标签以?标识，结束标签以/标识：`{{?sections}}{{/sections}}`
区块对开始和结束标签中间可以包含多个图片、表格、段落、列表、图表等，开始和结束标签可以跨多个段落，也可以在同一个段落，但是如果在表格中使用区块对，开始和结束标签必须在同一个单元格内，因为跨多个单元格的渲染行为是未知的。
区块对在处理一系列文档元素的时候非常有用，位于区块对中的文档元素可以被渲染零次，一次或N次，这取决于区块对的取值。
- False或空集合 隐藏区块中的所有文档元素
- 非False且不是集合 显示区块中的文档元素，渲染一次
- 非空集合 根据集合的大小，循环渲染区块中的文档元素

***如果区块对的值是 null 、false 或者空的集合，位于区块中的所有文档元素将不会显示，这就等同于if语句的条件为 false。***
传入的数据
```json
{
    "value": false
}
```

模板
```text
测试{{?value}}不会出现{{/value}}
```

渲染后的结果
```javascript
测试
```

***如果区块对的值不为 null 、 false ，且不是集合，位于区块中的所有文档元素会被渲染一次，这就等同于if语句的条件为 true。***
传入的数据
```json
{
  "person": { "name": "张三" }
}
```

模板
```text
{{?person}}
Hi {{name}}!
{{/person}}
```

渲染后的结果
```text
Hi 张三!
```

***如果区块对的值是一个非空集合，区块中的文档元素会被迭代渲染一次或者N次，这取决于集合的大小，类似于foreach语法。***
传入的数据
```json
{
  "users": [
    { "name": "张三" },
    { "name": "李四" },
    { "name": "王五" }
  ]
}
```

模板
```text
{{?users}}
{{name}}
{{/users}}
```

渲染后的结果
```javascript
张三
李四
王五
```

## 区块对循环中的内置变量

|变量|类型|说明|
|--|--|--|
|_index|Integer|返回当前迭代从0开始的索引|
|_is_first|Boolean|辨别循环项是否是当前迭代的第一项|
|_is_last|Boolean|辨别循环项是否是当前迭代的最后一项|
|_has_next|Boolean|辨别循环项是否是有下一项|
|_is_even_item|Boolean|辨别循环项是否是当前迭代间隔1的奇数项|
|_is_odd_item|Boolean|辨别循环项是否是当前迭代间隔1的偶数项|
|#this|Object|引用当前对象，由于#和已有表格标签标识冲突，所以在文本标签中需要使用=号标识来输出文本|

示例数据
```json
{
  "users": [
    "张三",
    "李四"
  ]
}
```
模板
```
{{?users}}
{{_index + 1}}. {{=#this}}
{{/users}}
```
结果
```
1. 张三
2. 李四
```

## 表格行循环
在声明变量时在变量前增加一个`-`符号，将开启表格行循环功能。将{{list}} 置于循环行的同一行，循环行设置要循环的标签和内容，
注意此时的标签应该使用 []，以此来实现在表格中对于行的循环,以下是一个例子

示例数据
```json
{
  "-users": [
    {"id":1,"name":"张三","age":18},
    {"id":2,"name":"李四","age":20},
    {"id":3,"name":"王五","age":30}
  ]
}
```
模板

|序号|姓名|年龄|
|--|--|--|
|`{{users}}`[_index+1]|[name]|[age]|

结果

|序号|姓名|年龄|
|--|--|--|
|1|张三|18|
|2|李四|20|
|3|王五|30|


## 表格列循环
在声明变量时在变量前增加一个`|`符号，将开启表格列循环功能。将{{list}} 置于循环列中，其它和循环行类似,以下是一个例子

示例数据
```json
{
  "|users": [
    {"id":1,"name":"张三","age":18},
    {"id":2,"name":"李四","age":20},
    {"id":3,"name":"王五","age":30}
  ]
}
```

|用户|
|--|
|`{{users}}`[_index+1]|
|[name]|
|[age]|

结果

|用户|用户|用户|
|--|--|--|
|1|2|3|
|张三|李四|王五|
|18|20|30|


## createWithTemplate
通过模板和数据生成一个Word文件
```javascript
informat.word.createWithTemplate(template,file,data)
```

| 参数  | 类型  | 描述      |
| ----  | ----  |---------|
| template  | String | 模板文件在本地沙盒中的路径 |
| file  | String | 生成的文件在本地沙盒中的路径 |
| data  | Object | 传递给模板的数据 |

## createPicture
生成Word中插入的图片数据
```javascript
informat.word.createPicture(pic)
```

| 参数  | 类型  | 描述      |
| ----  | ----  |---------|
| pic  | WordPicture | 图片配置 |

***返回值 返回插入图片的模板数据***

WordPicture的结构如下
```text
{
    url:String,//图片的URL地址
    path:String,//图片在本地沙盒中的路径
    storagePath:String,//图片在共享存储中的路径
    width:Integer,//图片的宽度 不设置的话为图片的原始尺寸
    height:Integer,//图片的高度 不设置的话为图片的原始尺寸
}
```
> 设置图片大小时必须同时设置`width`和`height`

**示例**

以下是一个通过word模板和数据生成word文件的例子

```javascript
const data = {
    text: '文本数据',
    list: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '王五' }
    ],
    pic: informat.word.createPicture({
        path: 'logo.png'
    })
}
informat.word.createWithTemplate('template.docx', 'out.docx', data);
```

## 替换word中的图片
引用图片标签是一个文本：`{{var}}`，标签位置在：设置图片格式—可选文字—标题或者说明（新版本Microsoft Office标签位置在：编辑替换文字-替换文字）。

![操作](images/word-1.png)
引用图片标签只会替换图片而不会改变图片尺寸和布局，数据模型和图片标签一致

::: tip 注意
替换文字的图片标签不需要`@`
:::