自定义单元格如何保持显示与编辑状态样式一致
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]