Clark.Pan 发表于 2020-8-3 10:45:15

自定义单元格如何保持显示与编辑状态样式一致

       SpreadJS中的自定义单元格作为SpreadJS中高阶的应用,本身是非常灵活的,但灵活程度与难度也是成正比的,善用自定义单元格的小伙伴能够做出很多非常炫酷超越Excel的表格效果,例如Datapicker,Autocomplete ,弹出框,多选等。但由于SpreadJS外部是用canvas渲染,进入编辑状态后编辑状态是dom结构组成。两者经常会遇到样式不一致的情况,并且在调整样式一致的时候由于canvas和dom的原理不同,很难调整成一致的显示。这会与精益求精的IT从业者来说是不可接受的。现在我们可以巧妙的利用svg的图片形式在完美的完成在html dom 与canvas中显示效果的转换。       例如下面例子,如果想要进入编辑状态的时候显示效果与外面canvas保持一致就要用到svg进行中间转换。

       首先,我们在createEditorElement中绘制了编辑状态的方框
       ContinuousBoxCellType.prototype.createEditorElement = function () {
            var div = document.createElement("div");
            div.setAttribute("gcUIElement", "gcEditingInput");
            div.style.backgroundColor= "white";
            div.style.overflow= "hidden";
                        div.innerHTML = '<input style="margin-top:2px;display:block;float:left;height:10px;font-size:10px;line-height:10px;width:10px;text-align:center;margin-left:1px;border:1px solid #999"/>'
                              + '<input style="margin-top:2px;display:block;float:left;height:10px;font-size:10px;line-height:10px;width:10px;text-align:center;margin-left:3px;border:1px solid #999"/>'
                              + '<input style="margin-top:2px;display:block;float:left;height:10px;font-size:10px;line-height:10px;width:10px;text-align:center;margin-left:3px;border:1px solid #999"/>'
                              + '<input style="margin-top:2px;display:block;float:left;height:10px;font-size:10px;line-height:10px;width:10px;text-align:center;margin-left:3px;border:1px solid #999"/>';
                        
                        return div;
      };          之后paint方法中将editor中的html转成svg,然后通过cavans的图片绘制将svg图片绘制在页面上
ContinuousBoxCellType.prototype.paint = function (ctx, value, x, y, w, h, style, context) {
                        var DOMURL = window.URL || window.webkitURL || window;
                        var cell = context.sheet.getCell(context.row, context.col);
                        var img = cell.tag();
                        if (img) {
                              try{
                                        ctx.save();
                                        ctx.rect(x, y, w, h);
                                        ctx.clip();
                                        ctx.drawImage(img, x + 2, y + 2)
                                        ctx.restore();
                                        cell.tag(null);
                                        return;
                              } catch(err){
                                        GC.Spread.Sheets.CustomCellType.prototype.paint.apply(this, )
                                        cell.tag(null);
                                        return;
                              }
                        }
                        var svgPattern = '<svg xmlns="http://www.w3.org/2000/svg" width="{0}" height="{1}">' +
                        '<foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="font:{2}">'+this.html+'</div></foreignObject></svg>';

                        var data = svgPattern.replace("{0}", w).replace("{1}", h).replace("{2}", style.font).replace("{3}", value.toString()==null?"":value.toString()).replace("{4}", value.toString()==null?"":value.toString()).replace("{5}", value.toString()==null?"":value.toString()).replace("{6}", value.toString()==null?"":value.toString());
                        var doc = document.implementation.createHTMLDocument("");
                        doc.write(data);
                        // Get well-formed markup
                        data = (new XMLSerializer()).serializeToString(doc.body.children);

                        img = new Image();
                        //var svg = new Blob(, {type: 'image/svg+xml;charset=utf-8'});
                        //var url = DOMURL.createObjectURL(svg);
                        //img.src = url;
                        img.src = 'data:image/svg+xml;base64,'+window.btoa(data);
                        cell.tag(img);
                        img.onload = function () {
                              context.sheet.repaint(new GC.Spread.Sheets.Rect(x, y, w, h));
                        }
                        
      };
这样就实现了编辑与展示一致的效果,详情可以见附件demo



页: [1]
查看完整版本: 自定义单元格如何保持显示与编辑状态样式一致