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

manifest.json

All meta information about the bundle. See section “The Meta Data File”.

data/dst*.json

The actual datasheet structure and data (Whereas * is an datasheet id). See section “The Datasheet File”.

asset\

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

version

Integer

No

The version number of the file format. Latest version is 1.

root

json object

No

Datasheet Details. See section “The Roo Define”.

createAt

String

Yes

TableBundle generation time

identifier

String

Yes

TableBundle File Id. It may be necessary to persist.

creatorURL

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.

Resource