Excel文件处理Demo

1.BLL业务逻辑代码

/// <summary>
        /// 处理“店铺竞品销售数据”导入文件
        /// </summary>
        /// <param name="filePath">文件物理路径</param>
        /// <param name="ownerId">品牌Id</param>
        /// <param name="saleYM">竞品数据销售年月</param>
        /// <param name="msg">处理过程中出现的错误消息</param>
        /// <returns></returns>
        public bool HandleImportExcel(string filePath, string ownerId, string saleYM, out string msg)
        {
            using (DaoTransactionScope ts = new DaoTransactionScope(true))
            {
                msg = "";    // 返回给UI层的错误消息            

                #region 1.0 设置连接Excel组件的连接字符串
                // 获取导入文件的扩展名
                string fileExt = Path.GetExtension(filePath).ToLower();
                // Excel组件连接字符串
                string excelConnStr = string.Empty;
                if (fileExt.Equals(".xlsx"))
                {
                    // "HDR=Yes;" 表示第一行是标题行, 不是数据。"HDR=No;" 则表示从第一行开始就是数据。
                    excelConnStr = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=‘Excel 12.0;HDR=No;IMEX=1‘", filePath);
                }
                else if (fileExt.Equals(".xls"))
                {
                    excelConnStr = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=‘Excel 8.0;HDR=No;IMEX=1‘", filePath);
                }
                else
                {
                    // "不是Excel文件,请重新选择文件导入!";
                    msg = this.GetResourceString("NotExcelFile");
                    return false;
                }
                #endregion

                string loginUser = this.LoginUser;
                // 总部营业日期
                string hqAccountDate = Convert.ToDateTime(new BLSystemInfo().GetSysValue(2033, 1)).ToString("yyyyMM");
                DLSalesOtherMakerSearch dal = new DLSalesOtherMakerSearch();

                OleDbConnection oleConn = null;     // 连接Excel文件的连接对象
                DataSet ds = null;
                DataTable dtExcel = null;           // 存储Excel文件数据的内存表
                DataTable dtInsert = null;          // 存储处理后的Excel文件数据的内存表
                try
                {
                    #region 2.0 通过OleDbConnection对象从Excel文件中获取数据并存放在内存DataTable中(变量:dtExcel)

                    oleConn = new OleDbConnection(excelConnStr);
                    oleConn.Open();
                    DataTable schemaTable = oleConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                    // 获取Excel中sheet名称
                    string tableName = string.Format("[{0}]", schemaTable.Rows[0][2].ToString().Trim());
                    string sql = string.Format("select * from {0}", tableName);
                    ds = new DataSet();
                    using (OleDbDataAdapter adapter = new OleDbDataAdapter(sql, oleConn))
                    {
                        adapter.Fill(ds, tableName);
                    }

                    // 第1,2,3行都是标题行
                    dtExcel = ds.Tables[tableName];
                    if (dtExcel.Rows.Count <= 3)
                    {
                        // "选择的文件没有需要导入的数据,请重新选择文件导入!";
                        msg = this.GetResourceString("ExcelFileNoData");
                        return false;
                    }

                    // 判断Excel中是否存在相同的店铺号,若存在则提示用户,不导入
                    // 根据店号进行分组
                    var storeList = from s in dtExcel.AsEnumerable()
                                    where s.Field<string>(0) != null
                                    group s by new { f = s.Field<string>(0).ToUpper() } into g
                                    select new
                                    {
                                        StoreId = g.Key.f,
                                        StoreCount = g.Count()
                                    };
                    // 查出有多行店号的数据
                    storeList = storeList.Where(item => item.StoreCount > 1);
                    if (storeList.Count() > 0)
                    {
                        string storeIds = string.Empty;
                        storeList.ToList().ForEach(item => storeIds += item.StoreId + ",");
                        // [{0}]店铺存在多行销售数据,请删除多余行的数据,每个店铺只保留一行!
                        msg = this.GetResourceString("StoreSalesDataRepeated", storeIds.Substring(0, storeIds.Length - 1));
                        return false;
                    }

                    #endregion

                    #region 3.0 判断Excel表中的数据是否合法并转换存放在符合数据库表结构的内存表中(变量:dtInsert)

                    // 创建要插入到数据库中的内存表dtInsert
                    dtInsert = dal.GetOtherMakerSaleTblScheme();

                    // Excel中的第三行是竞品品牌名称,故从第四行开始循环遍历dtExcel(注意下标为3)
                    DataRow rowExcel;
                    DataRow rowInsert;

                    // 获取所有竞品品牌主档数据
                    List<OtherMakerMasTbl> otherMakerMasList = dal.GetOtherMakerMasList();
                    if (otherMakerMasList == null || otherMakerMasList.Count <= 0)
                    {
                        // 没有竞品品牌主档数据,请联系系统管理员重新导入!
                        msg = this.GetResourceString("OtherMakerMasDataNotExist");
                        return false;
                    }

                    // 循环遍历Excel中的第三行竞品品牌名称,获取对应的竞品品牌代码,并替换掉竞品品牌名称
                    // 从第二列开始循环遍历竞品品牌
                    OtherMakerMasTbl otherMakerMasModel = null;
                    string notExistOtherMakerStr = string.Empty;
                    Dictionary<string, string> dicOtherMakerMas = new Dictionary<string, string>();
                    for (int j = 1; j < dtExcel.Columns.Count; j++)
                    {
                        otherMakerMasModel = otherMakerMasList.SingleOrDefault(item => item.OtherMakerNm.Trim().Equals(dtExcel.Rows[2][j].ToString().Trim()));
                        if (otherMakerMasModel == null)
                        {
                            // 在竞品品牌主档中未找到 {0} 该品牌对应的数据,请仔细核对数据重新导入!
                            //msg = this.GetResourceString("OtherMakerNotFound", dtExcel.Rows[2][j].ToString().Trim());
                            notExistOtherMakerStr += "[" + dtExcel.Rows[2][j].ToString().Trim() + "],";
                        }
                        else
                        {
                            dicOtherMakerMas.Add(otherMakerMasModel.OtherMakerCd, otherMakerMasModel.OtherMakerNm.Trim());
                            dtExcel.Rows[2][j] = otherMakerMasModel.OtherMakerCd;
                        }
                    }
                    if (!string.IsNullOrEmpty(notExistOtherMakerStr))
                    {
                        msg = this.GetResourceString("OtherMakerNotFound", notExistOtherMakerStr.Substring(0, notExistOtherMakerStr.Length - 1));
                        return false;
                    }

                    for (int i = 3; i < dtExcel.Rows.Count; i++)
                    {
                        rowExcel = dtExcel.Rows[i];
                        // 从第二列开始循环遍历竞品品牌
                        for (int j = 1; j < dtExcel.Columns.Count; j++)
                        {
                            // 如果店号为空,则Continue
                            if (dtExcel.Rows[i][0] == null || string.IsNullOrEmpty(dtExcel.Rows[i][0].ToString()))
                            {
                                continue;
                            }

                            // 如果金额数字为空,则Continue
                            if (dtExcel.Rows[i][j] == null || string.IsNullOrEmpty(dtExcel.Rows[i][j].ToString()))
                            {
                                continue;
                            }
                            rowInsert = dtInsert.NewRow();
                            rowInsert["OwnerId"] = ownerId;
                            rowInsert["CustomerCd"] = dtExcel.Rows[i][0];
                            rowInsert["OtherMakerCd"] = dtExcel.Rows[2][j].ToString();
                            rowInsert["OtherSaleYM"] = saleYM;
                            try
                            {
                                rowInsert["OtherSaleMoney"] = Convert.ToDecimal(dtExcel.Rows[i][j]);
                            }
                            catch (Exception)
                            {
                                // 店号为{0}的竞品品牌{1}填写的金额数字{2}有误,请重新导入
                                msg += this.GetResourceString("SaleAmoutError", dtExcel.Rows[i][0], dicOtherMakerMas[dtExcel.Rows[2][j].ToString()], dtExcel.Rows[i][j]) + "<br/>";
                                continue;
                            }
                            rowInsert["SCHInput"] = "1";
                            rowInsert["DayEndNo"] = dtExcel.Rows[i][0] + hqAccountDate;
                            rowInsert["BCCD"] = loginUser;
                            rowInsert["UpdateMan"] = loginUser;
                            rowInsert["UpdateTime"] = DateTime.Now;
                            rowInsert["Origsys"] = "2";

                            dtInsert.Rows.Add(rowInsert);
                        }

                    }

                    if (!string.IsNullOrEmpty(msg))
                    {
                        return false;
                    }

                    #endregion

                    #region 4.0 创建数据库临时表#temp,并把dtInsert内存表中的数据插入到临时表,再判断数据有效性并导入到正式表中

                    msg = dal.InsertOtherMakerSaleToTempTable(dtInsert);
                    if (!string.IsNullOrEmpty(msg))
                    {
                        return false;
                    }

                    #endregion

                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    #region 资源释放
                    if (oleConn != null)
                    {
                        oleConn.Dispose();
                        oleConn.Close();
                    }
                    if (dtInsert != null)
                    {
                        dtInsert.Dispose();
                    }
                    if (dtExcel != null)
                    {
                        dtExcel.Dispose();
                    }
                    if (ds != null)
                    {
                        ds.Dispose();
                    }
                    #endregion
                }

                ts.Complete();
                return true;
            }
        }

