JavaScript整合SpreadJS业务功能实现案例(附源码)

在这里插入图片描述


更多相关内容可查看

SpreadJS 介绍

SpreadJS 是由美国 GrapeCity 公司开发的一款高性能、高度可定制的企业级电子表格组件。它可以让开发者在 Web 应用程序中嵌入 Excel 式的电子表格,并提供了丰富的 API 和事件,以便于进行深度定制和操作。

以下是 SpreadJS 的一些主要特性:

  1. Excel 兼容:SpreadJS 支持大部分的 Excel 功能,包括公式、排序、过滤、数据验证、条件格式、图表、撤销/重做等。

  2. 高性能:SpreadJS 使用了先进的数据处理和渲染技术,能够快速处理大量数据,并保持流畅的用户体验。

  3. 强大的 API:SpreadJS 提供了丰富的 API,开发者可以通过编程的方式来操作电子表格,包括单元格、行列、样式、公式等。

  4. 事件驱动:SpreadJS 提供了大量的事件,开发者可以监听和处理这些事件,以实现复杂的业务逻辑。

  5. 高度可定制:SpreadJS 提供了丰富的样式和主题设置,开发者可以定制电子表格的外观和行为。

  6. 多平台支持:SpreadJS 支持所有主流的浏览器和操作系统,包括桌面和移动设备。

  7. 国际化:SpreadJS 支持多种语言和地区设置,包括日期、数字、货币等格式。

  8. 无依赖:SpreadJS 是一个独立的 JavaScript 库,不依赖于任何其他库或框架。

总的来说,SpreadJS 是一款功能强大、性能高效、易于使用和定制的电子表格组件,非常适合用于构建复杂的数据分析和报表应用。

SpreadJS常用功能实现

SpreadJS 是一个强大的 JavaScript 电子表格组件,可以用于实现各种业务需求。以下是一些在工作中可能经常会遇到的 SpreadJS 需求及其代码实现:
当然,以下是一些更具体的 SpreadJS 功能需求和相应的代码实现:

当然,以下是一些更具体的 SpreadJS 功能需求和相应的代码实现:

冻结和解冻行列

冻结的行或列在滚动时始终可见。

// 冻结和解冻行列
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.frozenRowCount(1);  // 冻结第一行
sheet.frozenColumnCount(0);  // 解冻所有列

设置单元格边框

可以设置单元格的边框样式和颜色。

// 设置单元格边框
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var border = new GC.Spread.Sheets.LineBorder('red', GC.Spread.Sheets.LineStyle.medium);
sheet.getCell(0, 0).borderBottom(border);  // 设置第一格的底部边框

设置单元格格式

可以设置单元格的数字格式、日期格式等。

// 设置单元格格式
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.getCell(0, 0).formatter('0.00%');  // 设置第一格的格式为百分比格式

设置行高和列宽

可以设置行的高度和列的宽度。

// 设置行高和列宽
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.setColumnWidth(0, 100);  // 设置第一列的宽度为100像素
sheet.setRowHeight(0, 20);  // 设置第一行的高度为20像素

设置单元格样式

可以设置字体、颜色、背景色等样式。

// 设置单元格样式
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var style = new GC.Spread.Sheets.Style();
style.font = '20px Arial';
style.foreColor = 'red';
style.backColor = 'yellow';
sheet.setStyle(0, 0, style);  // 设置第一格的样式

插入图片

可以在单元格中插入图片。

// 插入图片
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var image = new Image();
image.src = 'image.jpg';
image.onload = function() {
  sheet.pictures.add('Picture1', image, 0, 0, 100, 100);  // 在第一格插入一个图片
};

打印设置

可以设置打印区域、页边距、页眉页脚等。

// 设置打印设置
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.printInfo().printArea('A1:B5');  // 设置打印区域为前5行的 'A' 列和 'B' 列
sheet.printInfo().headerLeft('Page &P');  // 设置页眉左侧为页码
sheet.printInfo().footerCenter('&D');  // 设置页脚中间为日期

保护工作表

可以设置工作表保护以防止用户修改数据。

// 保护工作表
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.options.isProtected = true;  // 保护工作表

数据导入和导出

SpreadJS 支持从各种来源导入数据,包括 JSON、Excel 文件等,也支持将数据导出为各种格式。

// 导入 Excel 文件
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var excelIO = new GC.Spread.Excel.IO();
var file = document.getElementById('file').files[0];
excelIO.open(file, function(json) {
  spread.fromJSON(json);
});

