澳门在线威尼斯官方 > 澳门在线威尼斯官方 > 顾客关系管理种类中对客户及有关数据的导入导

原标题:顾客关系管理种类中对客户及有关数据的导入导

浏览次数:135 时间:2019-12-01

进程条达成

为了兑现实时更新插入进程,必要用到OracleDataAdapter类下RowUpdated.aspx卡塔尔(英语:State of Qatar)事件。官方文书档案中有注释,当使用Update方法时,在每一条记下更新时会发生三个事件,即OnRowUpdating和OnRowUpdated。利用OnRowUpdated那几个事件就可以记录已插入多少条数据,突显插入进程。

int Sum = 0; //总记录数
int rowNum = 0; //插入记录数
public int Import2Oracle(ISheet sheet)
{
    Sum = sheet.LastRowNum - 1; //获取总记录数
    DataTable dt = GetDataFromExcelByNPOI(sheet);  //经过转换后获得DataTable,利用到了NPOI
    OracleCommand cmd = conn.CreateCommand();// conn为数据库连接对象
    OracleDataAdapter da = new OracleDataAdapter(cmd);
    OracleCommandBuilder ocb = new OracleCommandBuilder(da);
    string SelectSQL = "select * from GZGDZL."+tablename+ " where ROWNUM=0";
    da.SelectCommand.CommandText = SelectSQL;
    da.InsertCommand = ocb.GetInsertCommand();

    // update, this operation fires two events 
    // (RowUpdating/RowUpdated) per changed row 
    //这里只用到RowUpdated事件
    da.RowUpdated += new OracleRowUpdatedEventHandler(OnRowUpdated);

    da.Update(dt);
    return 1; //返回正常
}
//OnRowUpdated事件
 private void OnRowUpdated(object sender, OracleRowUpdatedEventArgs e)
{
    //刷新界面进度条 
    rowNum = rowNum + 1;
    reportValue = (int)(rowNum /m_sheet.LastRowNum * 100);
    this.progressBar1.Value = percent; //progressBar控件已经设置最大值为100,最小值为0
}

经过改进后上述代码就可以让客户实时见到数据插入进程,就算在一定水平上会影响插入的功能,但换到了顾客对插入状态的打听,而且这种影响在数据量不是特意庞大的意况下大致可以忽视。

3、数据批量导入操作

即便下边能够二回性导入客商和其有关数据,然则还是一次性导入三个Excel,借使对于顾客数据比超多的意况下,三次次导入操作也是很麻烦的业务,因而顾客建议,供给依据目录把富有有关的Excel数据一回性导入,这种导入有个难点就是大家不能够再中途干预导入操作,因而为了多少的安全性,作者提供二个分界面让顾客选拔目录,然后把目录里面包车型地铁Excel文件列出来,然后在让客户确认是还是不是尤其导入。

图片 1

地方操作的兑今世码作者逐个介绍,首先第一步是内需递归列出目录下边的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<string> fileList = new List<string>();
                    foreach (object item in this.lstPath.Items)
                    {
                        CListItem fileItem = item as CListItem;
                        if (fileItem != null)
                        {
                            fileList.Add(fileItem.Value);
                        }
                    }

                    this.progressBar1.Visible = true;
                    worker.RunWorkerAsync(fileList);
                }
            }
        }

其后生可畏后台线程的拍卖逻辑和单个文件导入的操作大约,只可是这里需求扩大一个文件列表的遍历管理而已,具体代码如下所示。

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            List<string> fileList = e.Argument as List<string>;
            if (fileList == null || fileList.Count == 0) 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,用来对数码开展转移实体类,然后保留到数据库的操作过程,下边大家来轻便看看个中的拍卖代码

    /// <summary>
    /// 客户数据的批量导入和普通导入的操作逻辑代码
    /// </summary>
    public class ImportCustomerDataHelper
    {
        /// <summary>
        /// 登陆用户信息
        /// </summary>
        public LoginUserInfo LoginUserInfo { get; set; }

        /// <summary>
        /// 写入或更新客户数据,如果成功更新返回ID值
        /// </summary>
        /// <param name="dataTable">客户数据表</param>
        /// <returns></returns>
        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<ICustomerService>.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;
                    info.Company_ID = LoginUserInfo.CompanyId;
                    success = CallerFactory<ICustomerService>.Instance.Insert(info);
                }
                else
                {
                    success = CallerFactory<ICustomerService>.Instance.Update(info, info.ID);
                }

                if (success)
                {
                    result = info.ID;
                }
            }

            return result;
        }

...........................

 

批量布署

体系中接收的是System.Data.OracleClient。首先将Excel数据经过更改函数转换为DataTable,此中的字段和数据库中相应表格的字段完全对应。

public int Import2Oracle(ISheet sheet, string tablename)
{
    DataTable dt = GetDataFromExcelByNPOI(sheet); //经过转换后获得DataTable
    OracleCommand cmd = conn.CreateCommand();// conn为数据库连接对象
    OracleDataAdapter da = new OracleDataAdapter(cmd);
    OracleCommandBuilder ocb = new OracleCommandBuilder(da);
    string SelectSQL = "select * from "+tablename+ " where ROWNUM=0";
    da.SelectCommand.CommandText = SelectSQL;
    da.InsertCommand = ocb.GetInsertCommand();
    da.Update(dt);
    return 1; //返回正常
}

上述代码没有列出连接Oracle数据库相关代码,该段代码将DataTable批量插入数据库中。为了接收进度条控件实现显示插入的速度,须要在每一回成功插入一条数据后更新进度条。

4、数据的导出操作

导出操作,大家依据客户的筛选,能够二遍性导出七个Excel文件,每一个Excel文件包涵客商的基础消息,也含有相关数据,它们的格式和导入的格式保持意气风发致就能够,那样便于数据的交流处理。

导出操作,我们须要把顾客的精选音信调换为索要导出的靶子列表数据,然后绑定到Excel里面就能够,因而我们的Excel里面,可以通过自定义模板,钦定列的数码属性就足以绑定好数据了。

收获采用的客户音讯的代码如下所示。

                List<CustomerInfo> list = new List<CustomerInfo>();
                foreach (int iRow in rowSelected)
                {
                    string ID = this.winGridViewPager1.GridView1.GetRowCellDisplayText(iRow, "ID");
                    CustomerInfo info = CallerFactory<ICustomerService>.Instance.FindByID(ID);
                    if (info != null)
                    {
                        list.Add(info);
                    }
                }

最近介绍了,大家将运用自定义模板,在模板文件之中的附和字段下边,绑定二个参数属性就能够了,通过Aspose.Cell的操作管理,大家就很有益把数据导出到Excel里面了,而其中的字段还足以很方便达成自由的剪裁操作。

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

图片 2

导出客商以至相关消息的首要骨干代码如下所示。

                            #region 导出操作
                            //依次每个客户数据导出一个文件
                            string ownerUserName = CallerFactory<IUserService>.Instance.GetFullNameByID(customerInfo.Creator.ToInt32());
                            string filePath = Path.Combine(selectPath, ownerUserName);
                            DirectoryUtil.AssertDirExist(filePath);

                            Dictionary<string, object> dict = new Dictionary<string, object>();
                            dict.Add("Customer", new List<CustomerInfo>() { customerInfo });//需要构造一个列表绑定

                            List<FollowInfo> followList = CallerFactory<IFollowService>.Instance.Find(string.Format("Customer_ID ='{0}' ", customerInfo.ID));
                            dict.Add("Follow", followList);

                            List<ContactInfo> contactList = CallerFactory<IContactService>.Instance.FindByCustomer(customerInfo.ID);
                            dict.Add("Contact", contactList);

                            PagerInfo pagerInfo = null;
                            List<SupplierInfo> supplierList = CallerFactory<ISupplierService>.Instance.FindByCustomer(customerInfo.ID, "", ref pagerInfo);
                            dict.Add("Supplier", supplierList);

                            string templateFile = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "客户综合资料-导出模板.xls");
                            if (!File.Exists(templateFile))
                            {
                                throw new ArgumentException(templateFile, string.Format("{0} 文件不存在,", Path.GetFileName(templateFile)));
                            }

                            string saveFileName = string.Format("{0}.xls", customerInfo.Name);
                            string saveFilePath = Path.Combine(filePath, saveFileName);

                            WorkbookDesigner designer = new WorkbookDesigner();
                            designer.Workbook = new Workbook(templateFile);
                            foreach (string key in dict.Keys)
                            {
                                designer.SetDataSource(key, dict[key]);
                            }
                            designer.Process();
                            designer.Workbook.Save(saveFilePath, SaveFormat.Excel97To2003);   
                            #endregion

如此那般利用Aspose.Cell的管理操作,通过绑定相关的数目对象,大家就非常轻巧达成数据导出到适合我们预料格式的Excel里面去了,那样操作便捷、代码干净,Excel格式也相当相符大家的渴求。

以上就是在顾客关系管理连串里面遭遇特殊的数额导入导出须求的介绍和促成,希望大家互相调换,合营把软件开拓进度中,数据导入导出操作的施用体验做到最棒,更适合大家顾客接纳的习贯和必要。

前言

是因为种类供给,要求将Excel中的数据进过一定调换导入仅Oracle数据库中。思忖到当Excel数据量十分大时,循环Insert语句功效太低,故选用批量插入的艺术。在插入操作运维时,会产生系统短暂的“卡死”现象。为了让客户领悟插入的意况,必要构建叁个进程条来显示插入的速度。

2、数据导入操作的分界面设计及管理

咱俩知道,要二遍性导入多少个表的数目,须要先读取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(ex.Message);
            }
        }

出于导入进程中供给花销一定的岁月,因而大家得以由从此以后台线程结合过程条的方式提示客户,分界面设计效果如下效果所示。

图片 3

刚才说起,保存数据,大家把它内置后台线程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)
                {
                    this.progressBar1.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 = ex.Message;
                    LogTextHelper.Error(ex);
                    MessageDxUtil.ShowError(ex.ToString());
                }
            }
            else
            {
                e.Result = "请检查数据记录是否存在";
            }
        }

 

本文由澳门在线威尼斯官方发布于澳门在线威尼斯官方,转载请注明出处:顾客关系管理种类中对客户及有关数据的导入导

关键词:

上一篇:没有了

下一篇:net组件修炼手册,net从入门到精通