24
2012
07

Winform开发框架之通用数据导入导出操作,C#,asp.ne都可以使用

做了很多Winform的项目,对于数据导入,一直也有自己的理解,由于一般的业务系统,经常性的数据导入时很正常的业务需求,因为毕竟使用Excel来操作数据也很方便,或者由于系统之间的数据交换需要,我们需要提供一个入口给客户导入所需要的数据。但是导入数据的时候,不同的业务数据对应不同的Excel文件,很难做到统一,但如果是每个业务模型,都创建一个不同的导入界面来操作Excel数据,又会觉得可能某种程度上重复劳动,增加开发及维护成本。

那么有无一种介于两者之间的方法,来实现效率的最优化,并且能够统一利用好一个导入的界面呢,在开发领域,只要能想到的,一般也能做到,由于工作的需要,在我的

然后我们再来看看实际的导入模块操作界面,如下图所示

在最底的状态栏里面,但我们保存数据的时候,会调用后台线程进行数据保存,并显示数据导入的进度状态,由于是采用后台线程处理,不会阻塞当前的界面,在多文档的

        private BackgroundWorker worker = null;        public delegate bool SaveDataHandler(DataRow dr);        public event SaveDataHandler OnDataSave;        public event EventHandler OnRefreshData;        public FrmImportExcelData()        {            InitializeComponent();            this.gridView1.OptionsBehavior.AutoPopulateColumns = true;            worker = new BackgroundWorker();            worker.WorkerReportsProgress = true;            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);            worker.DoWork += new DoWorkEventHandler(worker_DoWork);            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);        }        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)        {            this.progressBar1.Value = e.ProgressPercentage;        }        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)        {            this.progressBar1.Visible = false;            this.progressBar1.Value = 0;            if (OnRefreshData != null)            {                OnRefreshData(null, null);            }            string tips = e.Result as string;            if (!string.IsNullOrEmpty(tips))            {                MessageDxUtil.ShowTips(tips);                if (tips == "操作成功")                {                    this.gridControl1.DataSource = null;                }            }        }
复制代码

2)设置显示不同的模板文件

由于导入数据操作要应用于不同的业务数据,那么他们的模板肯定也不同,因此需要提供一个接口给外部,实现模板文件的修改及打开操作。

复制代码
        /// <summary>        /// 设置导入模板标题,及文件路径        /// </summary>        /// <param name="title"></param>        /// <param name="filePath"></param>        public void SetTemplate(string title, string filePath)        {            this.lnkExcel.Text = title;            this.lnkExcel.Tag = filePath;        }        private void lnkExcel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)        {            try            {                string templateFile = this.lnkExcel.Tag.ToString();                Process.Start(templateFile);            }            catch (Exception)            {                MessageDxUtil.ShowWarning("文件打开失败");            }        }
复制代码

3)显示Excel数据

我们在数据导入的时候,最好提供一个数据的显示界面给客户,方便对导入数据的核对,这样可以提高体验效果以及对数据的核对操作,减少出错的几率。具体的实现代码如下所示。数据显示的操作,可以通过操作Excel数据库的方式进行读取,然后显示数据。(其中有些接口API来自我的共用类库,需要可以到我的随笔中了解相关的类库使用。

复制代码
      private void btnBrowse_Click(object sender, EventArgs e)        {            string file = FileDialogHelper.OpenExcel();            if (!string.IsNullOrEmpty(file))            {                this.txtFilePath.Text = file;                ViewData();            }        }        private void ViewData()        {            if (this.txtFilePath.Text == "")            {                MessageDxUtil.ShowTips("请选择指定的Excel文件");                return;            }                        try            {                string connectString = string.Format(connectionStringFormat, this.txtFilePath.Text);                string firstSheet = ExcelHelper.GetExcelFirstTableName(connectString);                myDs.Tables.Clear();                myDs.Clear();                this.gridControl1.DataSource = null;                                                OleDbConnection cnnxls = new OleDbConnection(connectString);                OleDbDataAdapter myDa = new OleDbDataAdapter(string.Format("select * from [{0}]", firstSheet), cnnxls);                myDa.Fill(myDs, "【导入表】");                this.gridControl1.DataSource = myDs.Tables[0];                this.gridView1.PopulateColumns();            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }        }
复制代码

4)调用者给出保存数据的逻辑