// 导出为 Excel 文件
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var excelIO = new GC.Spread.Excel.IO();
excelIO.save(spread.toJSON(), function(blob) {
  saveAs(blob, 'export.xlsx');
});

数据验证

SpreadJS 支持各种数据验证规则,可以确保用户输入的数据符合预期。

// 设置数据验证规则
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var validator = new GC.Spread.Sheets.DataValidation.createNumberValidator(
  GC.Spread.Sheets.DataValidation.ComparisonOperator.between, 1, 100
);
sheet.setDataValidator(0, 0, validator);

条件格式

SpreadJS 支持各种条件格式,可以根据单元格的值改变其样式。

// 设置条件格式
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var condition = new GC.Spread.Sheets.ConditionalFormatting.NormalCondition(
  GC.Spread.Sheets.ConditionalFormatting.ComparisonOperator.greaterThan, 50
);
var style = new GC.Spread.Sheets.Style();
style.backColor = 'red';
sheet.conditionalFormats.add(new GC.Spread.Sheets.ConditionalFormatting.CellValueRule(condition, style, 0, 0, 100, 100));

自定义函数

SpreadJS 支持自定义函数,可以实现复杂的计算需求。

// 添加自定义函数
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var customFunction = new GC.Spread.CalcEngine.Functions.Function('MYFUNC', function(args) {
  return args[0] * args[0];
});
spread.addCustomFunction(customFunction);
sheet.setFormula(0, 0, 'MYFUNC(5)');

合并单元格

在电子表格中,经常需要将多个单元格合并为一个单元格以显示更大的文本或标题。

// 合并单元格
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.addSpan(0, 0, 1, 2);  // 合并第一行的前两个单元格

添加过滤器

过滤器可以帮助用户更快地找到他们需要的数据。

// 添加过滤器
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.tables.add('Table1', 0, 0, 5, 5);  // 在前5行5列的区域添加一个表格
sheet.tables.findByName('Table1').filter(0, {values: ['Apple']});  // 在第一列添加一个过滤器,只显示值为 'Apple' 的行

创建图表

图表是一种直观的方式来显示数据。

// 创建图表
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
sheet.charts.add('Chart1', GC.Spread.Sheets.Charts.ChartType.column, 0, 0, 400, 300, 'A1:B5');  // 在前5行的 'A' 列和 'B' 列的数据基础上创建一个柱状图

添加注释

注释可以提供有关单元格内容的额外信息。

// 添加注释
var spread = new GC.Spread.Sheets.Workbook(document.getElementById('ss'));
var sheet = spread.getSheet(0);
var comment = new GC.Spread.Sheets.Comments.Comment();
comment.text('This is a comment.');
sheet.comments.add(0, 0, comment);  // 在第一格添加一个注释

