详解电子表格中的json数据:序列化与反序列化
从XML到JSON
当下应用开发常见的B/S架构之下,我们会遇到很多需要进行前后端数据传输的场景。而在这个传输的过程中,数据通过何种格式传输、方式是否迅速便捷、书写方式是否简单易学,都成为了程序员在开发时要考量的问题。
在1996年,W3C(World Wide Web Consortium,万维网联盟)正式公布了XML1.0标准,
XML采用标准格式为基于Web的应用提供了一个统一进行数据描述和数据交换的标准,不同于HTML侧重于解决":如何将文件显示在浏览器中",XML更加侧重于解决:"如何将数据以结构化方式描述"。
(需要注意的是,XML并不是一种编程语言,而是一种跨语言的数据格式。)
XML本身并不复杂,但是加上W3C制定的DTD、XSD、XPath、XSLT等二十多个标准之后,这个简单的数据交换格式平白变得复杂了起来。程序员但凡遇到,只能头大。苦心孤诣研究大半个月,也不好轻言自己全部清楚了。

而此时,推动着技术前进的另一台蒸汽机也被点燃——Ajax技术开始流行,映衬出XML越来越不容忽视的缺点。XML得以实现是基于DOM树,而DOM在各种浏览器中的实现细节不尽相同,所以XML的跨浏览器兼容性并不好,这时需要一种新的数据负载格式集成到HTML页面中,以满足Ajax的要求。
终于,在XML诞生后的第八年——2002年,由Douglas Crockford开始使用JSON这种轻量级数据交换格式。
首条JSON信息发出后,最让人们惊讶的是,这并不是一个全新的数据格式,它就是JavaScript。

document.domain = 'fudco';parent.session.receive( { to: "session", do: "test", text: "Hello world" } )
而由于这条数据内容本身就是JavaScript,因此不再需要做任何额外解析,使用JS编译器就可以解决一切。
由于JSON非常简单,很快就风靡Web世界,并且成为ECMA标准。几乎所有编程语言都有解析JSON的库,而在JavaScript中,我们可以直接使用JSON,因为JavaScript内置了JSON的解析。把JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。
Json的序列化和反序列化
正如一道菜做好后,需要装在盘子里端给顾客,前后端的数据传输也是如此。数据通过指定格式,将传输的对象序列化为二进制数据流,然后再通过反序列化将数据流内容转化成为对应的数据对象。

JSON中的数据形式与转化方式
在JSON中,数据有以下几种形式:
- 对象:一个没有顺序的"键/值",格式如

- 数组:用以设置数值顺序,格式如

- 字符串:任意数量的Unicode字符,格式如

进行数据序列化和反序列化的方式有以下三种:
- 使用JavaScriptSerializer类
- 使用DataContractJsonSerializer类
- 使用JSON.NET类库
以JavaScriptSerializer类为例,
//创建用户列表
List<UserInfo> userList = new List<UserInfo>();
userList.Add(new UserInfo() { ID = 1, Name = "张三", CreateTime = DateTime.Now });
userList.Add(new UserInfo() { ID = 2, Name = "李四", CreateTime = DateTime.Now });
userList.Add(new UserInfo() { ID = 2, Name = "王五" });
//创建一个JavaScriptSerializer对象
JavaScriptSerializer serializer = new JavaScriptSerializer();
//将用户列表序列化成JSON
string serializedResult = serializer.Serialize(userList);
//将JOSN反序列化成用户列表
List<UserInfo> deserializeResult = serializer.Deserialize<List<UserInfo>>(serializedResult);
只需要调用对应方法,就可以直接实现对数据内容的序列化。
你以为到这里就结束了吗,当然没有。在实际应用中,数据本身的处理并没有什么难度,真正需要考虑解决的问题是,数据本身附加的属性、设置。就以我们自身为例,客户在纯前端电子表格中对JSON数据传输的真实需求是,这段数据需要保证所有可视化内容的完整传输。
纯前端表格中的JSON数据处理
在实际处理用户需求时,用户在设置好如下图单元格后,不仅仅是单元格内存在数字,还会遇到单元格本身的样式、自定义函数、 自定义格式、自定义函数迷你图、自定义标签,以及自定义行筛选。

我们打开相关的代码,可以清楚地看到在格式中这些对单元格的设置,都被保存了下来。


