基于“五步实现系统主页面”系列文章:
- 《ComponentOne 2013v2.5 Winforms,五步实现一个系统主页面》
- 《ComponentOne 2013v2.5 Asp.net Wijmo,五步实现一个Web系统主页面》
- 《ComponentOne Studio® for Silverlight,五步实现一个RIA系统主页面》
- 《Spread for WinForms,五步实现一个数据处理系统主界面》
本文实现了一个Spread版数据分析系统主页面的简单原型。
在构建以数据分析为核心的系统中,有很多关键环节需注意。如,在控件套装的选型和评估中,务必要考虑3个关键业务需求环节:
- 数据录入:表单数据逐条录入数据、Excel批量导入数据、在线编辑修改数据
- 数据分析:类似Excel模板公式数据分析、类似Excel图表数据分析
- 数据导出:PDF格式、Excel格式、CSV格式等
- 基于此,本文选择了
- 表格产品来构建原型系统:
- 1
全球销量第一的表格控件,全面的中文化
- :使得系统更加符合中国的国内市场:开发人员和一线用户
- 2
类似Excel的强大功能
- : 全面兼容Excel的操作方式,非常符合数据分析行业从业人员的习惯,系统易用性好
- 3
可视化设计器
- :极大的方便了二次开发和业务需求人员进行无损的原型设计--业务人员设计UI后存储为XML,开发人员针对XML二次实现数据读取、呈现、持久化,极大的提高了研发各个环节的沟通效能。
开发环境:
1. Window 7 64位英文系统
2. Visual Studio 2012 SP3 英文版 (C#.net) .NetFramework 4.0 (注: Visual Studio 2010可用源码)
3. Spread for WinForms 全球销量第一的表格控件,类似Excel的强大功能
原型系统采用左侧导航菜单,其中分为5个模块进行呈现业务:
- 报表设计器
- 财务报表操作
- 2D图表呈现
- Excel数据导入
- 信息查询表单
Step 1: 报表设计器
Spread是世界上最强大、最畅销的.NET表格控件,它提供了灵活开放的对象模型和50,000个以上的API,使得用户拥有定制几乎所有元素和接口的能力。开发人员通过将Spread表格控件嵌入到.NET应用程序中,可以实现Microsoft Excel的绝大部分功能。
Spread设计器用来设计并快速创建一个表单原型。通过其直观、易用的界面,在设计阶段对表单的外观进行定制,从而缩短开发时间。 Spread 设计器可为表单创建一个快照。当所有的更改完成后,所有可直接应用于工作表单。
Spread 设计器支持打开已有设计文件并将设计更改保存为文件。
针对开发人员超乎想象的便捷,点击按钮,打开报表设计器,仅仅2行代码:
1: private void button1_Click(object sender, EventArgs e)
2: {
3: FarPoint.Win.Spread.Design.FpSpreadDesigner design = new FarPoint.Win.Spread.Design.FpSpreadDesigner();
4: design.ShowDialog(this.fpSpread1);
5: }
Step 2: 财务报表操作
为表��增加一个上下文菜单, 通过ContextMenu属性可创建一个ContextMenu, 通过右键菜单可实现很多实用的功能场景,详情见下截图:
支持自定义丰富的单元格类型。通过用Spread提供的单元格类型或定制自己的类型,确定在一个单元格中可以输入什么样的数据、避免程序员不必要的检查和验证,并为用户提供一种自然的输入数据的方式
- 货币
- 日期-时间型
- 普通型
- Mask型
- 数值型
- 百分比型
- 常规表达式型
- 文本型
- 开关型
- 按钮型
- 复选框型
- 组合框型
- 超链接型
- 图形型
- 多选项型
- 进度指示条形
- Rich Text型
- 滑块型
注:为了快速呈现原型系统,这里仅列举出了5种数据类型。
改变数据类型代码示例:
1: private void SetCellType(string menuText)
2: {
3:
4: BaseCellType baseType = null;
5: switch (menuText)
6: {
7: case "单元格类型":
8: break;
9: case "数字类型":
10: {
11: FarPoint.Win.Spread.CellType.NumberCellType objNumCell = new FarPoint.Win.Spread.CellType.NumberCellType();
12: objNumCell.DecimalPlaces = 0;
13: objNumCell.MinimumValue = 1;
14: objNumCell.MaximumValue = 9999;
15: objNumCell.ShowSeparator = false;
16: baseType = objNumCell;
17: }
18: break;
19: case "日期类型":
20: {
21: FarPoint.Win.Spread.CellType.DateTimeCellType objDateCell = new FarPoint.Win.Spread.CellType.DateTimeCellType();
22: objDateCell.DateTimeFormat = FarPoint.Win.Spread.CellType.DateTimeFormat.ShortDate;
23: baseType = objDateCell;
24: }
25: break;
26: case "文本类型":
27: {
28: FarPoint.Win.Spread.CellType.TextCellType objTextCell = new FarPoint.Win.Spread.CellType.TextCellType();
29: objTextCell.MaxLength = 100;
30: baseType = objTextCell;
31: }
32: break;
33: case "单选框类型":
34: {
35: FarPoint.Win.Spread.CellType.CheckBoxCellType objCheckCell = new FarPoint.Win.Spread.CellType.CheckBoxCellType();
36: objCheckCell.ThreeState = false;
37: baseType = objCheckCell;
38: }
39: break;
40: case "货币类型":
41: {
42: FarPoint.Win.Spread.CellType.CurrencyCellType objCurrCell = new FarPoint.Win.Spread.CellType.CurrencyCellType();
43: objCurrCell.LeadingZero = FarPoint.Win.Spread.CellType.LeadingZero.Yes;
44: objCurrCell.NegativeRed = true;
45: objCurrCell.FixedPoint = true;
46: baseType = objCurrCell;
47: }
48: break;
49: default:
50: break;
51: }
52:
53:
54: if (baseType != null)
55: {
56: fpSpread1.ActiveSheet.ActiveCell.CellType = baseType;
57: }
58: }
Step 3: 2D图表呈现
Spread支持85种丰富多彩的图表效果。可以在Spread设计器中基于工作表的数据直接生成图表,操作简单。同时,软件人员还可以在Visual Studio设计环境中定制图表的所有元素,包括标题、序列、轴、样式、图例等。
图表的生成有2种途径
方法一:通过Spread设计器,类似Excel插入图表功能,非常易上手
方法二:通过代码实现,仅需要2步
1 选择数据区域Range
2 插入指定类型的图表:起始x、y坐标,宽度和高度
图表代码生成代码示例:
1: FarPoint.Win.Spread.Model.CellRange range = new CellRange(38, 2, 5, 4);
2: fpSpread1.Sheets[0].AddChart(range, typeof(BarSeries), 600, 300, 0, 0, ChartViewType.View2D, true);
3:
4: fpSpread1.Sheets[0].AddChart(range, typeof(FarPoint.Win.Chart.XYLineSeries), 600, 300, 0, 350, ChartViewType.View2D, true);
5:
Step 4: Excel数据导入
在数据处理系统中,有相当大的一块是做数据采集的,除了固定格式、海量数据可以通过采集系统程序采集外,其他配置数据、工程数据大多需要人工录入系统,但是手工一条一条录入有2点门槛:
- 系统数据录入权限:数据系统对数据来源要求安全、质量很高,故录入数据权限不是100%开放所有用户
- 手工录入数据效率低
故业内默认的行规是:批量数据录入是采用Excel模板,通过系统提供的Excel导入功能实现批量数据录入。
Spread会独立安装Excel文件格式的输入输出引擎,在没有安装Excel的环境中也可以进行Excel文件格式的输入输出,开发时设计的图表、图形、图像等都会作为对象输出到Excel文件中。Spread提供多种版本的Excel和多种文件类型的导入导出服务,包括Excel文件(XLS、XLSX)、档案文件(CSV)和文本文件(TXT)。
导入文件类型:
- Spread XML 文件
- Excel(.xls)文件
- Spread 文件
- 文本文件
- Excel数据导入有2个系统分界线:
- 1 Excel文件到内存: 复杂度大、数据校验、Excel文件格式不同等等,难度较大。 约占开发工作量的60%
- 2 内存到业务数据库:一旦到内存中,对开发者来说就如鱼得水了。约占开发工作量的30%~40%
- 本文所说的Spread实现的数据导入,能够实现Excel文件到内存,也就是Excel数据预览功能,后续实现导入的业务逻辑代码,依据不同行业库表规则,写SQL实现insert即可。
- 代码就一行:
1: this.fpSpread1.OpenExcel(ExcelFullPath);
2:
Step 5: 信息查询表单
复杂数据录入界面,通过Spread设计器实现复杂商业文档的录入界面,比如复杂的订单、发票、保单、报税表等。本文模拟量一个查询条件的查找表单,其中用到了本周新介绍的《Spread 7 for WinForms 新增的GcTextBoxCellType (水印、自动换行、自动大写、长度限制等)》单元格类型,非常实用。
表单是通过Spread 设计器设计好:背景、颜色、单元格类型、图片、按钮等等。然后保存为XML格式,在程序中通过两行代码加载实现的:
1: string fullPath = AppDomain.CurrentDomain.BaseDirectory + "..\\..\\ChartSpread.xml";
2: this.fpSpread1.Open(fullPath);
为了实现按回车进行查询功能,自定义了一个Action:
1: public class ClickButtonAction : FarPoint.Win.Spread.Action
2: {
3: public DataInputSpread mChartSpread;
4: public override void PerformAction(object source)
5: {
6: if (source is SpreadView)
7: {
8: SpreadView spreadView = (SpreadView)source;
9: mChartSpread.fpSpread1_ButtonClicked(spreadView, null);
10: }
11: }
12: }
13:
14: this.fpSpread1.ButtonClicked += fpSpread1_ButtonClicked;
15:
16: InputMap im = fpSpread1.GetInputMap(InputMapMode.WhenFocused);
17: ActionMap am = fpSpread1.GetActionMap();
18: im.Put(new Keystroke(Keys.Enter, Keys.None), "ClickButtonAction");
19: am.Put("ClickButtonAction", new ClickButtonAction() { mChartSpread = this });
20:
21: public void fpSpread1_ButtonClicked(object sender, EditorNotifyEventArgs e)
22: {
23: FarPoint.Win.Spread.SheetView sheet1;
24: if (sender is FarPoint.Win.Spread.FpSpread)
25: {
26: sheet1 = (sender as FarPoint.Win.Spread.FpSpread).Sheets[1];
27: }
28: else
29: {
30: sheet1 = (sender as FarPoint.Win.Spread.SpreadView).Sheets[1];
31: }
32:
33: string name = sheet1.Cells["name"].Text;
34: string phone = sheet1.Cells["phone"].Text;
35: string date = sheet1.Cells["date"].Text;
36: string sex = sheet1.Cells["sex"].Text;
37:
38: string msg = string.Format("搜索内容 姓名:{0}, 电话:{1}, 日期: {2}, 性别: {3}", name, phone, date, sex);
39: if (e != null)
40: {
41: msg = string.Format("{0}, row:{1}, col:{2}", msg, e.Row, e.Column);
42: }
43: MessageBox.Show(msg);
44: }
代码下载: