为了账号安全,请及时绑定邮箱和手机立即绑定

应用界面实战案例 - 如何处理客户关系管理系统中数据导入导出分析

标签:
AngularJS

DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 近期正式发布了v21.1,最新版拥有众多新产品和数十个具有高影响力的功能,可为桌面、Web和移动应用提供直观的解决方案,全面解决各种使用场景问题。

在很多系统,我们都知道,Excel数据的导入导出操作是必不可少的一个功能,这种功能能够给使用者和外部进行数据交换,也能批量迅速的录入数据到系统中;但在一些系统中,为了方便消费者,可能把很多个基础表或者相关的数据综合到一个Excel表格文件里面,然后希望通过接口进行导入,这种需求处理就显得比较复杂一点了。本文探讨在我的客户关系管理系统中,对于单个Excel表格中,集合了客户基础数据及相关数据的导入和导出操作的处理。

本随笔主要介绍如何在系统中,导入单一文件中的数据到系统中,这个文件包含了基础数据和相关数据的导入和导出操作,一般来说这样的操作对于导入数据已经足够简便了,但是,有时候数据很多的情况下,我们可能需要每次选定文件也是一个麻烦的事情。因此指定目录进行批量数据的导入操作也是一个好的需求,可以进一步简化用户的数据导入操作。

下面我们就来介绍,导入、批量导入和导出的三个重要的操作,如图所示。

应用界面实战案例 - 如何处理客户关系管理系统中数据导入导出分析

导入的数据,是一个Excel,它要求包含几个不同表的数据,导入操作一次性完成数据的导入,Excel文件的格式如下所示。

应用界面实战案例 - 如何处理客户关系管理系统中数据导入导出分析

我们知道,要一次性导入几个表的数据,需要先读取Excel获取各个Sheet(工作表)的数据,然后把它转换为DataTable的数据对象,这样我们就可以根据它的字段赋值给对应的实体类,然后调用业务逻辑处理将数据写入数据库即可。

为了直观的给使用者查看将要导入的数据,我们把需要导入到数据库的数据,展现在界面上,供客户确认,如果没有问题,就可以进行导入操作。由于我们需要操作多个数据表,因此有效读取Excel里面的Sheet就是第一步工作。

查看Excel数据的操作代码如下所示,主要的逻辑就是调用Apose.Cell的封装类进行处理。

AsposeExcelTools.ExcelFileToDataSet(this.txtFilePath.Text, out myDs, out error);

把Excel文件里面多个Sheet的数据转换为DataSet,然后每个进行依次的处理,展示代码如下所示。

private void ViewData()

{

if (this.txtFilePath.Text=="")

{

MessageDxUtil.ShowTips(“请选择指定的Excel文件”);

return;

}

try

{

myDs.Tables.Clear();

myDs.Clear();

this.gridCustomer.DataSource=null;

string error="";

AsposeExcelTools.ExcelFileToDataSet(this.txtFilePath.Text, out myDs, out error);

this.gridCustomer.DataSource=myDs.Tables[0];

this.gridView1.PopulateColumns();

this.gridFollow.DataSource=myDs.Tables[1];

this.gridView2.PopulateColumns();

this.gridContact.DataSource=myDs.Tables[2];

this.gridView3.PopulateColumns();

this.gridSupplier.DataSource=myDs.Tables[3];

this.gridView4.PopulateColumns();

}

catch (Exception ex)

{

LogTextHelper.Error(ex);

MessageDxUtil.ShowError(exssage);

}

}

由于导入过程中需要耗费一定的时间,因此我们可以通过后台线程结合进度条的方式提示用户,界面设计效果如下效果所示。

应用界面实战案例 - 如何处理客户关系管理系统中数据导入导出分析

刚才说到,保存数据,我们把它放到后台线程BackgroudWorker进行处理即可,处理代码如下所示。

private void btnSaveData_Click(object sender, EventArgs e)

{

if (worker.IsBusy)

return;

if (this.txtFilePath.Text=="")

{

MessageDxUtil.ShowTips(“请选择指定的Excel文件”);

return;

}

if (MessageDxUtil.ShowYesNoAndWarning(“该操作将把数据导入到系统数据库中,您确定是否继续?”)==DialogResult.Yes)

{

if (myDs !=null && myDs.Tables[0].Rows.Count > 0)

{

thisgressBar1.Visible=true;

worker.RunWorkerAsync();

}

}

}

后台线程操作的主要业务逻辑代码如下所示,就是依次把不同的数据进行解析,并保存即可。

void worker_DoWork(object sender, DoWorkEventArgs e)

{

if (myDs !=null && myDs.Tables.Count >=4 && myDs.Tables[0].Rows.Count > 0)

{

try

{

ImportCustomerDataHelper helper=new ImportCustomerDataHelper();

helper.LoginUserInfo=LoginUserInfo;

//写入或更新客户信息

string customerID=helper.UpdateCustomer(myDs.Tables[0]);

if (!string.IsNullOrEmpty(customerID))

{

helper.AddFollow(customerID, myDs.Tables[1], worker);

helper.AddContact(customerID, myDs.Tables[2], worker);

helper.AddSupplier(customerID, myDs.Tables[3], worker);

e.Result=“操作完成”;

}

else

{

e.Result=“操作失败”;

}

}

catch (Exception ex)

{

e.Result=exssage;

LogTextHelper.Error(ex);

MessageDxUtil.ShowError(ex.ToString());

}

}

else

{

e.Result=“请检查数据记录是否存在”;

}

}

虽然上面可以一次性导入客户和其相关数据,但是还是一次性导入一个Excel,如果对于客户数据比较多的情况下,一次次导入操作也是很繁琐的事情,因此客户提出,需要按照目录把所有相关的Excel数据一次性导入,这种导入有个问题就是我们不能再中途干预导入操作,因此为了数据的安全性,我提供一个界面让客户选择目录,然后把目录里面的Excel文件列出来,然后在让客户确认是否进一步导入。

上面操作的实现代码我逐一介绍,首先第一步是需要递归列出目录下面的Excel文件,然后显示出来供用户确认导入的清单。

private void btnSelectPath_Click(object sender, EventArgs e)

{

string mydocDir=Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

string selectPath=FileDialogHelper.OpenDir(mydocDir);

if (!string.IsNullOrEmpty(selectPath))

{

//清空就记录

this.lstPath.Items.Clear();

string[] fileArray=Directory.GetFiles(selectPath, “*.xls”, SearchOption.AllDirectories);

if (fileArray !=null && fileArray.Length > 0)

{

foreach (string file in fileArray)

{

string fileName=Path.GetFileName(file);

this.lstPath.Items.Add(new CListItem(fileName, file));

}

}

}

}

当用户确认操作的时候,提示客户确认是否进行,确认后将统一批量导入列表里面的文件,这个地方也是为了方便,使用后台线程进行数据的导出操作,并在过程中提供进度条的指示。

private void btnConfirm_Click(object sender, EventArgs e)

{

if (worker.IsBusy)

return;

if (this.lstPath.Items.Count > 0)

{

if (MessageDxUtil.ShowYesNoAndTips(“您确认导入列表的Excel文件吗?”)==System.Windows.Forms.DialogResult.Yes)

{

List fileList=new List();

foreach (object item in this.lstPath.Items)

{

CListItem fileItem=item as CListItem;

if (fileItem !=null)

{

fileList.Add(fileItem.Value);

}

}

thisgressBar1.Visible=true;

worker.RunWorkerAsync(fileList);

}

}

}

这个后台线程的处理逻辑和单个文件导入的操作差不多,只不过这里需要增加一个文件列表的遍历处理而已,具体代码如下所示。

void worker_DoWork(object sender, DoWorkEventArgs e)

