基本函数

SpreadJS 提供了丰富的内置函数库,支持 450 多个 Excel 兼容函数。本 Demo 以学生成绩数据为例,演示如何使用 AVERAGE、MAX、MIN、MEDIAN 等统计函数进行数据计算与分析,并通过三色条件格式直观展示数据分布。

概述 本 Demo 展示了 SpreadJS 内置基本函数的使用方法。Demo 包含两个工作表:第一个工作表以学生成绩为例,演示如何使用 AVERAGE、MAX、MIN、MEDIAN 等统计函数计算平均分、最高分、最低分和中位数;第二个工作表展示了 Excel 2010 新增函数的使用示例。 实现思路 使用 setArray 方法批量加载学生成绩数据到工作表 使用 setArray 方法的第四个参数将公式数组批量设置到单元格 使用统计函数(AVERAGE、MAX、MIN、MEDIAN)计算各项统计数据 为平均分列添加三色条件格式,实现数据可视化效果 创建第二个工作表,展示 Excel 2010 新增函数的用法和结果 代码解析 批量设置学生成绩数据 setArray 方法将二维数组批量设置到工作表的指定位置。相比多次调用 setValue,setArray 在处理大量数据时性能更优。第一个参数 0 表示起始行索引,第二个参数 1 表示起始列索引。 批量设置统计公式 setArray 方法的第四个参数设为 true,表示数组中的字符串是公式而非普通文本。这样可以一次性将多个公式设置到单元格,避免多次调用 setFormula。AVERAGE 函数计算指定范围内数值的平均值。 计算各科统计数据 这段代码计算各科的统计数据: MAX 函数:返回范围内的最大值 MIN 函数:返回范围内的最小值 MEDIAN 函数:返回范围内的中位数 添加三色条件格式 add3ScaleRule 方法为指定范围添加三色渐变条件格式: minType、minValue、minColor:最小值的类型、值和颜色(红色) midType、midValue、midColor:中间值的类型、值和颜色(白色) maxType、maxValue、maxColor:最大值的类型、值和颜色(绿色) ranges:应用条件的单元格范围数组 这里使用 ScaleValueType.lowestValue 表示最小值,ScaleValueType.percentile 表示第 50 百分位数(中位数),ScaleValueType.highestValue 表示最大值。条件格式会根据单元格值的大小,在红、白、绿三色之间渐变,直观展示成绩分布。 运行效果 第一个工作表显示学生成绩表,包含每位学生的五次作业成绩和自动计算的平均分 表格底部显示各科的统计数据:平均分、最高分、最低分和中位数 平均分列使用三色条件格式,分数越高颜色越绿,越低越红,中间值显示为白色 第二个工作表展示了多种 Excel 2010 新增函数(如 BETA.DIST、CHISQ.DIST、F.DIST 等)的使用示例和计算结果 双击公式单元格可查看完整公式,支持直接编辑和修改 API 参考 setArray 方法 row:起始行索引 column:起始列索引 array:要设置的二维数组 setFormula:可选,是否将数组中的字符串作为公式处理 conditionalFormats.add3ScaleRule 方法 minType:最小值类型(如 ScaleValueType.lowestValue) minValue:最小值(某些类型可为 null) minColor:最小值的颜色 midType:中间值类型(如 ScaleValueType.percentile) midValue:中间值 midColor:中间值的颜色 maxType:最大值类型(如 ScaleValueType.highestValue) maxValue:最大值(某些类型可为 null) maxColor:最大值的颜色 ranges:应用范围的 Range 对象数组
window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 2 }); initSpread(spread); }; function initSpread(spread) { var spreadNS = GC.Spread.Sheets; var sheet = spread.getActiveSheet(); spread.suspendPaint(); var data = [ ['五年级数学'], ['作业'], ['学生', 1, 2, 3, 4, 5, , '平均分'], ['Anna Mull', 76, 52, 91, 87, 98], ['Anna Sthesia', 95, 95, 94, 98, 95], ['Barb Ackue', 86, 83, 84, 89, 90], ['Barb Dwyer', 59, 40, 60, 20, 66], ['Barry Wine', 75, 55, 64, 76, 89], ['Bob Frapples', 91, 80, 72, 98, 95], ['Brock Lee', 86, 77, 89, 76, 70], ['Buck Kinnear', 100, 95, 94, 92, 91], ['Cliff Hanger', 97, 98, 99, 81, 89], ['Cory Ander', 53, 69, 93, 60, 95], [''], ['平均分:'], ['最高分:'], ['最低分:'], ['中位数分数:'], ]; var formulas_r = [ ['=AVERAGE(C4:G4)'], ['=AVERAGE(C5:G5)'], ['=AVERAGE(C6:G6)'], ['=AVERAGE(C7:G7)'], ['=AVERAGE(C8:G8)'], ['=AVERAGE(C9:G9)'], ['=AVERAGE(C10:G10)'], ['=AVERAGE(C11:G11)'], ['=AVERAGE(C12:G12)'], ['=AVERAGE(C13:G13)'] ]; var formulas_b = [ ['=AVERAGE(C4:C13)', '=AVERAGE(D4:D13)', '=AVERAGE(E4:E13)', '=AVERAGE(F4:F13)', '=AVERAGE(G4:G13)'], ['=MAX(C4:C13)', '=MAX(D4:D13)', '=MAX(E4:E13)', '=MAX(F4:F13)', '=MAX(G4:G13)'], ['=MIN(C4:C13)', '=MIN(D4:D13)', '=MIN(E4:E13)', '=MIN(F4:F13)', '=MIN(G4:G13)'], ['=MEDIAN(C4:C13)', '=MEDIAN(D4:D13)', '=MEDIAN(E4:E13)', '=MEDIAN(F4:F13)', '=MEDIAN(G4:G13)'], ]; sheet.setArray(0, 1, data); sheet.setArray(3, 8, formulas_r, true); sheet.setArray(14, 2, formulas_b, true); sheet.setRowHeight(0, 40); sheet.getCell(0, 1).font('Bold 19px Arial').vAlign(spreadNS.VerticalAlign.center); sheet.addSpan(1, 1, 1, 8); sheet.getCell(1, 1).font('Bold 13px Arial') .hAlign(spreadNS.HorizontalAlign.center) .backColor('rgb(130, 188, 0)') .foreColor('white') .vAlign(spreadNS.VerticalAlign.center); sheet.getRange(2, 1, 1, 8).font('Bold 13px Arial') .backColor('rgb(244, 248, 235)') .vAlign(spreadNS.VerticalAlign.center) .borderBottom(new spreadNS.LineBorder('black', spreadNS.LineStyle.thin)); sheet.getCell(2, 8).hAlign(spreadNS.HorizontalAlign.right); sheet.getRange(3, 1, 10, 8).font('12px Arial'); sheet.getRange(14, 1, 4, 8).backColor('rgb(230,230,230)'); sheet.getRange(14, 1, 4, 1).font('Bold 12px Arial').hAlign(spreadNS.HorizontalAlign.right); [110, 70, 70, 70, 70, 70, 10, 80].forEach(function (val, index) { sheet.setColumnWidth(index + 1, val); }); sheet.conditionalFormats.add3ScaleRule( spreadNS.ConditionalFormatting.ScaleValueType.lowestValue, null, 'rgb(231,114,111)', spreadNS.ConditionalFormatting.ScaleValueType.percentile, 50, 'rgb(252,252,255)', spreadNS.ConditionalFormatting.ScaleValueType.highestValue, null, 'rgb(122,188,129)', [new GC.Spread.Sheets.Range(3, 8, 10, 1)]); spread.resumePaint(); initExcel2010(spread); }; function initExcel2010(spread) { var spreadNS = GC.Spread.Sheets; var sheet = spread.getSheet(1); sheet.name("Excel 2010 函数"); sheet.setColumnWidth(0, 200); sheet.setColumnWidth(1, 400); sheet.setColumnWidth(2, 80); sheet.getRange(-1, 0, -1, 1).wordWrap(true); sheet.getRange(-1, 1, -1, 1).wordWrap(true); let data = [ ["公式", "描述", "结果"], ["=BETA.DIST(2,8,10,TRUE,1,3)", "累积贝塔概率密度函数"], ["=BETA.DIST(2,8,10,FALSE,1,3)", "贝塔概率密度函数"], ["=CEILING.PRECISE(4.3)", "将 4.3 向上舍入到最接近的 1 的倍数。"], ["=CEILING.PRECISE(-4.3)", "将 -4.3 向上舍入到最接近的 1 的倍数。由于数字为负,因此向 0 舍入。"], ["=CEILING.PRECISE(4.3, 2)", "将 4.3 向上舍入到最接近的 2 的倍数。"], ["=CHISQ.DIST(0.5,1,TRUE)", "0.5 的卡方分布,返回为累积分布函数,使用 1 个自由度。"], ["=CHISQ.DIST(2,3,FALSE)", "2 的卡方分布,返回为概率密度函数,使用 3 个自由度。"], ["=CHISQ.INV(0.93,1)", "0.93 的卡方分布左尾概率的反函数,使用 1 个自由度。"], ["=CHISQ.INV(0.6,2)", "0.6 的卡方分布左尾概率的反函数,使用 2 个自由度。"], ["=CONFIDENCE.T(0.05,1,50)", "基于样本大小为 50、显著性水平为 5% 且标准差为 1 的总体均值的置信区间。这基于学生 t 分布。"], ["=COVARIANCE.S({2,4,8},{5,8,11})", "以数组形式输入到函数中的数据点的样本协方差。"], ["=ERF.PRECISE(0.74500)", "误差函数在 0 和 0.74500 之间的积分 (0.707929)"], ["=ERFC.PRECISE(0.74500)", "0.74500 的互补误差函数。"], ["=F.DIST(15.2069,6,4,TRUE)", "使用累积分布函数的 F 概率(累积参数为 TRUE)。"], ["=F.DIST(15.2069,6,4,FALSE)", "使用概率密度函数的 F 概率(累积参数为 FALSE)。"], ["=F.INV(0.01,6,4)", "F 概率分布的反函数。"], ["=FLOOR.PRECISE(-3.2)", "将 -3.2 向下舍入到最接近的 -1 的倍数"], ["=FLOOR.PRECISE(3.2)", "将 3.2 向下舍入到最接近的 1 的倍数"], ["=FLOOR.PRECISE(3.2, 2)", "将 3.2 向下舍入到最接近的 2 的倍数"], ["=GAMMALN.PRECISE(4)", "4 处的伽马函数的自然对数"], ["=HYPGEOM.DIST(1,4,8,20,TRUE)", "累积超几何分布函数。"], ["=HYPGEOM.DIST(1,4,8,20,FALSE)", "概率超几何分布函数。"], ["=ISO.CEILING(4.3)", "将 4.3 向上舍入到最接近的 1 的倍数"], ["=ISO.CEILING(-4.3)", "将 -4.3 向上舍入到最接近的 1 的倍数"], ["=ISO.CEILING(4.3, 2)", "将 4.3 向上舍入到最接近的 2 的倍数"], ["=LOGNORM.DIST(4,3.5,1.2,TRUE)", "4 处的累积对数正态分布。"], ["=LOGNORM.DIST(4,3.5,1.2,FALSE)", "4 处的概率对数正态分布。"], ["=NEGBINOM.DIST(10,5,0.25,TRUE)", "累积负二项分布。"], ["=NEGBINOM.DIST(10,5,0.25,FALSE)", "概率负二项分布。"], ["=NETWORKDAYS.INTL(DATE(2006,1,1),DATE(2006,1,31))", "结果为 22 个未来工作日。从两个日期之间的 31 天总数中减去 9 个非工作日(5 个星期六和 4 个星期日)。默认情况下,星期六和星期日被视为非工作日。"], ["=NETWORKDAYS.INTL(DATE(2006,2,28),DATE(2006,1,31))", "结果为 -21,即过去的 21 个工作日。"], ["=NETWORKDAYS.INTL(DATE(2006,1,1),DATE(2006,2,1),7,{\"2006/1/2\",\"2006/1/16\"})", "通过从 2006 年 1 月 1 日到 2006 年 2 月 1 日的 32 天中减去 10 个非工作日(4 个星期五、4 个星期六、2 个节假日),结果为 22 个未来工作日。使用参数 7 表示周末,即星期五和星期六。此时间段内还有两个节假日。"], ["=NETWORKDAYS.INTL(DATE(2006,1,1),DATE(2006,2,1),\"0010001\",{\"2006/1/2\",\"2006/1/16\"})", "结果为 20 个未来工作日。与上面的时间段相同,但星期日和星期三为周末。"], ["=NORM.S.DIST(1.333333,TRUE)", "1.333333 处的正态累积分布函数。"], ["=NORM.S.DIST(1.333333,FALSE)", "1.333333 处的正态概率分布函数。"], ["=PERCENTRANK.EXC({1,2,3,4,6,6,7,8,9}, 7)", "返回数组中值 7 的排名。"], ["=PERCENTRANK.EXC({1,2,3,4,6,6,7,8,9}, 5.43)", "返回数组中值 5.43 的排名。"], ["=PERCENTRANK.EXC({1,2,3,4,6,6,7,8,9}, 5.43, 1)", "返回数组中值 5.43 的排名,结果中仅显示 1 位有效数字(默认值为 3)。"], ["=PERCENTILE.EXC({1,2,3,4,5,6}, 0.25)", "当指定百分位数的值位于数组中的两个值之间时进行插值。"], ["=QUARTILE.EXC({1,2,3,4,5,6,7,8,9,10,11},1)", "定位第一个四分位数的位置 (3)。"], ["=QUARTILE.EXC({1,2,3,4,5,6,7,8,9,10,11},3)", "定位第三个四分位数的位置 (9)。"], ["=RANK.AVG(95, {89, 88, 92, 101, 94, 97, 95})", "查找数组中值 95 的排名(位置)(降序)。在这种情况下,95 在降序中排名第 3。"], ["=RANK.AVG(95, {89, 88, 92, 101, 94, 97, 95}, 1)", "查找数组中值 95 的排名(位置)(升序)。在这种情况下,95 在升序中排名第 5。"], ["=T.DIST(60,1,TRUE)", "60 的学生左尾 t 分布,返回为累积分布函数,使用 1 个自由度。"], ["=T.DIST(8,3,FALSE)", "8 的学生左尾 t 分布,返回为概率密度函数,使用 3 个自由度。"], ["=T.INV(0.05464,60)", "基于指定参数的学生 t 分布的 t 值。"], ["=WORKDAY.INTL(DATE(2012,1,1),30,0)", "周末参数使用 0 会导致 #NUM! 错误。"], ["=WORKDAY.INTL(DATE(2012,1,1),90,11)", "从 2012 年 1 月 1 日起找到 90 个工作日后的日期,仅将星期日视为周末(周末参数为 11)。"], ["=TEXT(WORKDAY.INTL(DATE(2012,1,1),30,17), \"m/dd/yyyy\")", "使用 TEXT 函数将结果序列号 (40944) 格式化为 \"m/dd/yyyy\" 格式。从 2012 年 1 月 1 日起找到 30 个工作日后的日期,仅将星期六视为周末(周末参数为 17)。"] ]; sheet.setArray(0, 0, data, false); var r, len, i; for (r = 1, len = data.length; r < len; r++) { sheet.setFormula(r, 2, data[r][0]); } var arrayFormulaData = [ ["=MODE.MULT({1,2,3,4,3,2,1,2,1,3})", "该公式必须作为数组公式输入。它返回 1、2 和 3 作为众数,因为它们各出现 3 次。如果该公式不作为数组公式输入,则单个结果为 1。", 3] ]; for (i = 0, len = arrayFormulaData.length; i < len; i++) { var cur = arrayFormulaData[i], rows = cur[2], cols = cur[3] || 1; sheet.addSpan(r, 0, rows, 1); sheet.setValue(r, 0, cur[0]); sheet.addSpan(r, 1, rows, 1); sheet.setValue(r, 1, cur[1]); sheet.setArrayFormula(r, 2, rows, cols, cur[0]); r += rows; } for (i = 1; i < r; i++) { sheet.autoFitRow(i); } sheet.getRange(-1, 2, -1, 1).formatter(".######"); sheet.setFormatter(48, 2, "M/d/yyyy"); var table = sheet.tables.add("FunctionTable", 0, 0, 50, 3, spreadNS.Tables.TableThemes.medium9); table.rowFilter().filterButtonVisible(false); // Array formula with merge cells, set style like above table rows var rowStyle = sheet.getActualStyle(48, 0); sheet.getRange(50, 0, 3, 3).backColor(rowStyle.backColor); sheet.getRange(49, 0, 4, 3).setBorder(rowStyle.borderBottom, { all: true }); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="zh-cn" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"></div> </div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; overflow: hidden; float: left; border: 1px solid gray; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }