随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了。

其实也许我们每天面对的太多东西了,觉得很多都稀松平常了,即使很细微的地方,可能我们都已经形成习惯了。反过来,如果我们切换到其他领域,如IOS、android,那么开始我们可能对里面很多设计的规则不甚了解,开始可能也是一头雾水。

本篇继续上一篇《循序渐进开发WinForm项目(4)--Winform界面模块的集成使用》,继续介绍如何循序渐进开发Winform项目,介绍业务模块常见的导入导出操作的功能实现,使得我们能够快速,高效开发常见的模块功能。

上篇随笔我们介绍到自动代码生成的界面如下所示,具备了导入、导出操作,这个操作是针对Excel进行的。

下面我们来介绍这个在很多模块里面常见的Excel导入、Excel导出操作是如何实现的。

1、Excel数据的导出操作

由于我为了演示的目的,我在客户信息表里面只是设计了几个代表性的字段,下面我们来看看代码生成工具自动生成的界面后台代码是如何的。

        /// <summary>
/// 导出Excel的操作
/// </summary>
private void btnExport_Click(object sender, EventArgs e)
{
string file = FileDialogHelper.SaveExcel(string.Format("{0}.xls", moduleName));
if (!string.IsNullOrEmpty(file))
{
string where = GetConditionSql();
List<CustomerInfo> list = BLLFactory<Customer>.Instance.Find(where);
DataTable dtNew = DataTableHelper.CreateTable("序号|int,姓名,年龄,创建人,创建时间");
DataRow dr;
int j = ;
for (int i = ; i < list.Count; i++)
{
dr = dtNew.NewRow();
dr["序号"] = j++;
dr["姓名"] = list[i].Name;
dr["年龄"] = list[i].Age;
dr["创建人"] = list[i].Creator;
dr["创建时间"] = list[i].CreateTime;
dtNew.Rows.Add(dr);
} try
{
string error = "";
AsposeExcelTools.DataTableToExcel2(dtNew, file, out error);
if (!string.IsNullOrEmpty(error))
{
MessageDxUtil.ShowError(string.Format("导出Excel出现错误:{0}", error));
}
else
{
if (MessageDxUtil.ShowYesNoAndTips("导出成功,是否打开文件?") == System.Windows.Forms.DialogResult.Yes)
{
System.Diagnostics.Process.Start(file);
}
}
}
catch (Exception ex)
{
LogTextHelper.Error(ex);
MessageDxUtil.ShowError(ex.Message);
}
}
}

上面的代码中,FileDialogHelper.SaveExcel 函数是调用公用类库模块,弹出一个选择保存文件的对话框,如果你没有这个类,你可以自己添加代码实现这个操作(这就是公用类库的好处,在使用的时候能够快速调用,减少代码,提高效率)。

然后根据客户录入的条件检索需要的数据内容:string where = GetConditionSql();

接着就是构建一个相关字段的表格对象:DataTableHelper.CreateTable,这里面也是使用公用类库来方便创建各种字段的表格,默认字段为字符串格式,如果需要如整形格式的,可以通过|进行分割,如“序号|int” 。

创建DataTable对象后,我们遍历对象集合,把它里面的数据一行行的赋值给DataRow对象就可以了。

                for (int i = ; i < list.Count; i++)
{
dr = dtNew.NewRow();
dr["序号"] = j++;
dr["姓名"] = list[i].Name;
dr["年龄"] = list[i].Age;
dr["创建人"] = list[i].Creator;
dr["创建时间"] = list[i].CreateTime;
dtNew.Rows.Add(dr);
}

赋值后,就是需要把DataTable对象转换为Excel的操作过程了,这里操作分为两步,第一是创建Excel文档,第二个是写数据的表头和数据行信息,也就是数据的写入操作,这里面我们把它封装在公用类库里面,方便模块之间的调用。

导出Excel模块采用了基于Aspose.Cell的组件进行数据的写入操作:AsposeExcelTools.DataTableToExcel2

导出完成后,我们提示用户是否打开Excel文件。