在这个图中,我们可以看到不同类型的数据内容都可以完成序列化和反序列化的过程。在使用自定义序列化的过程中,查看相关代码,处理序列化的核心是typeName 字段在调用toJSON函数的过程,比如,可以将此类姓名和window对象联系。而反序列化时,调用 getTypeFromString 函数来获取类型名并且构造类型实例对象,然后调用类型实例上的 fromJSON方法。

此外还有许多其他的属性内容,下面列举其他样式设置的例子:
背景图片:
//这个例子设置了backgroundImageLayout属性。
var style = new GC.Spread.Sheets.Style();
style.backColor = "lightgreen";
style.backgroundImage = "/css/images/quarter1.png";
style.backgroundImageLayout = GC.Spread.Sheets.ImageLayout.center;
activeSheet.setStyle(1,1,style,GC.Spread.Sheets.SheetArea.viewport);
水印设置:
//此示例设置水印的单元格填充。
var type = new GC.Spread.Sheets.Style();
type.watermark = "User name";
type.cellPadding = "20";
type.labelOptions = {alignment:GC.Spread.Sheets.LabelAlignment.topLeft, visibility: GC.Spread.Sheets.LabelVisibility.visible};
activeSheet.setStyle(0, 1, type);
activeSheet.getRange(0, -1, 1, -1, GC.Spread.Sheets.SheetArea.viewport).height(60);
activeSheet.getRange(-1, 1, -1, 1).width(150);
var combo = new GC.Spread.Sheets.CellTypes.ComboBox();
combo.items([{ text: "Oranges", value: "11k" }, { text: "Apples", value: "15k" }, { text: "Grape", value: "100k" }]);
combo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text);
activeSheet.setCellType(2, 1, combo, GC.Spread.Sheets.SheetArea.viewport);
activeSheet.getCell(2, 1, GC.Spread.Sheets.SheetArea.viewport).watermark("ComboBox Cell Type").cellPadding('10 10 20 10');
activeSheet.getCell(2, 1, GC.Spread.Sheets.SheetArea.viewport).labelOptions({alignment: GC.Spread.Sheets.LabelAlignment.bottomCenter, foreColor: 'yellowgreen', font: 'bold 15px Arial'});
activeSheet.getRange(2, -1, 1, -1, GC.Spread.Sheets.SheetArea.viewport).height(60);
主题字体:
//这个例子使用了themeFont属性。
var style = new GC.Spread.Sheets.Style();
style.formatter = "0.000%";
style.themeFont = "Body";
activeSheet.setStyle(1,1,style,GC.Spread.Sheets.SheetArea.viewport);
activeSheet.getCell(1,1).value("11");
还有许多对于单元格的设置,这些样式内容都可以被完整保存下来,作为json数据进行传输,带来真正的表格json数据传输的便利。
使用过程中需要注意以下问题:
- 给 typeName 字段设置完整的类型名字符串(如果有命名空间也应包含命名空间)。
- 如果自定义类型有循环依赖或是你希望减小JSON 数据的大小,亦或是你有其他更高级的需求,那么你的自定义类型需要重写toJSON和fromJSON方法。
- 如果自定义类型定义在一个闭包中,换句话说,你不希望将自定义类型定义在 window 对象上,你需要重写 getTypeFromString 函数来手动解析类型的字符串。
代码示例:
GC.Spread.Sheets.getTypeFromString = function(typeString) {
switch (typeString) {
case "MyFormatter":
return MyFormatter;
case "MyRowFilter":
return MyRowFilter;
default:
return oldFun.apply(this, arguments);
}
};
MyTag.prototype.toJSON = function() {
return {
typeName: this.typeName, //necessary
name: this.name,
age: this.age
};
};
MyTag.prototype.fromJSON = function(settings) {
if (settings.name !== undefined) {
this.name = settings.name;
}
if (settings.age !== undefined) {
this.age = settings.age;
}
};
总结
本文详细为大家介绍了数据传输从XML到JSON的故事,以及json进行序列化和反序列化的工作原理,同时带大家了解了在前端电子表格中要想完全实现整个内容的数据序列化和反序列化应该如何做。

