Overview

TableSheet grouping can group a data source by the specified fields.

Besides the basic column, each group can have summary columns, which can use any formula to aggregate the grouped records, such as SUM, AVERAGE, COUNT, COUNTA, MIN or MAX.

Each summary column can also have slice columns, which can slice the aggregation result into several columns.

In addition, the basic column and the summary columns can have captions and the width and style can be changed.

The slice columns have width and styles that can be changed.

Description
app.vue
index.html
Copy to CodeMine

TableSheet class provides the groupBy method and removeGroupBy method.

  /**
    * group the table sheet by options
    * @param {GC.Spread.Sheets.TableSheet.IGroupByOptions[]} options - The options of the groupBy
    * @returns {GC.Spread.Sheets.TableSheet.IGroupByOptions[]}
    */
   groupBy(options?: GC.Spread.Sheets.TableSheet.IGroupByOptions[]): GC.Spread.Sheets.TableSheet.IGroupByOptions[]

TableSheet could be grouped by a single field.

sheet.groupBy([
    {
        field: "Category"
    }
]);

TableSheet could be grouped by single field, with summary fields and slice fields.

sheet.groupBy([
    {
        caption: "Category", field: "Category", width: 120, style: { backColor: "#D0CECE" }, summaryFields: [
            {
                caption: "SUM(Quantity)",
                formula: "=SUM([Quantity])",
                slice: {field: "Office", width: 120, style: { backColor: "#D9E1F2"} },
                width: 120,
                style: { backColor: "#D9E1F2" }
            },
            {
                caption: "SUM(Amount)",
                formula: "=SUM([Amount])",
                slice: {field: "=YEAR([@OrderDate])", width: 120, style: { backColor: "#E2EFDA", formatter: "$ #,##0.00"} },
                width: 120,
                style: { backColor: "#E2EFDA", formatter: "$ #,##0.00" }
            }
        ]
    }
]);
  /**
   * remove group status of the table sheet
   * @returns {void}
   */
  removeGroupBy(): void

TableSheet could be removed the group status.

sheet.removeGroupBy();
TableSheet class provides the groupBy method and removeGroupBy method. TableSheet could be grouped by a single field. TableSheet could be grouped by single field, with summary fields and slice fields. TableSheet could be removed the group status.
<template> <div class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"> </gc-spread-sheets> <div class="options-container"> <div class="option-row"> <label>Use the below buttons to group or ungroup.</label> </div> <div class="option-row"> <input type="button" value="Group" id="groupButton" @click="groupCallback" /> <input type="button" value="Remove Group" id="removeGroupButton" @click="removeGroupCallback" /> </div> </div> </div> </template> <script setup> import GC from "@mescius/spread-sheets"; import { ref, toRaw } from "vue"; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-vue"; const spreadRef = ref(null); function initSpread(spread) { spreadRef.value = spread; spread.suspendPaint(); spread.clearSheets(); spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader; //init a data manager var dataManager = spread.dataManager(); var ordersTable = dataManager.addTable("ordersTable", { data: orderDataSource, schema: { type: "csv", columns: { OrderDate: { dataType: "date" }, ShipDate: { dataType: "date" }, Quantity: { dataType: "number" }, Amount: { dataType: "number" } } } }); //init a table sheet var sheet = spread.addSheetTab(0, "TableSheet1", GC.Spread.Sheets.SheetType.tableSheet); sheet.setDefaultRowHeight(40, GC.Spread.Sheets.SheetArea.colHeader); sheet.options.allowAddNew = false; //hide new row //bind a view to the table sheet ordersTable.fetch().then(function () { var myView = ordersTable.addView("myView", [ { value: "OrderID", caption: "ID", width: 100 }, { value: "Product", width: 150 }, { value: "OrderDate", caption: "Order Date", width: 105 }, { value: "ShipDate", caption: "Ship Date", width: 105 }, { value: "Quantity", width: 100 }, { value: "Amount", width: 100 }, { value: "Office", width: 100 }, { value: "Category", width: 150 }]); spread.suspendPaint(); sheet.setDataView(myView); groupCallback(); spread.resumePaint(); }); spread.resumePaint(); } function groupCallback() { let sheet = spreadRef.value.getActiveSheetTab(); sheet.groupBy([{ caption: "Category", field: "Category", width: 120, style: { backColor: "#D0CECE" }, summaryFields: [ { caption: "Σ(Quantity)", formula: "=SUM([Quantity])", slice: { field: "Office", width: 70, style: { backColor: "#D9E1F2" } }, width: 105, style: { backColor: "#D9E1F2" } }, { caption: "μ(Amount)", formula: "=AVERAGE([Amount])", slice: { field: "=YEAR([@OrderDate])", width: 80, style: { backColor: "#E2EFDA", formatter: "$ #,##0.00" } }, width: 100, style: { backColor: "#E2EFDA", formatter: "$ #,##0.00" } } ] }]); } function removeGroupCallback() { let sheet = spreadRef.value.getActiveSheetTab(); sheet.removeGroupBy(); } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/demos\//)[0] + 'server/api'; } </script> <style scoped> #app { height: 100%; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 210px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 210px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } label { display: block; margin-bottom: 3px; margin-top: 3px; } input { padding: 4px 6px; } input[type=button] { margin-top: 6px; display: block; width: 100%; text-align: center; } input[type=text] { width: 230px; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: 0; } </style>
<!DOCTYPE html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>SpreadJS VUE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/spread/source/data/orderDataSource.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script> <script src="./systemjs.config.js"></script> <script src="./compiler.js" type="module"></script> <script> var System = SystemJS; System.import("./src/app.js"); System.import('$DEMOROOT$/en/lib/vue3/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
(function (global) { SystemJS.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, packageConfigPaths: [ './node_modules/*/package.json', "./node_modules/@mescius/*/package.json", "./node_modules/@babel/*/package.json", "./node_modules/@vue/*/package.json" ], map: { 'vue': "npm:vue/dist/vue.esm-browser.js", 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', "systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js", '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js' }, meta: { '*.css': { loader: 'systemjs-plugin-css' }, '*.vue': { loader: "../plugin-vue/index.js" } } }); })(this);