List 嵌套 List

Excel list 中嵌套 list 的规范说明。

纵向 list 中的嵌套

纵向 list 中的横向 list

HelloWorld.xlsx 中的 worksheet ItemConf

IDNameProp1IDProp1ValueProp2IDProp2Value
[Item]uint32string[Prop]int32int64int32int64
Item’s IDItem’s nameProp1’s IDProp1’s valueProp2’s IDProp2’s value
1Apple110220
2Orange330
3Banana

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  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"}];
    repeated Prop prop_list = 3 [(tableau.field) = {name:"Prop" layout:LAYOUT_HORIZONTAL}];
    message Prop {
      int32 id = 1 [(tableau.field) = {name:"ID"}];
      int64 value = 2 [(tableau.field) = {name:"Value"}];
    }
  }
}
ItemConf.json
{
    "itemList": [
        {
            "id": 1,
            "name": "Apple",
            "propList": [{"id": 1, "value": "10"}, {"id": 2, "value": "20"}]
        },
        {
            "id": 2,
            "name": "Orange",
            "propList": [{"id": 3, "value": "30"}]
        },
        {
            "id": 3,
            "name": "Banana",
            "propList": []
        }
    ]
}

纵向 keyed-list 中的纵向 list

HelloWorld.xlsx 中的 worksheet ItemConf

IDNamePropIDPropValue
[Item]<uint32>string[Prop]int32int64
Item’s IDItem’s nameProp’s IDProp’s value
1Apple110
2Orange120
2Banana230

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated Item item_list = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
  message Item {
    uint32 id = 1 [(tableau.field) = {name:"ID"}];
    string name = 2 [(tableau.field) = {name:"Name"}];
    repeated Prop prop_list = 3 [(tableau.field) = {layout:LAYOUT_VERTICAL}];
    message Prop {
      int32 prop_id = 1 [(tableau.field) = {name:"PropID"}];
      int64 prop_value = 2 [(tableau.field) = {name:"PropValue"}];
    }
  }
}
ItemConf.json
{
    "itemList": [
        {
            "id": 1,
            "name": "Apple",
            "propList": [{"propId": 1, "propValue": "10"}]
        },
        {
            "id": 2,
            "name": "Orange",
            "propList": [{"propId": 1, "propValue": "20"}, {"propId": 2, "propValue": "30"}]
        }
    ]
}

纵向 keyed-list 中的纵向 keyed-list

HelloWorld.xlsx 中的 worksheet ItemConf

IDDescPropIDPropNum
[KeyedItem]<uint32>string[Prop]<uint32>int32
Item’s IDItem’s descProp’s IDProp’s num
1Apple10100
1Banana11110
2Orange20200

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated KeyedItem keyed_item_list = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
  message KeyedItem {
    uint32 id = 1 [(tableau.field) = {name:"ID"}];
    string desc = 2 [(tableau.field) = {name:"Desc"}];
    repeated Prop prop_list = 3 [(tableau.field) = {key:"PropID" layout:LAYOUT_VERTICAL}];
    message Prop {
      uint32 prop_id = 1 [(tableau.field) = {name:"PropID"}];
      int32 prop_num = 2 [(tableau.field) = {name:"PropNum"}];
    }
  }
}
ItemConf.json
{
    "keyedItemList": [
        {
            "id": 1,
            "desc": "Apple",
            "propList": [{"propId": 10, "propNum": 100}, {"propId": 11, "propNum": 110}]
        },
        {
            "id": 2,
            "desc": "Orange",
            "propList": [{"propId": 20, "propNum": 200}]
        }
    ]
}

纵向 keyed-list 中的 incell list

HelloWorld.xlsx 中的 worksheet ItemConf

IDProp
[Item]uint32[]int32
Item’s IDItem’s props
110,20,30
210,20
310

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated Item item_list = 1 [(tableau.field) = {layout:LAYOUT_VERTICAL}];
  message Item {
    uint32 id = 1 [(tableau.field) = {name:"ID"}];
    repeated int32 prop_list = 2 [(tableau.field) = {name:"Prop" layout:LAYOUT_INCELL}];
  }
}
ItemConf.json
{
    "itemList": [
        {"id": 1, "propList": [10, 20, 30]},
        {"id": 2, "propList": [10, 20]},
        {"id": 3, "propList": [10]}
    ]
}

纵向 keyed-list 中的 incell keyed-list