后续也会为大家带来更多有趣或者严肃的内容~
觉得不错,点个赞再走吧。
详解电子表格中的json数据:序列化与反序列化的更多相关文章
- C#中的Json的序列化和反序列化
Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...
- 详解Google-ProtoBuf中结构化数据的编码
本文的主要内容是google protobuf中序列化数据时用到的编码规则,但是,介绍具体的编码规则之前,我觉得有必要先简单介绍一下google protobuf.因此,本文首先会介绍一些google ...
- 在C#中,Json的序列化和反序列化的几种方式总结
在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...
- 在MVC中使用Json.Net序列化和反序列化Json对象
在.Net的MVC开发中,经常会使用到Json对象,于是,系统提供了JsonResult这个对象,其本质是调用.Net系统自带的Json序列化类JavaScriptSerializer对数据对象进行序 ...
- 在C#中,Json的序列化和反序列化的几种方式总结 转载
转载自 https://www.cnblogs.com/caofangsheng/p/5687994.html 谢谢 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据 ...
- C#中,Json的序列化和反序列化的几种方式总结
在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...
- 在C#中,Json的序列化和反序列化的几种方式
摘自:http://www.cnblogs.com/caofangsheng/p/5687994.html 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化 ...
- 在C#中实现Json的序列化与反序列化
第一种方式利用 JavaScriptSerializer [对应的Assembly 为 System.Web.Extensions.dll] 进行处理: public static class Kas ...
- 详解javaweb中jstl如何循环List中的Map数据_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 详解javaweb中jstl如何循环List中的Map数据 第一种方式: 1:后台代码(测试) List<Map& ...
随机推荐
- Springboot2.0整合Redis(注解开发)
一. pom.xm文件引入对应jar包 <dependency> <groupId>org.springframework.boot</groupId> <a ...
- IDEA连接Mysql数据库之后,在Mapper.xml编写SQL时不会自动提示表信息问题(非常详细!)
1.首先得连接上数据库 (一)点击IDEA右侧数据库模块 (二)选择MySql进行连接 (三)填写数据库相关配置 (四)重点!!! 这个时候点击测试连接是连接不上的,需要设置时区 (按照如下设置) ( ...
- 拥抱开源,共建生态 - 开源生态与效能提升专场 | CIF 精彩看点
随着软件技术日新月异的发展,GitHub 已经进化成为人类软件的基因库,遇到问题第一时间在 GitHub 上寻求合适的解决方案,已经逐渐变成工程师处理问题的常见方法.据 GitHub 年度报告显示,2 ...
- CEF使用过程问题合集
CEF使用过程问题合集 1.Couldn't mmap icu data file 解决方案:检查程序执行目录下是否有icudtl.dat文件,如果没有请从cef的Resources文件夹中复制一份. ...
- Oracle数据泵数据迁移
1 表空间查询 1.1 检查用户与表空间对应情况 select username,default_tablespace from dba_users; 1.2 查看临时表空间 select ta ...
- linux下nginx编译安装、版本信息修改
环境 centos 7 安装依赖包 yum install -y gcc gcc-c++ glibc glibc-devel pcre pcre-devel zlib zlib-devel opens ...
- Vue3学习(八)之 Vue CLI多环境配置
一.前言 这里相对于之前就没那么麻烦了,通俗点说就是使用配置文件来管理多环境,实现环境的切换. 二.实现切换 1.增加开发和生产配置文件 在web的根目录下,创建开发环境切换配置文件.env.dev, ...
- SpringCloud微服务实战——搭建企业级开发框架(五):数据库持久化集成MySql+Druid+MyBatis-Plus
在引入相关数据库持久化相关依赖库之前,我们可以考虑到,当我们因业务开发需要,引入各种各样的依赖库时,Jar包冲突是我们必须面对的一个问题,Spring为了解决这些Jar包的冲突,推出了各种bom, ...
- 第五课第四周笔记4:Transformer Network变压器网络
Transformer Network变压器网络 你已经了解了 self attention,你已经了解了 multi headed attention.在这个视频中,让我们把它们放在一起来构建一个变 ...
- 基于自定义Validator来验证枚举类型
基于自定义Validator来验证枚举类型 一.背景 二.技术要点 三.实现一个自定义枚举校验. 1.需求. 2.实现步骤 1.自定义一个 Sex 枚举. 2.自定义一个 Enum 注解 3.编写具体 ...