2.DAO数据库操作代码

/// <summary>
        /// 创建“竞品品牌销售数据临时表”,判断数据有效性,导入到正式表中
        /// </summary>
        /// <param name="dtInsert">店铺竞品品牌销售数据</param>
        /// <returns></returns>
        public string InsertOtherMakerSaleToTempTable(DataTable dtInsert)
        {
            string msg = "";
            string tempTableName = "#OtherMakerSaleTemp";
            StringBuilder sql = new StringBuilder();
            // 1 先删除临时表
            sql.AppendFormat(" if object_id(N‘{0}‘,N‘U‘) is not null drop table {1}", tempTableName, tempTableName).AppendLine();
            this.DataAccessClient.ExecuteNonQuery(sql.ToString());

            // 2 创建临时表
            sql.Remove(0, sql.Length);
            sql.AppendFormat(" select * into {0} from OtherSaleMonthTbl where 1=0 ;", tempTableName).AppendLine();
            // 2.1 为临时表添加主键
            sql.AppendFormat(" alter table {0} add primary key(ownerid,customercd,othermakercd,othersaleym); ", tempTableName).AppendLine();
            this.DataAccessClient.ExecuteNonQuery(sql.ToString());

            // 3.往临时表中插入数据
            #region DeleteCode
            /*
            string connString = Inf.DevLib.Data.DataAccess.DataAccessFactory.ConnectionString;
            using (SqlConnection conn = new SqlConnection(connString))
            {
                if (conn.State != System.Data.ConnectionState.Open)
                {
                    conn.Open();
                }

                using (SqlBulkCopy bc = new SqlBulkCopy(conn))
                {
                    bc.BulkCopyTimeout = 300;
                    bc.DestinationTableName = tempTableName;
                    bc.WriteToServer(dtInsert);
                }
                conn.Close();
            }
            */
            #endregion

            this.DataAccessClient.BatchInsert(dtInsert, tempTableName, null, 100);

            // 4.判断临时表中的店号在ShopRelateMakerTBL表中是否存在,若不存在则给予提示并返回
            sql.Remove(0, sql.Length);
            sql.AppendFormat("select distinct a.CustomerCd from {0} a", tempTableName).AppendLine();
            sql.AppendLine("where not exists");
            sql.AppendLine("(select b.CustomerCd from ShopRelateMakerTBL b where a.OwnerId = b.OwnerId and a.CustomerCd = b.CustomerCd )");
            // 在商店别他品牌对应表(ShopRelateMakerTBL)中不存在的店号
            DataTable notExistsTable = this.DataAccessClient.ExecuteDataTable(sql.ToString());
            if (notExistsTable != null && notExistsTable.Rows.Count > 0)
            {
                foreach (DataRow row in notExistsTable.Rows)
                {
                    msg += row[0] + ",";
                }
                // 店号在商店别他品牌对应表中不存在,请仔细核对数据重新导入!
                msg = this.GetResourceString("StoreIdNotExist", msg.Substring(0, msg.Length - 1));
                return msg;
            }

            // 5.判断临时表中店铺所有的竞品品牌在ShopRelateMakerTBL表中是否存在,若不存在则给予提示并返回
            sql.Remove(0, sql.Length);
            sql.AppendLine("select t.*,mst.OtherMakerNm from ");
            sql.AppendLine("(");
            sql.AppendLine("    select omst.OwnerId, omst.CustomerCd,omst.OtherMakerCd");
            sql.AppendFormat("    from {0} omst", tempTableName).AppendLine();
            sql.AppendLine("    where not exists");
            sql.AppendLine("    (select srmt.OtherMakerCd from ShopRelateMakerTBL srmt ");
            sql.AppendLine("    where omst.OwnerId = srmt.OwnerId and omst.CustomerCd = srmt.CustomerCd and omst.OtherMakerCd = srmt.OtherMakerCd )");
            sql.AppendLine(") t ");
            sql.AppendLine("inner join OtherMakerMasTbl mst");
            sql.AppendLine("         on t.OwnerId = mst.OwnerId");
            sql.AppendLine("         and t.OtherMakerCd = mst.OtherMakerCd");
            List<ShopRelateMakerTBL> errorOtherMakerMasList = new List<ShopRelateMakerTBL>();
            this.DataAccessClient.FillQuery(errorOtherMakerMasList, sql.ToString());
            if (errorOtherMakerMasList.Count > 0)
            {
                var q = from e in errorOtherMakerMasList
                        group e by new { e.OwnerId, e.CustomerCd } into g
                        select new
                        {
                            StoreId = g.Key.CustomerCd,
                            OtherMakerNm = string.Join(",", g.Select(i => i.OtherMakerNm.Trim()))
                        };
                string str = string.Empty;
                q.ToList().ForEach(item => str += string.Format("[{0}:{1}]", item.StoreId, item.OtherMakerNm) + ",");
                // 店号{0}的竞品品牌主档数据在商店别他品牌对应表中不存在,请仔细核对数据重新导入!
                msg = this.GetResourceString("StoreOtherMakerNotExist", str.Substring(0, str.Length - 1));
                return msg;
            }

            // 6.把临时表中的数据插入到正式表OtherSaleMonthTbl(先删再插)
            sql.Remove(0, sql.Length);
            // 6.1 先删除 正式表中未确认的店铺精品销售数据
            sql.AppendLine("delete A ");
            sql.AppendLine("from OtherSaleMonthTbl A");
            sql.AppendFormat("inner join {0} B", tempTableName).AppendLine();
            sql.AppendLine("        on A.OwnerId = B.OwnerId");
            sql.AppendLine("        and A.CustomerCd = B.CustomerCd");
            sql.AppendLine("        and A.OtherSaleYM = B.OtherSaleYM");
            sql.AppendLine(" where ( A.ConfirmFlg != ‘1‘ or A.ConfirmFlg is null) "); // 未确认
            this.DataAccessClient.ExecuteNonQuery(sql.ToString());

            // 6.2 再删除 临时表中在正式表中已确认过的店铺销售数据
            sql.Remove(0, sql.Length);
            sql.AppendLine("delete B ");
            sql.AppendFormat("from {0} B", tempTableName).AppendLine();
            sql.AppendLine(" inner join OtherSaleMonthTbl A");
            sql.AppendLine("        on A.OwnerId = B.OwnerId");
            sql.AppendLine("        and A.CustomerCd = B.CustomerCd");
            sql.AppendLine("        and A.OtherSaleYM = B.OtherSaleYM");
            sql.AppendLine(" where A.ConfirmFlg = ‘1‘  "); // 已确认
            this.DataAccessClient.ExecuteNonQuery(sql.ToString());

            // 6.3 最后把临时表中的数据全部插入正式表
            sql.Remove(0, sql.Length);
            sql.AppendLine("INSERT INTO OtherSaleMonthTbl");
            sql.AppendLine("select * ");
            sql.AppendFormat("from {0} ", tempTableName).AppendLine();
            this.DataAccessClient.ExecuteNonQuery(sql.ToString());

            // 7.删除临时表
            sql.Remove(0, sql.Length);
            sql.AppendFormat("drop table {0}", tempTableName).AppendLine();
            this.DataAccessClient.ExecuteNonQuery(sql.ToString());

            return msg;
        }