后端装载 EXcel模板的Json格式,加载到前端界面

    @Override
    public void beforeBindData(EventObject e) {
        super.beforeBindData(e);
        //查询
        QFilter numberFilter = new QFilter("number","=","1");
        DynamicObject dynamicObject1 = BusinessDataServiceHelper.loadSingle("hifi_declarat_conf", "fid,xxx", new QFilter[]{numberFilter});
        Object hifiSpreadjsonTag = dynamicObject1.get("xxx");
        Object hifiTreejsonTag = dynamicObject1.get("xxx");
        //获取表单id
        String pageId = this.getView().getPageId();
        //放入自定义控件中
        CustomControl customControl = getControl(SpreadConstants.CUSTOM_CONTROL);
        Map<String, Object> paramsMap2 = new HashMap<>();
        paramsMap2.put("jsonTemp",hifiSpreadjsonTag);
        paramsMap2.put("treeJson",hifiTreejsonTag);
        paramsMap2.put("declare",true);
        paramsMap2.put("random", pageId);
        //传回前端并进行加载
        customControl.setData(paramsMap2);
    }
	
	 //控件初始化,只会触发一次,常用于控件渲染,资源文件加载
        init: function (props) {
            if (props.data) {
                props.data.action = "INIT_CODE_HTML";

            } else {
                var paramsMap = new Object();
                paramsMap["action"] = "INIT_CODE_HTML";
                props.data = paramsMap;
            }
            setHtml(this.model, props);

        },

    function setHtml(model, props) {

        //加载CSS
        var jsArray = ['./js/gc.spread.sheets.charts.16.2.2.min.js', './js/gc.spread.sheets.shapes.16.2.2.min.js', './js/gc.spread.sheets.print.16.2.2.min.js'
            , './js/gc.spread.sheets.barcode.16.2.2.min.js', './js/gc.spread.sheets.pdf.16.2.2.min.js', './js/gc.spread.pivot.pivottables.16.2.2.min.js',
            './js/gc.spread.sheets.formulapanel.16.2.2.min.js', './js/gc.spread.sheets.io.16.2.2.min.js', './js/gc.spread.excelio.16.2.2.min.js', './js/gc.spread.sheets.resources.zh.16.2.2.min.js', './js/gc.spread.sheets.designer.resource.cn.16.2.2.min.js', './js/gc.spread.sheets.designer.all.16.2.2.min.js', './js/jquery-ui-1.9.1.custom.min.js'];

        var firstJsArray = ['./js/jstree/dist/jstree.min.js', './js/gc.spread.sheets.all.min.js', './js/pinyin4js.js', './js/FileSaver.js']
        var cssArray = ['./css/gc.spread.sheets.excel2013white.16.2.2.css', './css/gc.spread.sheets.designer.16.2.2.min.css', './css/custom.css', './css/dist/themes/default/style.min.css', './css/bootstrap.min.css', './css/font-awesome.min.css'];
        KDApi.loadFile(cssArray, model, () => {
            KDApi.loadFile(firstJsArray, model, function () {
                KDApi.loadFile(jsArray, model, function () {
                    KDApi.getTemplateStringByFilePath('./html/template.html', model, {

                        //传递给模板的参数
                        id: props.data.random,
                        // draftIcon:KDApi.nameSpace(model) + './img/draft.png',
                        // taskIcon:KDApi.nameSpace(model) + './img/todo.png',
                        // signIcon:KDApi.nameSpace(model) + './img/sign.png',
                        // saveIcon:KDApi.nameSpace(model) + './img/save.png',
                    }).then(async result => {

                        //挂载页面模板
                        model.dom.innerHTML = result
                        var spread = initSpread(model, props.data);
                    })
                })
            })
        })

设置为下拉格式

	 var style = new GC.Spread.Sheets.Style();
         style.cellButtons = [
             {
                 imageType: GC.Spread.Sheets.ButtonImageType.dropdown,
                 command: "openList",
                 useButtonStyle: true,
             }
         ];
         style.dropDowns = [
             {
                 type: GC.Spread.Sheets.DropDownType.list,
                 option: {
                     items: [
                         {
                             text: 'text1',
                             value: 'value1'
                         },
                         {
                             text: 'text2',
                             value: 'value2'
                         },
                         {
                             text: 'text3',
                             value: 'value3'
                         },
                         {
                             text: 'text4',
                             value: 'value4'
                         }
                     ],
                 }
             }
         ];
		 

读取单元格数据、某行数据、单元格公式

		    $("#helloText").click(function (){
            spreadcOM = model.spread;
            var formulaMap = new Map();
            for (var s = 0; s < spreadcOM.getSheetCount(); s++) {
                var sheet = spreadcOM.getSheet(s);
                for (var i = 0; i < sheet.getRowCount(); i++) {
                    for (var j = 0; j < sheet.getColumnCount(); j++) {
                        //获取单元格公式
                        var formula = sheet.getFormula(i, j);
                        //获取单元格数据
                        var value = sheet.getValue(i,j);
                        //获取行数据
                        var valueRow = sheet.getArray(i,j,1,sheet.getColumnCount())
                        if (formula && formula != null) {
                            if (textRegex.test(formula)) {
                                formulaMap.set(s + "_" + i + "_" + j, formula+'/'+value+'/'+valueRow)
                            }
                        }
                    }
                }
            }
            let formulaArray = Array.from(formulaMap);
            var serializationOption = {
                ignoreFormula: false, 
            }
            var jsonString = JSON.stringify(spreadcOM.toJSON(serializationOption));
            var ss = model.invoke("hello", { excelJson: jsonString, formulaArray: formulaArray })
        })
		
	//后端接收
	@Override
    public void customEvent(CustomEventArgs e) {

        super.customEvent(e);
        String key = e.getKey();
        if (SpreadConstants.CUSTOM_CONTROL.equals(key)) {
            //calc计算事件
            String eventName = e.getEventName();
            if("hello".equalsIgnoreCase(eventName))
            {
                getValuesT(e);
            }
        }
    }		 

设置隐藏/显示某个sheet

		$("#visibleFalse").click(function () {
            var sheet = spreadcOM.getSheet(0)
            sheet.visible(false);
        })
        $("#visibleTrue").click(function () {
            var sheet = spreadcOM.getSheet(0)
            sheet.visible(true);
        })

监听新增行事件

		    sheet.bind(GC.Spread.Sheets.Events.RowChanged, function (e, info) {
            var flag = info.propertyName;
            if(flag == "addRows")
            {
                var ss = model.invoke("addRows")
            }

监听单元格值改变,触发 另一个单元格

		    sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) {
            var newValue = info.newValue;
            if(newValue == "value2")
            {
                valueChanged(sheet,true);
            }else{
                valueChanged(sheet,false);
            }
    
		
	function valueChanged(sheet,status){
        var person = { name: '李四', age: 24, sex: '男', address: { postcode: '123456789' } };
        var source = new GC.Spread.Sheets.Bindings.CellBindingSource(person);
        sheet.setBindingPath(2, 1, 'name');
        sheet.setBindingPath(3, 1, 'age');
        sheet.setBindingPath(4, 1, 'sex');
        sheet.setBindingPath(5, 1, 'address.postcode');
        sheet.setDataSource(source);
        if(status == false)
        {
            sheet.setBindingPath(2, 1, null)
            sheet.setBindingPath(3, 1, null)
            sheet.setBindingPath(4, 1, null)
            sheet.setBindingPath(5, 1, null)
            sheet.setDataSource(source);
        }
    }

设定某列,某单元锁定

	    $("#editLockD").click(function () {
            var sheet = spreadcOM.getSheet(0)
            sheet.getRange(0,0,1,1).locked(true);
            sheet.getRange(0,1,1,1).locked(false);
            sheet.options.isProtected = true;
        })
        $("#editLockR").click(function () {
            var sheet = spreadcOM.getSheet(0)
            sheet.getRange(0,0,sheet.getRowCount,1).locked(true);
            sheet.options.isProtected = true;
        })

状态栏显示

	   var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(
            document.getElementById('statusBar' + data.random)
        );
        statusBar.bind(spreadcOM);

设置角标按钮

	<button id="addButton">添加角标</button>
	<select id="colorSelect">
  		<option value="green">绿色</option>
  		<option value="red">红色</option>
	</select>
<div id="ss" style="width:600px;height:400px;border:1px solid gray"></div>

<script>
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), {sheetCount: 1});
var sheet = spread.getSheet(0);

document.getElementById("addButton").addEventListener("click", function() {
    var cell = sheet.getActiveCell();
    var colorSelect = document.getElementById("colorSelect");
    var color = colorSelect.options[colorSelect.selectedIndex].value;
    var text = color === "green" ? "XX" : "YY";

    var style = new GC.Spread.Sheets.Style();
    style.cellButtons = [
        {
            buttonBackColor: color,
            text: text,
            buttonBorderColor: "black",
            width: 15,
            height: 15,
        }
    ];
    sheet.setStyle(cell.row, cell.col, style);
});
</script>

超链接跳转

<button id="addHyperlink">添加超链接</button>
<label for="linkText">链接文本:</label>
<input type="text" id="linkText" name="linkText">
<label for="linkSheet">目标工作表:</label>
<input type="text" id="linkSheet" name="linkSheet">
<div id="ss" style="width:600px;height:400px;border:1px solid gray"></div>

<script>
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), {sheetCount: 2});
var sheet1 = spread.getSheet(0);
var sheet2 = spread.getSheet(1);

// 设置第二个工作表的名称
sheet2.name("目标工作表");

document.getElementById("addHyperlink").addEventListener("click", function() {
    var cell = sheet1.getActiveCell();
    var linkText = document.getElementById("linkText").value;
    var linkSheet = document.getElementById("linkSheet").value;
    var hyperlink = new GC.Spread.Sheets.HyperLink();
    hyperlink.linkToolTip("点击跳转到" + linkSheet);
    hyperlink.text(linkText);
    hyperlink.linkType(GC.Spread.Sheets.HyperLink.LinkType.worksheet);
    hyperlink.linkAddress(linkSheet);
    sheet1.setHyperlink(cell.row, cell.col, hyperlink);
});
</script>
  • 35
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来一杯龙舌兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值