Sales Report

Sales reports can be useful for tracking the performance of individual salespeople or product lines, identifying trends in consumer behavior, and determining overall growth or decline in revenue.

Description
app.js
index.html
styles.css
Copy to CodeMine
Open the demo in new window can open the designer

How to open desgnr

You can use the ‘Group' and 'Summary’ cell types to generate the sales report in the following steps.

  • Define the sales table in the DataManager.
  • Set the style for the template.
  • Bind the data column to the template and use the ‘Group' and 'Summary’ cell types.
const spread = new GC.Spread.Sheets.Workbook('ss', { sheetCount: 1 });
spread.options.scrollByPixel = true;
spread.options.scrollbarMaxAlign = true;
const records = [
    ['East', 'John', 'Banana', 180],
    ['East', 'Mike', 'Banana', 200],
    ['East', 'Emma', 'Banana', 210],
    ['East', 'Sophia', 'Banana', 316],
    ['East', 'Jennifer', 'Banana', 130],
    ['North', 'Kristen', 'Banana', 410.0],
    ['North', 'Mia', 'Banana', 290.0],
    ['North', 'Bella', 'Banana', 342.0],
    ['North', 'Eva', 'Banana', 214.0],
    ['East', 'John', 'Strawberry', 230.0],
    ['East', 'Mike', 'Strawberry', 641.0],
    ['East', 'Emma', 'Strawberry', 234.0],
    ['East', 'Sophia', 'Strawberry', 625.0],
    ['East', 'Jennifer', 'Strawberry', 241.0],
    ['North', 'Kristen', 'Strawberry', 195.0],
    ['North', 'Mia', 'Strawberry', 569.0],
    ['North', 'Bella', 'Strawberry', 698.0],
    ['North', 'Eva', 'Strawberry', 214.0],
    ['East', 'John', 'Watermelon', 147.0],
    ['East', 'Mike', 'Watermelon', 489.0],
    ['East', 'Emma', 'Watermelon', 347.0],
    ['East', 'Sophia', 'Watermelon', 652.0],
    ['East', 'Jennifer', 'Watermelon', 471.0],
    ['North', 'Kristen', 'Watermelon', 287.0],
    ['North', 'Mia', 'Watermelon', 349.0],
    ['North', 'Bella', 'Watermelon', 163.0],
    ['North', 'Eva', 'Watermelon', 841.0],
    ['East', 'John', 'Chips', 292.0],
    ['East', 'Mike', 'Chips', 514.0],
    ['East', 'Emma', 'Chips', 256.0],
    ['East', 'Sophia', 'Chips', 148.0],
    ['East', 'Jennifer', 'Chips', 486.0],
    ['North', 'Kristen', 'Chips', 285.0],
    ['North', 'Mia', 'Chips', 741.0],
    ['North', 'Bella', 'Chips', 249.0],
    ['North', 'Eva', 'Chips', 105.0],
    ['East', 'John', 'Cookie', 554.0],
    ['East', 'Mike', 'Cookie', 311.0],
    ['East', 'Emma', 'Cookie', 186.0],
    ['East', 'Sophia', 'Cookie', 654.0],
    ['East', 'Jennifer', 'Cookie', 247.0],
    ['North', 'Kristen', 'Cookie', 143.0],
    ['North', 'Mia', 'Cookie', 617.0],
    ['North', 'Bella', 'Cookie', 214.0],
    ['North', 'Eva', 'Cookie', 324.0],
];
const columns = ['Region', 'Salesman', 'Product', 'Sales'];
const salesTable = spread.dataManager().addTable('Sales', {
    data: records.map((x) => {
        const record = {};
        columns.forEach((c, i) => record[c] = x[i]);
        return record;
    })
});

salesTable.fetch().then(() => {
    const reportSheet = spread.addSheetTab(0, 'Sales Report', GC.Spread.Sheets.SheetType.reportSheet);
    const templateSheet = reportSheet.getTemplate();

    // set style for the template
    templateSheet.defaults.colWidth = 100;
    const headerStyle = new GC.Spread.Sheets.Style();
    headerStyle.backColor = '#91ACDA';
    headerStyle.foreColor = '#424242';
    headerStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
    headerStyle.font = '12px Maine';
    const dataStyle = new GC.Spread.Sheets.Style();
    dataStyle.foreColor = '#424242';
    dataStyle.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
    dataStyle.vAlign = GC.Spread.Sheets.VerticalAlign.center;
    dataStyle.font = '12px Maine';
    const border = new GC.Spread.Sheets.LineBorder('#E0E0E0', 1);
    dataStyle.borderBottom = border;
    dataStyle.borderTop = border;
    dataStyle.borderLeft = border;
    dataStyle.borderRight = border;
    const dataStyle1 = dataStyle.clone();
    dataStyle1.backColor = '#FFF8E1';
    const dataStyle2 = dataStyle.clone();
    dataStyle2.backColor = '#FFE082';
    templateSheet.getRange('A1:D1').setStyle(headerStyle);
    templateSheet.getRange('A2:D4').setStyle(dataStyle);
    templateSheet.getRange('C3:D3').setStyle(dataStyle1);
    templateSheet.getRange('B4:D4').setStyle(dataStyle2);
    [[1, 0, 3, 1], [1, 1, 2, 1], [3, 1, 1, 2]].forEach(x => templateSheet.addSpan(...x));
    [[2, 2], [3, 1]].forEach(x => {
        templateSheet.setValue(x[0], x[1], 'Total');
        const style = templateSheet.getStyle(...x).clone();
        style.hAlign = GC.Spread.Sheets.HorizontalAlign.left;
        templateSheet.setStyle(x[0], x[1], style);
    });
    [1, 2, 3].forEach(r => {
        const style = templateSheet.getStyle(r, 3).clone();
        style.hAlign = GC.Spread.Sheets.HorizontalAlign.right;
        templateSheet.setStyle(r, 3, style);
    });
    templateSheet.setValue(3, 1, 'Total');

    // set binding for the template
    columns.forEach((columnName, i) => {
        templateSheet.setValue(0, i, columnName);
        if (i < 3) {
            templateSheet.setTemplateCell(1, i, {
                type:'Group',
                binding: `Sales[${columnName}]`,
            });
        }
        else {
            [1, 2, 3].forEach(c => {
                templateSheet.setTemplateCell(c, i, {
                    type: 'Summary',
                    aggregate: 'Sum',
                    binding: `Sales[${columnName}]`,
                });
            })
        }
    });

    reportSheet.refresh();
});
Open the demo in new window can open the designer You can use the ‘Group' and 'Summary’ cell types to generate the sales report in the following steps. Define the sales table in the DataManager. Set the style for the template. Bind the data column to the template and use the ‘Group' and 'Summary’ cell types.
window.onload = async () => { const loadingTip = addLoadingTip(); const { spread, designer } = createSpreadAndDesigner(); const res = await fetch('$DEMOROOT$/en/sample/features/report-sheet/showcase/grouped-report/sales-report/spread.json'); await spread.fromJSON(await res.json()); loadingTip.remove(); if (designer) { designer.refresh(); } } function createSpreadAndDesigner() { const demoHost = document.getElementById('demo-host'); if (window !== top) { return { spread: new GC.Spread.Sheets.Workbook(demoHost, { sheetCount: 1 }), } } else { const designer = new GC.Spread.Sheets.Designer.Designer(demoHost, undefined, undefined, { sheetCount: 1 }); return { designer, spread: designer.getWorkbook(), } } } function addLoadingTip() { const div = document.createElement('div'); div.style.position = 'absolute'; div.style.inset = '0'; div.style.display = 'flex'; div.style.alignItems = 'center'; div.style.justifyContent = 'center'; div.style.background = 'white'; div.style.zIndex = '100'; div.textContent = 'Loading data from server ...'; document.body.appendChild(div); return div; }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script> const designerDependencyScripts = [ '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer-resources-en/dist/gc.spread.sheets.designer.resource.en.min.js', '$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js', '$DEMOROOT$/spread/source/js/designer/license.js', ] function appendScriptNode (src) { const script = document.createElement('script'); script.src = src; script.async = false; script.type = 'text/javascript'; document.head.appendChild(script); } if (top === window) { // not in iframe designerDependencyScripts.forEach(appendScriptNode); } </script> <script src="app.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <div id="demo-host"></div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } #demo-host { width: 100%; height: 100%; overflow: hidden; float: left; }