时间: 2024-10-31 13:08:28

Excel文件处理Demo的相关文章

Java读写Excel文件DEMO

下载一定格式的Excel文件: @RequestMapping("/xxxx/xxxx/xxxx/copyfiledownload") @ResponseBody public void copyfiledownload(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception{ response.setContentType("text/html; char

vs创建控制台程序使用C++读写excel文件(ODBC方式)

1.创建一个vs项目,选择windows控制台应用程序,项目名称输入cppRWexcel 2.在StdAfx.h文件最下方加入如下代码: #include <iostream> #include <afxdb.h> #include <odbcinst.h> using namespace std; 3.在cppRWexcel.cpp中写入如下代码: // cppRWexcel.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h

在Node.js中使用ejsexcel输出EXCEL文件

1.背景 在Nodejs应用程序中输出Excel,第一印象想到的一般是node-xlsx,这类插件不仅需要我们通过JS写入数据,还需要通过JS进行EXCEL显示样式的管理. 这是个大问题,不仅代码冗余,而且非常不易于维护,假设业务需要合并一个单元格,或者换个颜色,我们都需要重新修改代码. 反思这个问题的核心,跟使用JS来操作页面样式其实是同一个道理,我们没有把数据/业务逻辑操作和样式分离. 在WEB开发中,我们有了CSS来分离处理样式的问题. 现在,在输出EXCEL的时候,我们也希望将样式问题分

NPOI导出为Excel文件

1.添加引用 2.将ExcelRender.cs和SqlHelper.cs两个类拷贝到App_Code文件夹下 3.写后台代码 eg:根据部门和日期导出成绩表 1 /// <summary> 2 /// 点击导出Excel 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 p

使用Open Xml按模版导出Excel文件(下)

(3)将数据写入Excel 把数据写入到Excel文件是本文的关键技术.这里需要用到OpenXml.在Sdk里已经提供了足够的文件操作方法,我们就调用这些方法,将数据源的数据写到文件中. 首先我们定义了一些工具类,用于读取单元格的行列值. 在Excel中,每个单元格都有一个地址:如B3表示第二行第三列的格子,在Utility中的GetRowIndex和GetColumnIndex就是输入字符串”B3”,返回Int类型的索引2 和3.还有输入“B3”,返回列的字母“B”等等. 在WorkSheet

.NET从EXCEL文件导入数据

.NET com组件 这种方法在计算机没有安装office套件时,也是能够使用的.所以不依赖于软件, 但是还是需要xcel.exe编译后的dll文件打包到相应的程序中来引用.这样将dll文件" 随身携带",就可以了.还是挺不错的! 1.注册Microsoft.Office.Interop.Excel.dll 在office安装文件夹下找到excel.exe,路径D:\Program Files(x86)\Microsoft Office\Office15.将excel.exe文件复制到

使用Python xlwt写excel文件

如果需要使用Python写Excel文件,首先下载或者安装xlwt. pip install xlwt 下面的这些demo应该可以帮助开发者快速上手使用xlwt写Excel文件: 创建工作簿(workbook)和工作表(sheet): import xlwt workbook = xlwt.Workbook() sheet = workbook.add_sheet("Sheet Name") 写单元格(cell): sheet.write(0, 0, 'foobar') # row,

将excel文件导入到数据库

参考:http://blog.csdn.net/jayxujia123/article/details/13684313 参考:http://kevin850115.iteye.com/blog/578142 MySQL官网:http://dev.mysql.com/doc/refman/5.7/en/load-data.html 学弟有个面试题,在群里问了下如何将excel文件导入到数据库.以前也没试过,正好在学习MySQL,练练手吧. 首先,将excel文件另存为用逗号分隔的csv文件,传到

MFC 与Excel文件的交互操作

假日快要结束了,带着沉重的心情写下之前关于MFC与Excel文件交互的总结.由于VS的版本不同可能在操作上有些差异,所以在此指明下本篇文章的工程环境为VS2013,也建议大家用最新的. 说到程序对于Excel的操作,应该不能算是什么新需求了,方法也有好几种,诸如利用office提供的接口.开源代码之类的.本文在查了一些资料之后选择了实现起来较为反便的一种.其实现的方法基本上完全照抄的这篇文章的,如果看本篇不大明白的可以去看看. 参考的文章说,"踏破铁鞋无觅处,得来费死了工夫",然而进过