if (MessageDxUtil.ShowYesNoAndTips("导出成功,是否打开文件?") == System.Windows.Forms.DialogResult.Yes)
{
System.Diagnostics.Process.Start(file);
}

最终,完成功能后,我们运行程序,导出Excel数据的效果如下所示。

2、Excel数据的导入操作

相对于数据的导出操作,Excel数据的导入操作会稍微麻烦一点,你至少需要选择一个文件,文件最好以固定的模板进行导入,因此为了让用户确认数据的有效性,我们最好能提供了一个把Excel数据显示出来再确认导入的过程,这样可以减少导入错误数据的可能。

我们知道,这种常见的导入操作,很多业务模块可能都需要,因此有必要考虑把它抽象出来,作为一个通用的导入模块,这样我们可以多次利用,非常方便,因此我们提炼这个通用导入的模块特性如下所示。

Excel数据的导入模块,默认生成界面的时候,也已经一并生成了,我们来看看其中的代码。

        private string moduleName = "客户信息";
/// <summary>
/// 导入Excel的操作
/// </summary>
private void btnImport_Click(object sender, EventArgs e)
{
string templateFile = string.Format("{0}-模板.xls", moduleName);
FrmImportExcelData dlg = new FrmImportExcelData();
dlg.SetTemplate(templateFile, System.IO.Path.Combine(Application.StartupPath, templateFile));
dlg.OnDataSave += new FrmImportExcelData.SaveDataHandler(ExcelData_OnDataSave);
dlg.OnRefreshData += new EventHandler(ExcelData_OnRefreshData);
dlg.ShowDialog();
}

其中FrmImportExcelData 是一个界面基础模块中定义的一个通用导入模块,里面实现了一些如显示Excel数据,模板信息关联,保存数据的接口等操作。我们来看看它的程序运行的效果。

其中我们通过代码 dlg.SetTemplate 指定模板就是用来关联Excel模板信息的,我们让可以尽可能的选择正确的模板进行录入数据。

用户通过第2的标识,指定要导入的Excel数据文件,选择文件后,数据会自动显示出来方便确认。

但我们选择保存数据的操作的时候,这个通用模块会执行保存的逻辑代码,并调用由创建者实现的代码逻辑,如上面代码的dlg.OnDataSave就是在执行保存的时候,执行的代码逻辑,我们来看看生成的一些代码实现。

        bool ExcelData_OnDataSave(DataRow dr)
{
bool success = false;
bool converted = false;
DateTime dtDefault = Convert.ToDateTime("1900-01-01");
DateTime dt;
CustomerInfo info = new CustomerInfo();
info.Name = dr["姓名"].ToString();
info.Age = dr["年龄"].ToString().ToInt32();
info.Creator = dr["创建人"].ToString();
converted = DateTime.TryParse(dr["创建时间"].ToString(), out dt);
if (converted && dt > dtDefault)
{
info.CreateTime = dt;
} success = BLLFactory<Customer>.Instance.Insert(info);
return success;
}

我们知道,导入的时候,是遍历每行Excel进行数据保存操作的,因此我们这里给出了一个一行的操作代码即可:bool ExcelData_OnDataSave(DataRow dr),里面的逻辑,在数据保存的时候会被模块进行调用。

上面的操作,是一条条的进行操作,如果累计超过3条记录出错,模块提示是否继续还是退出。

这里面并没有采用事务的操作,对于一些如Sqlite的大批量的数据操作(速度提升很快),建议采用事务进行处理,关于这个可以参考《Winform开发框架之通用数据导入导出操作的事务性操作完善》进行修改调整。

最后,我们的Excel数据导入完成后,为了及时更新主界面的数据,我们也定义了一个事件作为回调,如下所示。

dlg.OnRefreshData += new EventHandler(ExcelData_OnRefreshData);

这个事件的实现代码就是在主界面的数据绑定更新。

        void ExcelData_OnRefreshData(object sender, EventArgs e)
{
BindData();
}

循序渐进开发WInform项目--系列文章导引:

循序渐进开发WinForm项目(5)--Excel数据的导入导出操作