由于是通用的数据导入操作,因此公用的导入界面,只能抛出相应的事件给外部进行数据保存的逻辑处理,数据导入页面只需要负责总体逻辑,具体的保存逻辑交给调用者实现,这样各司其职,共同把事情做好。下面是调用者(药品信息显示窗体中),对数据导入的操作逻辑实现。我们可以看到,它需要指定模板文件、数据刷新操作、数据保存操作,其他的交给通用数据导入界面进行处理即可。

复制代码
       private string moduleName = "药品目录";        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();        }        void ExcelData_OnRefreshData(object sender, EventArgs e)        {            BindData();        }        bool ExcelData_OnDataSave(DataRow dr)        {            bool success = false;            DrugDetailInfo info = new DrugDetailInfo();            info.DrugNo = dr["药品编码"].ToString();            info.DrugName = dr["药品名称"].ToString();            info.Manufacture = dr["制造商"].ToString();            info.Formulations = dr["剂型"].ToString();            info.Specification = dr["规格"].ToString();            info.Unit = dr["药品单位"].ToString();            info.Note = dr["备注信息"].ToString();            info.StockQuantity = ConvertHelper.ToInt32(dr["库存量"].ToString(), 0);            info.EditTime = DateTime.Now;            info.Editor = Portal.gc.LoginInfo.Name;            info.Dept_ID = Portal.gc.LoginInfo.Dept_ID;            success = BLLFactory<DrugDetail>.Instance.Insert(info);            return success;        }
复制代码

到这里,通用数据导入的操作基本上就结束了,我的处理方式是否和你的想法吻合呢,或者有更好的实现方式?

不过大家的总体思想,肯定是殊途同归,抽象封装统一的部分,并提供个性化的逻辑给外部进行处理,这样就可以实现综合的统一,提高整体的使用效率,较少今后维护的成本。

在这里顺便说一下,数据导出的操作,因为既然有导入,应该也有导出,所以我们也需要实现。它的操作代码不是很复杂,只需要把数据按照导入模板约定的字段名称导出即可,记得要和导入模板一致。

复制代码
       private void btnExport_Click(object sender, EventArgs e)        {            string file = FileDialogHelper.SaveExcel(string.Format("{0}.xls", moduleName));            if (!string.IsNullOrEmpty(file))            {                List<DrugDetailInfo> list = BLLFactory<DrugDetail>.Instance.GetAll();                DataTable dtNew = DataTableHelper.CreateTable("序号|int,药品编码,药品名称,制造商,剂型,规格,药品单位,备注信息,库存量");                DataRow dr;                for (int i = 0; i < list.Count; i++)                {                    dr = dtNew.NewRow();                    dr["序号"] = i + 1;                    dr["药品编码"] = list[i].DrugNo;                    dr["药品名称"] = list[i].DrugName;                    dr["制造商"] = list[i].Manufacture;                    dr["剂型"] = list[i].Formulations;                    dr["规格"] = list[i].Specification;                    dr["药品单位"] = list[i].Unit;                    dr["备注信息"] = list[i].Note;                    dr["库存量"] = list[i].StockQuantity;                    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)                {                    LogHelper.Error(ex);                    MessageDxUtil.ShowError(ex.Message);                }            }
复制代码

以上就是我的通用数据导入导出操作,欢迎拍砖或者共同探讨。

来源:http://www.cnblogs.com/wuhuacong/archive/2012/07/19/2598723.html

« 上一篇下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。