List
This guide demonstrates different features of excel list type.
Horizontal list
There are three kinds of horizontal list:
- Horizontal scalar/enum list, as element type is scalar. E.g:
[]int32
. - Horizontal incell struct list, as element type is incell struct. E.g:
[]{int32 ID, string Name}Item
. - Horizontal struct list, as element type is struct. E.g:
[Item]int32
.
Horizontal scalar list
A worksheet ItemConf
in HelloWorld.xlsx:
Param1 | Param2 | Param3 |
---|---|---|
[]int32 | int32 | int32 |
Param1’s value | Param2’s value | Param3’s value |
1 | 2 | 3 |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated int32 param_list = 1 [(tableau.field) = {name:"Param" layout:LAYOUT_HORIZONTAL}];
}
ItemConf.json
{
"paramList": [
1,
2,
3
]
}
Horizontal enum list
FruitType
in common.proto is predefined as:
enum FruitType {
FRUIT_TYPE_UNKNOWN = 0 [(tableau.evalue).name = "Unknown"];
FRUIT_TYPE_APPLE = 1 [(tableau.evalue).name = "Apple"];
FRUIT_TYPE_ORANGE = 3 [(tableau.evalue).name = "Orange"];
FRUIT_TYPE_BANANA = 4 [(tableau.evalue).name = "Banana"];
}
A worksheet ItemConf
in HelloWorld.xlsx:
Param1 | Param2 | Param3 |
---|---|---|
[]enum<.FruitType> | enum<.FruitType> | enum<.FruitType> |
Param1’s value | Param2’s value | Param3’s value |
1 | FRUIT_TYPE_ORANGE | Banana |
Generated:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated protoconf.FruitType param_list = 1 [(tableau.field) = {name:"Param" layout:LAYOUT_HORIZONTAL}];
}
ItemConf.json
{
"paramList": [
"FRUIT_TYPE_APPLE",
"FRUIT_TYPE_ORANGE",
"FRUIT_TYPE_BANANA"
]
}
Horizontal struct list
A worksheet ItemConf
in HelloWorld.xlsx:
Item1ID | Item1Name | Item2ID | Item2Name | Item3ID | Item3Name |
---|---|---|---|---|---|
[Item]uint32 | string | uint32 | string | uint32 | string |
Item1’s ID | Item1’s name | Item2’s ID | Item2’s name | Item3’s ID | Item3’s name |
1 | Apple | 2 | Orange | 3 | Banana |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL}];
message Item {
uint32 id = 1 [(tableau.field) = {name:"ID"}];
string name = 2 [(tableau.field) = {name:"Name"}];
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"name": "Apple"
},
{
"id": 2,
"name": "Orange"
},
{
"id": 3,
"name": "Banana"
}
]
}
Horizontal predefined-struct list
Item
in common.proto is predefined as:
message Item {
int32 id = 1 [(tableau.field) = {name:"ID"}];
int32 num = 2 [(tableau.field) = {name:"Num"}];
}
A worksheet ItemConf
in HelloWorld.xlsx:
Item1ID | Item1Num | Item2ID | Item2Num | Item3ID | Item3Num |
---|---|---|---|---|---|
[.Item]int32 | int32 | int32 | int32 | int32 | int32 |
Item1’s ID | Item1’s num | Item2’s ID | Item3’s num | Item3’s ID | Item3’s num |
1 | 100 | 2 | 200 | 3 | 300 |
Generated:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated protoconf.Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL}];
}
ItemConf.json
{
"ItemList": [
{
"id": 1,
"num": 100
},
{
"id": 2,
"num": 200
},
{
"id": 3,
"num": 300
}
]
}
Horizontal incell-struct list
A worksheet ItemConf
in HelloWorld.xlsx:
Item1 | Item2 | Item3 |
---|---|---|
[]{int32 ID, string Name}Item | Item | Item |
Item1’s info | Item2’s info | Item3’s info |
1,Apple | 2,Orange | 3,Banana |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL span:SPAN_INNER_CELL}];
message Item {
int32 id = 1 [(tableau.field) = {name:"ID"}];
string name = 2 [(tableau.field) = {name:"Name"}];
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"name": "Apple"
},
{
"id": 2,
"name": "Orange"
},
{
"id": 3,
"name": "Banana"
}
]
}
Horizontal incell-predefined-struct list
Item
in common.proto is predefined as:
message Item {
int32 id = 1 [(tableau.field) = {name:"ID"}];
int32 num = 2 [(tableau.field) = {name:"Num"}];
}
A worksheet ItemConf
in HelloWorld.xlsx:
Reward1 | Reward2 | Reward3 |
---|---|---|
[]{.Item} | .Item | .Item |
Item1’s info | Item2’s info | Item3’s info |
1,100 | 2,200 | 3,300 |
Generated:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated protoconf.Item reward_list = 1 [(tableau.field) = {name:"Reward" layout:LAYOUT_HORIZONTAL span:SPAN_INNER_CELL}];
}
ItemConf.json
{
"rewardList": [
{
"id": 1,
"num": 100
},
{
"id": 2,
"num": 200
},
{
"id": 3,
"num": 300
}
]
}
Vertical list
There are two kinds of vertical list:
- Vertical scalar list, as list element type is scalar. E.g:
[]int32
. - Vertical struct list, as list element type is struct. E.g:
[Item]int32
.
Vertical scalar list
No need to support, use [Item]SCALAR
instead:
[Item]int32
[Item]enum<.FruitType>
Vertical struct list
A worksheet ItemConf
in HelloWorld.xlsx:
ID | Name | Desc |
---|---|---|
[Item]uint32 | string | string |
Item’s ID | Item’s name | Item’s desc |
1 | Apple | A kind of delicious fruit. |
2 | Orange | A kind of sour fruit. |
3 | Banana | A kind of calorie-rich fruit. |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {layout:LAYOUT_VERTICAL}];
message Item {
uint32 id = 1 [(tableau.field) = {name:"ID"}];
string name = 2 [(tableau.field) = {name:"Name"}];
string desc = 3 [(tableau.field) = {name:"Desc"}];
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"name": "Apple",
"desc": "A kind of delicious fruit."
},
{
"id": 2,
"name": "Orange",
"desc": "A kind of sour fruit."
},
{
"id": 3,
"name": "Banana",
"desc": "A kind of calorie-rich fruit."
}
]
}
Vertical predefined-struct list
Item
in common.proto is predefined as:
message Item {
int32 id = 1 [(tableau.field) = {name:"ID"}];
int32 num = 2 [(tableau.field) = {name:"Num"}];
}
A worksheet ItemConf
in HelloWorld.xlsx:
ID | Num |
---|---|
[.Item]int32 | int32 |
Item’s ID | Item’s num |
1 | 100 |
2 | 200 |
3 | 300 |
Generated:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated protoconf.Item _item_list = 1 [(tableau.field) = {layout:LAYOUT_VERTICAL}];
}
ItemConf.json
{
"ItemList": [
{
"id": 1,
"num": 100
},
{
"id": 2,
"num": 200
},
{
"id": 3,
"num": 300
}
]
}
Vertical incell-struct list
A worksheet ItemConf
in HelloWorld.xlsx:
Item |
---|
[]{int32 ID,int32 Num}Item |
Item’s info |
1,100 |
2,200 |
3,300 |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_VERTICAL span:SPAN_INNER_CELL}];
message Item {
int32 id = 1 [(tableau.field) = {name:"ID"}];
int32 num = 2 [(tableau.field) = {name:"Num"}];
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"num": 100
},
{
"id": 2,
"num": 200
},
{
"id": 3,
"num": 300
}
]
}
Vertical incell-predefined-struct list
Item
in common.proto is predefined as:
message Item {
int32 id = 1 [(tableau.field) = {name:"ID"}];
int32 num = 2 [(tableau.field) = {name:"Num"}];
}
A worksheet ItemConf
in HelloWorld.xlsx:
Item |
---|
[]{.Item} |
Item’s info |
1,100 |
2,200 |
3,300 |
Generated:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated protoconf.Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_VERTICAL span:SPAN_INNER_CELL}];
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"num": 100
},
{
"id": 2,
"num": 200
},
{
"id": 3,
"num": 300
}
]
}
Incell list
There are two kinds of in-cell list:
- Incell scalar list, as list value type is scalar. E.g:
[]int32
. - Incell struct list, as list value type is struct. E.g:
[Item]int32
.
Incell scalar list
A worksheet ItemConf
in HelloWorld.xlsx:
Param |
---|
[]int32 |
Param list |
1,2,3 |
4,5 |
6 |
The Param
column’s type is incell list []int32
, as the list element is scalar type int32
.
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated int32 param_list = 1 [(tableau.field) = {name:"Param" layout:LAYOUT_INCELL}];
}
ItemConf.json
{
"paramList": [
1,
2,
3,
4,
5,
6
]
}
Incell enum list
FruitType
in common.proto is predefined as:
enum FruitType {
FRUIT_TYPE_UNKNOWN = 0 [(tableau.evalue).name = "Unknown"];
FRUIT_TYPE_APPLE = 1 [(tableau.evalue).name = "Apple"];
FRUIT_TYPE_ORANGE = 3 [(tableau.evalue).name = "Orange"];
FRUIT_TYPE_BANANA = 4 [(tableau.evalue).name = "Banana"];
}
A worksheet ItemConf
in HelloWorld.xlsx:
Param |
---|
[]enum<.FruitType> |
Param list |
1,FRUIT_TYPE_ORANGE,Banana |
The Param
column’s type is incell list []enum<.FruitType>
, as the list element is the predefined enum type FruitType
.
Generated:
hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated protoconf.FruitType param_list = 1 [(tableau.field) = {name:"Param" layout:LAYOUT_INCELL}];
}
ItemConf.json
{
"paramList": [
"FRUIT_TYPE_APPLE",
"FRUIT_TYPE_ORANGE",
"FRUIT_TYPE_BANANA"
]
}
Incell struct list
See Advanced predefined incell struct â.
Horizontal list size
Dynamic size
By default, all lists are Dynamically Sized Types. List elements should be present continuously, otherwise an error is reported if an empty element is existed in between.
Fixed size
Implicit fixed size
The list size is auto resolved by the max present list elements in name row.
In this example below, though the second element Item2 is empty, it is legal as the field property fixed
is set true
. Besides, Item2 will also be generated as an empty element. You can see it in the generated file ItemConf.json.
A worksheet ItemConf
in HelloWorld.xlsx.
Item1ID | Item1Name | Item2ID | Item2Name | Item3ID | Item3Name |
---|---|---|---|---|---|
[Item]uint32|{fixed:true} | string | uint32 | string | uint32 | string |
Item1’s ID | Item1’s name | Item2’s ID | Item2’s name | Item3’s ID | Item3’s name |
1 | Apple | 3 | Banana |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL prop:{fixed:true}}];
message Item {
uint32 id = 1 [(tableau.field) = {name:"ID"}];
string name = 2 [(tableau.field) = {name:"Name"}];
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"name": "Apple"
},
{
"id": 0,
"name": ""
},
{
"id": 3,
"name": "Banana"
}
]
}
Explicit fixed size
The list size is explicitly set by field property size
.
In this example below, field property size
is set as 2, then list elements after the second element Item2 will all be truncated. Besides, Item2 will also be generated as an empty element. You can see it in the generated file ItemConf.json.
A worksheet ItemConf
in HelloWorld.xlsx:
Item1ID | Item1Name | Item2ID | Item2Name | Item3ID | Item3Name |
---|---|---|---|---|---|
[Item]uint32|{size:2} | string | uint32 | string | uint32 | string |
Item1’s ID | Item1’s name | Item2’s ID | Item2’s name | Item3’s ID | Item3’s name |
1 | Apple | 3 | Banana |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL prop:{size:2}}];
message Item {
uint32 id = 1 [(tableau.field) = {name:"ID"}];
string name = 2 [(tableau.field) = {name:"Name"}];
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"name": "Apple"
},
{
"id": 0,
"name": ""
}
]
}
Advanced features
Horizontal column-skipped list
A worksheet ItemConf
in HelloWorld.xlsx:
D | Prop1ID | Prop1Value | Prop2ID | Prop2Value | ||
---|---|---|---|---|---|---|
map<uint32, Item> | [Prop]int32 | int32 | int32 | int32 | ||
Item’s ID | Prop1âs ID | Prop1âs name | Prop1âs value | Prop2âs ID | Prop2âs name | Prop2âs value |
1 | 1 | Apple | 100 | 2 | Orange | 200 |
2 | 3 | Banana | 300 | 4 | Pomelo | 400 |
3 | 5 | Watermelon | 500 |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
map<uint32, Item> item_map = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
message Item {
uint32 id = 1 [(tableau.field) = {name:"ID"}];
repeated Prop prop_list = 2 [(tableau.field) = {name:"Prop" layout:LAYOUT_HORIZONTAL}];
message Prop {
int32 id = 1 [(tableau.field) = {name:"ID"}];
int32 value = 2 [(tableau.field) = {name:"Value"}];
}
}
}
HeroConf.json
{
"itemMap": {
"1": {
"id": 1,
"propList": [
{
"id": 1,
"value": 100
},
{
"id": 2,
"value": 200
}
]
},
"2": {
"id": 2,
"propList": [
{
"id": 3,
"value": 300
},
{
"id": 4,
"value": 400
}
]
},
"3": {
"id": 3,
"propList": [
{
"id": 5,
"value": 500
}
]
}
}
}
Keyed list
Keyed list is same as normal list, except that ColumnType
(first field type) is surrounded by angle brackets <>
, and is treated as map key.
Syntax: [ElemType]<ColumnType>
Vertical struct keyed-list
For example, a worksheet ItemConf
in HelloWorld.xlsx:
ID | PropID | PropName |
---|---|---|
[Item]<uint32> | map<int32, Prop> | string |
Item’s ID | Prop’s ID | Prop’s name |
1 | 1 | sweet |
2 | 1 | sweet |
2 | 2 | delicious |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated Item item_list = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
message Item {
uint32 id = 1 [(tableau.field) = {name:"ID"}];
map<int32, Prop> prop_map = 2 [(tableau.field) = {key:"PropID" layout:LAYOUT_VERTICAL}];
message Prop {
int32 prop_id = 1 [(tableau.field) = {name:"PropID"}];
string prop_name = 2 [(tableau.field) = {name:"PropName"}];
}
}
}
ItemConf.json
{
"itemList": [
{
"id": 1,
"propMap": {
"1": {
"propId": 1,
"propName": "sweet"
}
}
},
{
"id": 2,
"propMap": {
"1": {
"propId": 1,
"propName": "sweet"
},
"2": {
"propId": 2,
"propName": "delicious"
}
}
}
]
}
Scalar keyed-list
A worksheet ItemConf
in HelloWorld.xlsx:
Param |
---|
[]<int32> |
Param list |
1,2,2,3 |
Generated:
hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx"};
message ItemConf {
option (tableau.worksheet) = {name:"ItemConf" namerow:1 typerow:2 noterow:3 datarow:4};
repeated int32 param_list = 1 [(tableau.field) = {name:"Param" key:"Param" layout:LAYOUT_INCELL}];
}
ItemConf.json
{
"paramList": [
1,
2,
3
]
}