{

List fileList=e.Argument as List;

if (fileListnull || fileList.Count0) return;

bool hasError=false;

ImportCustomerDataHelper helper=new ImportCustomerDataHelper();

helper.LoginUserInfo=LoginUserInfo;

foreach (string file in fileList)

{

DataSet myDs=new DataSet();

string error="";

AsposeExcelTools.ExcelFileToDataSet(file, out myDs, out error);

if (myDs !=null && myDs.Tables.Count >=4 && myDs.Tables[0].Rows.Count > 0)

{

try

{

//写入或更新客户信息

string customerID=helper.UpdateCustomer(myDs.Tables[0]);

if (!string.IsNullOrEmpty(customerID))

{

helper.AddFollow(customerID, myDs.Tables[1], worker);

helper.AddContact(customerID, myDs.Tables[2], worker);

helper.AddSupplier(customerID, myDs.Tables[3], worker);

}

}

catch (Exception ex)

{

hasError=true;

LogTextHelper.Error(ex);

}

}

}

string msg=“操作完成”;

if (hasError)

{

msg +=",导入出现错误。具体可以查看log.txt日志记录。";

}

e.Result=msg;

和上面的单个文件导入一样,我们这里使用了一个封装类ImportCustomerDataHelper,用来对数据进行转换实体类,然后保存到数据库的操作过程,下面我们来简单看看里面的处理代码:

///

/// 客户数据的批量导入和普通导入的操作逻辑代码

///

public class ImportCustomerDataHelper

{

///

/// 登陆用户信息

///

public LoginUserInfo LoginUserInfo { get; set; }

///

/// 写入或更新客户数据,如果成功更新返回ID值

///

/// 客户数据表

///

public string UpdateCustomer(DataTable dataTable)

{

bool success=false;

bool converted=false;

DateTime dtDefault=Convert.ToDateTime(“1900-01-01”);

DateTime dt;

string result="";

DataRow dr=dataTable.Rows[0];

if (dr !=null)

{

string customerName=dr[“客户名称”].ToString();

CustomerInfo info=CallerFactory.Instance.FindByName(customerName);

bool isNew=false;

if (info==null)

{

info=new CustomerInfo();

isNew=true;

}

info.Name=customerName;

info.HandNo=dr[“客户编号”].ToString();

info.SimpleName=dr[“客户简称”].ToString();

info.IsPublic=dr[“公开与否”].ToString().ToBoolean();

info.Satisfaction=dr[“客户满意度”].ToString().ToInt32();

info.TransactionCount=dr[“交易次数”].ToString().ToInt32();

info.TransactionTotal=dr[“交易金额”].ToString().ToDecimal();

info.Creator=dr[“客户所属人员”].ToString();

converted=DateTime.TryParse(dr[“创建时间”].ToString(), out dt);

if (converted && dt > dtDefault)

{

info.CreateTime=dt;

}

info.Editor=LoginUserInfo.ID.ToString();

info.EditTime=DateTime.Now;

if (isNew)

{

info.Dept_ID=LoginUserInfo.DeptId;

infopany_ID=LoginUserInfopanyId;

success=CallerFactory.Instance.Insert(info);

}

else

{

success=CallerFactory.Instance.Update(info, info.ID);

}

if (success)

{

result=info.ID;

}

}

return result;

}

导出操作,我们根据用户的选择,可以一次性导出多个Excel文件,每个Excel文件包含客户的基础信息,也包含相关数据,它们的格式和导入的格式保持一致即可,这样方便数据的交换处理。

导出操作,我们需要把客户的选择信息转换为需要导出的对象列表数据,然后绑定到Excel里面即可,因此我们的Excel里面,可以通过自定义模板,指定列的数据属性就可以绑定好数据了。

获取选择的客户信息的代码如下所示。

List list=new List();

foreach (int iRow in rowSelected)

{

string ID=this.winGridViewPager1.GridView1.GetRowCellDisplayText(iRow, “ID”);

CustomerInfo info=CallerFactory.Instance.FindByID(ID);

if (info !=null)

{

list.Add(info);

}

}

前面介绍了,我们将使用自定义模板,在模板文件里面的对应字段下面,绑定一个参数属性就可以了,通过Aspose.Cell的操作处理,我们就很方便把数据导出到Excel里面了,而里面的字段还可以很方便实现自由的裁剪操作。

自定义模板文件效果如下所示。

导出客户以及相关信息的主要核心代码如下所示。

#region 导出操作

//依次每个客户数据导出一个文件

string ownerUserName=CallerFactory.Instance.GetFullNameByID(customerInfo.Creator.ToInt32());

string filePath=Pathbine(selectPath, ownerUserName);

DirectoryUtil.AssertDirExist(filePath);

Dictionary

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消