循序渐进开发WinForm项目(4)--Winform界面模块的集成使用

循序渐进开发WinForm项目(3)--Winform界面层的项目设计

循序渐进开发WinForm项目(2)--项目代码的分析

循序渐进开发WinForm项目(1) --数据库设计和项目框架的生成

循序渐进开发WinForm项目(5)--Excel数据的导入导出操作的更多相关文章

  1. 循序渐进开发WinForm项目(6)--开发使用混合式Winform模块

    1.Winform数据访问模式定义 传统的Winform程序模块:用于传统的数据库通讯获取数据,这种方式获取数据,方便快捷,可以用于常规的业务系统的场景,用于单机版软件或者基于局域网内的业务系统软件. ...

  2. 循序渐进开发WinForm项目(4)--Winform界面模块的集成使用

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  3. 循序渐进开发WinForm项目(3)--Winform界面层的项目设计

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  4. 循序渐进开发WinForm项目(2)--项目代码的分析

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  5. 循序渐进开发WinForm项目(1) --数据库设计和项目框架的生成

    随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我 ...

  6. 使用phpExcel实现Excel数据的导入导出(完全步骤)

    使用phpExcel实现Excel数据的导入导出(完全步骤)   很多文章都有提到关于使用phpExcel实现Excel数据的导入导出,大部分文章都差不多,或者就是转载的,都会出现一些问题,下面是本人 ...

  7. 利用PHPExcel 实现excel数据的导入导出(源码实现)

    利用PHPExcel 实现excel数据的导入导出(源码实现) 在开发过程中,经常会遇到导入导出的需求,利用phpexcel类实现起来也是比较容易的,下面,我们一步一步实现 提前将phpexcel类下 ...

  8. VB中Excel 2010的导入导出操作

    VB中Excel 2010的导入导出操作 编写人:左丘文 2015-4-11 近来这已是第二篇在讨论VB的相关问题,今天在这里,我想与大家一起分享一下在VB中如何从Excel中导入数据和导出数据到Ex ...

  9. java项目中Excel文件的导入导出

    package poi.excel; import java.io.IOException; import java.io.InputStream; import java.io.OutputStre ...

随机推荐

  1. Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  2. HDU 5914 Triangle 数学找规律

    Triangle 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5914 Description Mr. Frog has n sticks, who ...

  3. nodejs - 如何完全更新

    Nodejs可以毫不犹豫地说一个版本狂魔,时不时就发布一个版本,而且还一直没有一个1.0版本,好囧呀,对于我们这些有强迫症的人来说,的确不是好事. 下面我就说一下Nodejs中常见的更新方式. 1. ...

  4. Asp.net Core中使用NLog,并封装成公共的日志方法

    1.安装NLog "NLog.Extensions.Logging": "1.0.0-rtm-alpha4" 2.配置NLog public void Conf ...

  5. 1.什么是泛型和C#中泛型在Class上的实现

    阅读目录 一:什么是泛型? 二:C#中泛型在Class上的实现   一:什么是泛型? 我们在编程的时候需要一个数据类型,但是在刚开始的时候还不确定这个数据类型是怎么样的,或者说对于不同的多个数据类型有 ...

  6. UICollectionView瀑布流的实现原理(转)

    http://ios.jobbole.com/85689/ 和使用 UIScollView 创刊一个瀑布流是一样的方式 7cc829d3gw1f4nq2oc09zj20j00hvq90.jpg 我的 ...

  7. The model backing the <Database> context has changed since the database was created.

    Just found out the answer and thought of updating here. Just need to do the following. public class ...

  8. GitHub上排名前100的Android开源库介绍(来自github)

    本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍,至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果,然后过滤了 ...

  9. 移动API-restful的设计原则和参考

    移动应用API设计10大技巧 http://jingyan.baidu.com/article/455a9950fd27ffa166277825.html RESTful API 设计指南 http: ...

  10. Version of SQLCE in WP8

    The version on the device is compatible with version 3.5 on the desktop, but the Windows Phone versi ...