Specification
TableBundle Specification
The purpose of the TableBundle file format is to simplify the exchange of various datasheet files together with additional attachment between sandboxed applications. On the other hand, it also provides another common table storage format for collaborative tables. By using a single package file, Users can export,import and convert their own data in the datasheet between different products.
A TableBundle file may contain multiple folders node, subfolders node, datasheets node, and files referenced in data tables.
File Type
TableBundles can be stored inside a compressed Zip container. This is especially useful for exchanging files between users.
The compressed format uses the path extension .tablebundle
Structure of a TableBundle
A TableBundle package contains the following files:
File Name | Content |
|---|---|
| All meta information about the bundle. See section “The Meta Data File”. |
| The actual datasheet structure and data (Whereas * is an datasheet id). See section “The Datasheet File”. |
| All attachment asset files referenced from the datashhet |
The Meta Data File
The manifest file contains all datasheet index data about the TableBundle. It saves the structure of the folder node and the information of the datasheet. It is a JSON file using the following key / value pairs:
The Basic Field Define
Key | Type | Optional | Description |
|---|---|---|---|
| Integer | No | The version number of the file format. Latest version is 1. |
| json object | No | Datasheet Details. See section “The Roo Define”. |
| String | Yes | TableBundle generation time |
| String | Yes | TableBundle File Id. It may be necessary to persist. |
| String | Yes | Parameter URL when creating TableBundle file. |
The Roo Define
root contains all datasheet information in the form of json. The following is the description of the relevant key.
Key | Type | Optional | Description |
|---|---|---|---|
nodeName | String | No | node‘s name |
type | Integer | No | node type 0: root 1:folder 2: datasheet 3:Form 4.dashboard |
nodeId | String | No | node Id |
data | String | Yes | If the type is 2(datasheet), this field points to the definition of the data table. |
parentId | String | Yes | The ID of the parent node is used to record the file tree structure information. |
child | Root Array | Yes | Contents of the subfile |
Root Json Sample
The following shows an root example of the contents of an manifest.json file:
"root":{
"nodeName":"folder",
// a folder node
"type":1, // node type 0: root 1:folder 2: datasheet 3:Form 4.dashboard
"nodeId":"fodId", // node id
"child":[
{
"nodeName":"datasheet a",
"data":"0481a3361d065016ee3caa5cea49d6db.json",
"type":2,
"parentId":"fodgheMkKfPb8",
"nodeId":"dstfUYqfLptvPoDXNS",
"child":[
]
},
{
"nodeName":"datasheet b",
"data":"27cad031548dc149447b009a84fa4ac0.json",
"type":2,
"parentId":"fodgheMkKfPb8",
"nodeId":"dstuMTJsVjrmwmS7rY",
"child":[
]
}
]
}The Datasheet File
The content of the datasheet similar to concepts.
The content of the datasheet mainly saves two types of data in the form of json, one is the structure of the datasheet, including the fields and data types of the header. The other type is the row data of the datasheet.
Key | Type | Optional | Description |
|---|---|---|---|
meta | json object | No | the structure of the datasheet |
recordMap | json object | No | the row data of the datasheet |
The following shows an example of the contents of an dstIdXXX.json file:
{
"recordMap": {
"fldMNKMZ7X4P6": {
"data": {
"flds5VCUKUZMH": ["optQAZBO9LO3t"],
"fldMNKMZ7X4P6": [{
"type": 1,
"text": "x z c x z c "
}],
"fldt3qT5kfsBk": [{
"mimeType": "image/png",
"token": "space/2023/05/17/0026b58ee1654c439bffc3974f9cb4dc",
"bucket": "QNY1",
"size": 60983,
"name": "image.png",
"width": 856,
"id": "atcW6tzBymOzF",
"height": 646
}]
},
"id": "recXXXX",
"recordMeta": null
}
},
"meta": {
"fieldMap": {
"flds5VCUKUZMH": {
"type": 4,
"name": "选项",
"property": {
"options": [{
"color": 0,
"name": "想啊啥",
"id": "optQAZBO9LO3t"
}]
},
"id": "flds5VCUKUZMH"
},
"fldMNKMZ7X4P6": {
"type": 19,
"name": "标题",
"property": {
"defaultValue": ""
},
"id": "fldMNKMZ7X4P6"
},
"fldt3qT5kfsBk": {
"type": 6,
"name": "附件",
"id": "fldt3qT5kfsBk"
}
},
"views": [{
"frozenColumnCount": 1,
"columns": [{
"statType": 1,
"fieldId": "fldMNKMZ7X4P6"
}, {
"fieldId": "flds5VCUKUZMH"
}, {
"fieldId": "fldt3qT5kfsBk"
}],
"rows": [{
"recordId": "recfte8MK9TWd"
}, {
"recordId": "recc2klate85d"
}, {
"recordId": "recMWYWw95sVi"
}],
"type": 1,
"autoSave": false,
"name": "维格视图",
"id": "viwruy3vMmo70"
}]
}
}Referencing Assets
Inside the .tablebundle file, all assets can be saved in a folder called assets/. By that, even apps that are unable to open TableBundles can correctly process the datasheets of a bundle. They can handle the attachments in the form in any way they want.
When exporting files into TableBundles, the application should automatically add the attachments into assets\ folder. This way, users do not need to consider the usage of TableBundl. At the same time, you don't have to worry about losing accessories.
Cooperating With Other Applications
TableBundles are meant to be opened, processed and modified by multiple applications at once. Therefore, applications must behave cooperatively on a bundle file. Whenever an application overwrites a TableBundle it should pay attention that any application-specific meta data of other applications is kept.
Snapshot API
Here we give the definition of the snapshot data structure:
export interface ISnapshot {
meta: IMeta;
recordMap: IRecordMap;
}The meta object contains table information and row data information:
export interface IMeta {
fieldMap: IFieldMap;
views: IViewProperty[];
widgetPanels?: IWidgetPanel[];
}
export interface IFieldMap {
[fieldId: string]: IField;
}
export interface IViewProperty {
id: string;
name: string;
type: ViewType;
rows: IViewRow[];
columns: IViewColumn[];
}The recordMap object contains row data information:
export interface IRecordMap {
[recordId: string]: IRecord;
}
export interface IRecord {
id: string;
/**
*
* the data inside the record
* only the record's some fields with content, `data` will contains the field's fieldId key
*/
data: IRecordCellValue;
/**
* the number of records' comments
*
* @type {number}
*/
commentCount: number;
/**
* optional, return all comments of current record by api request
* @type {IComments[]}
*/
comments?: IComments[];
/**
* @type: timestamp
* @desc: the timestamp that be deleted
*/
deleteAt?: number;
/**
* the meta of record.
* infos of createdAt/updatedAt/createdBy/updatedBy and fieldUpdatedMap
*/
recordMeta?: IRecordMeta;
/**
* @type: timestamp
* the timestamp that created
*/
createdAt?: number;
/**
* @type: timestamp
* the timestamp that last modified
*/
updatedAt?: number;
}FAQ
How to deal with IDs in json
In the exported .tablebundle file, there are various IDs. When importing again, the nodeId will be rewritten, but the record id can not be processed.
more features
We can use tablebundle as the data exchange format, for example, provide the function of converting xlsx file to tablebundle.