HelloWorld.xlsx 中的 worksheet ItemConf

IDDescTip
[KeyedItem]<uint32>|{unique:false}string[]<uint32>
Item’s IDItem’s descItem’s tip
1Apple1,2,3
1Banana4,5
2Orange1,2

父级 struct keyed-list 需要聚合 incell keyed-list,因此需要将字段属性 unique 设置为 false

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated KeyedItem keyed_item_list = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
  message KeyedItem {
    uint32 id = 1 [(tableau.field) = {name:"ID" prop:{unique:false}}];
    string desc = 2 [(tableau.field) = {name:"Desc"}];
    repeated uint32 tip_list = 3 [(tableau.field) = {name:"Tip" key:"Tip" layout:LAYOUT_INCELL}];
  }
}
ItemConf.json
{
    "keyedItemList": [
        {"id": 1, "desc": "Apple", "tipList": [1, 2, 3, 4, 5]},
        {"id": 2, "desc": "Orange", "tipList": [1, 2]}
    ]
}

横向 list 中的嵌套

横向 list 中的横向 list

HelloWorld.xlsx 中的 worksheet ItemConf

Reward1Item1IDReward1Item1NumReward1Item2IDReward1Item2NumReward1NameReward2Item1IDReward2Item1NumReward2Name
[Reward][Item]int32int32int32int32stringint32int32string
Item1’s IDItem1’s numItem2’s IDItem2’s numReward’s nameItem1’s IDItem1’s numReward’s name
110220Lotto10100Super Lotto

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated Reward reward_list = 1 [(tableau.field) = {name:"Reward" layout:LAYOUT_HORIZONTAL}];
  message Reward {
    repeated Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL}];
    message Item {
      int32 id = 1 [(tableau.field) = {name:"ID"}];
      int32 num = 2 [(tableau.field) = {name:"Num"}];
    }
    string name = 2 [(tableau.field) = {name:"Name"}];
  }
}
ItemConf.json
{
    "rewardList": [
        {"itemList": [{"id": 1, "num": 10}, {"id": 2, "num": 20}], "name": "Lotto"},
        {"itemList": [{"id": 10, "num": 100}], "name": "Super Lotto"}
    ]
}

横向 list 中的 predefined struct list

common.proto 中预定义的 Item

message Item {
    int32 id = 1 [(tableau.field) = {name:"ID"}];
    int32 num = 2 [(tableau.field) = {name:"Num"}];
}

HelloWorld.xlsx 中的 worksheet ItemConf

Reward1Item1IDReward1Item1NumReward1Item2IDReward1Item2NumReward1NameReward2Item1IDReward2Item1NumReward2Name
[Reward][.Item]int32int32int32int32stringint32int32string
Item1’s IDItem1’s numItem2’s IDItem2’s numReward’s nameItem1’s IDItem1’s numReward’s name
110220Lotto10100Super Lotto

生成结果:

hello_world.proto
// --snip--
import "common.proto";
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated Reward reward_list = 1 [(tableau.field) = {name:"Reward" layout:LAYOUT_HORIZONTAL}];
  message Reward {
    repeated protoconf.Item item_list = 1 [(tableau.field) = {name:"Item" layout:LAYOUT_HORIZONTAL}];
    string name = 2 [(tableau.field) = {name:"Name"}];
  }
}
ItemConf.json
{
    "rewardList": [
        {"itemList": [{"id": 1, "num": 10}, {"id": 2, "num": 20}], "name": "Lotto"},
        {"itemList": [{"id": 10, "num": 100}], "name": "Super Lotto"}
    ]
}

横向 list 中的 incell list

HelloWorld.xlsx 中的 worksheet ItemConf

Task1ParamTask2ParamTask3Param
[Task][]int32[]int32[]int32
Task1Task2Task3
1,23,45,6,7

生成结果:

hello_world.proto
// --snip--
option (tableau.workbook) = {name:"HelloWorld.xlsx" namerow:1 typerow:2 noterow:3 datarow:4};

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  repeated Task task_list = 1 [(tableau.field) = {name:"Task" layout:LAYOUT_HORIZONTAL}];
  message Task {
    repeated int32 param_list = 1 [(tableau.field) = {name:"Param" layout:LAYOUT_INCELL}];
  }
}
ItemConf.json
{
    "taskList": [
        {"paramList": [1, 2]},
        {"paramList": [3, 4]},
        {"paramList": [5, 6, 7]}
    ]
}