总结一下很久之前做的报表小程序,今日有问题又调试了一下。
DB中存在一个表,记录了ID<自增长>,SqlStatement<sql查询语句>及其他必要字段,比如SheetName,ReferenceTable,InertDate等等
任务是循环表记录,针对SqlStatement语句查询结果,对应dataTable,如有数据则以一个sheet显示出来,如果没有数据则略过。
以下是循环生成sheet的代码:
public static void Create(ref Workbook xBook, ref Application xApp, out string ReportDate) { Hashtable hash = new Hashtable(); IT_Check_ReportMgr reportMgr = new IT_Check_ReportMgr(); System.Data.DataTable ItCheckEecel = new System.Data.DataTable();//为了避免不明确引用 Worksheet ws; int idcount; reportMgr.Get_ITCheckID_Data(out idcount); DataSet ds = new DataSet(); ds = reportMgr.Get_ITCheck_Data(); string strReportDate = reportMgr.GetFlieGenerateDate(); ReportDate = strReportDate; string key = string.Empty; for (int i = 0; i < ds.Tables.Count;i++ ) { key = "dt" + i.ToString(); if (ds.Tables[i].Rows.Count==0) continue;//如果DT没有数据,则终止当前,开始新的循环 hash.Add(key, ds.Tables[i]); ws = (Worksheet)xBook.Sheets[xBook.Sheets.Count]; //获取sheet名 if (reportMgr.GetSheetName(i).Length >= 31) { ws.Name = reportMgr.GetSheetName(i).Substring(0, 30); } else { ws.Name = reportMgr.GetSheetName(i); } IT_Check_Report_Sheet sheetNew = new IT_Check_Report_Sheet(ref ws); sheetNew.Generate(hash, ws.Name, i); if ( i+1==ds.Tables.Count) continue; xBook.Sheets.Add(Type.Missing, xBook.Sheets[xBook.Sheets.Count], Type.Missing, Type.Missing); } hash.Clear(); ////删除无用的sheet //xApp.DisplayAlerts = false; //如果想删除某个sheet页,首先要将此项设为fasle,最开始生成excel因工作薄内至少含有一张可视工作表,开始时不可删除 //for (int i = 1; i < xApp.Worksheets.Count; i++) //{ // if (((Worksheet)xApp.Worksheets[i]).Name.IndexOf("Sheet")> -1)//sheetName中是否包含带有sheet名的工作表 // { // (xApp.ActiveWorkbook.Sheets[i] as Worksheet).Delete(); // } //} //xApp.DisplayAlerts = false; //把Sheet定位到第一个 Worksheet wsh = (Worksheet)xBook.Sheets[1]; wsh.Activate(); }
调试监视:
以下是generate方法,调用的fill方法<带excel-sheet表头>:
public bool Generate(Hashtable hash,string SheetName,int i) { System.Data.DataTable dt1 = (System.Data.DataTable)hash["dt"+i.ToString()]; sheet.Name = SheetName; sheet.Tab.Color = 0xFFFF; if (dt1.Rows.Count == 0) { return false; } Fill(dt1, startRowIndex, startColIndex, true); //设置列标题栏位 IT_Check_TitleStyle(dt1, sheet, dt1.Rows.Count); //增加筛选功能 IT_Check_HeaderFileter(dt1,sheet); return true; } protected void Fill(System.Data.DataTable dt, int rowStart, int colStart, bool isFormat) { int p = 80000; for (int beginIndex = 0; beginIndex < dt.Rows.Count; beginIndex += p) { int endIndex = dt.Rows.Count - 1; if (beginIndex + p < dt.Rows.Count) { endIndex = beginIndex + p - 1; } //dt先填充到二维数组中,再添加到range对象效率会高,用时变少 //填充sheet的列名 object[,] arr = new object[endIndex - beginIndex + 2, dt.Columns.Count]; for (int i = 0; i < dt.Columns.Count;i++ ) { arr[0,i]=dt.Columns[i].ColumnName; } for (int i = beginIndex; i <= endIndex; i++) { for (int j = 0; j < dt.Columns.Count; j++) { arr[i - beginIndex +1, j] = dt.Rows[i][j].ToString().Replace("=", ""); } } Range range = sheet.get_Range(sheet.Cells[rowStart + beginIndex + 1, colStart + 1], sheet.Cells[rowStart + endIndex + 2, colStart + dt.Columns.Count]); range.Rows.NumberFormat = "@";//在填充之前先设置整个range是text类型 if (isFormat) { // range.NumberFormat = "#,##0.00"; } range.Value2 = arr;//二维数组填充到range range.Borders.LineStyle = XlLineStyle.xlContinuous; range.Columns.EntireColumn.AutoFit();//设置列宽自动适应 } }
另:回顾一下Break/Continue的用法:
循环的定义是程序段执行完了以后,再次判断条件,若条件为真,则继续执行该程序段。而在switch结构当中,只是该程序段执行完了之后,就继续执行下面的语句。因此很明显switch结构不是循环。循环有重复、反复执行的功能。
break是跳出整个循环,而continue是结束本次循环!进入下一次循环!
break是不是只针对 for、while、switch 起作用,break的用处可以有两个:
第一:用在switch结构当中的case语句的后面,作用是不再执行后面的case语句,结束switch结构。<选择,退出分支,是条件控制语句,可以用ifelse代替>
第二:用在循环当中,作用是终止该循环的执行,继续执行程序中循环下面的语句。如果有嵌套,只能跳出一层。<结束循环,即跳出与当前该语句最近的循环>如:for循环内if判断语句为真break,则会跳出for循环
例:遍历dr in DataTable,向DB逐条insert语句插入数据,对每dr进行条件筛选,如不符合,则添加errorMsg发送邮件,并结束本次循环,开始下一条dr:
private void POS_3C_Sale_DSG(string strExrName, string strPathFileName, string strFileName, string FileName, string DataRange, string strCountryCode) { var dt = ReadExcelToTable(strPathFileName); //dt.Rows.RemoveAt(0); SqlConnection con = new SqlConnection(Connstr); SqlCommand cmd = new SqlCommand(); cmd.Connection = con; con.Open(); int num = 0, num1 = 0; string strHead = "insert into POS3C_Sale(DataRange,SaleDate,C3AcerRegionTemp,C3ProvinceTemp,C3CityTemp,C3Code,DataType,C3BigAreaCode,C3BigAreaName,C3BranchCode,C3BranchName,C3StoreCode,C3StoreName,C3ProductCode,C3AcerProductCode,C3ProductName,C3BiProductName,C3Brand,C3ProductType1,C3ProductType2,C3ProductType2Name,C3CustomerCode,C3CustomerName,C3ChannelType,C3ChannelName,SaleQty,C3BuyType,C3BuyOrganize,C3ShipAddr,C3SellType,C3OtherInfo1,C3OtherInfo2,C3OtherInfo3,C3OtherInfo4,C3OtherInfo5,C3AcerStoreCode,C3AcerStoreName,DataSource,InsertDate) values ", strError = ""; Dictionary<DataRow, string> ExcelList = new Dictionary<DataRow, string>(); foreach (DataRow dr in dt.Rows) { num1++; try { string DataRang = DataRange; string SaleDate = dr[0].ToString(); DateTime date; string C3AcerRegionTemp=dr[1].ToString(); string C3ProvinceTemp=dr[2].ToString(); string C3CityTemp = dr[3].ToString(); //C3Code-->strCountryCode string DataType = (DataRange.IndexOf("w")>-1?"Weekly":"Monthly"); string C3BigAreaCode = ""; string C3BigAreaName = ""; string C3BranchCode = ""; string C3BranchName = ""; string C3StoreCode = "";//门店代码 string C3StoreName = "";//门店名称 string C3ProductCode = ""; string C3AcerProductCode = dr[8].ToString(); string C3ProductName = ""; string C3BiProductName = ""; string C3Brand = ""; string C3ProductType1 = ""; string C3ProductType2 = ""; string C3ProductType2Name = ""; string C3CustomerCode = ""; string C3CustomerName = ""; string C3ChannelType = ""; string C3ChannelName = ""; int SaleQty = dr[10].ToString() == "" ? 0 : Convert.ToInt32(dr[10]); string C3BuyType=""; string C3BuyOrganize=""; string C3ShipAddr=""; string C3SellType=""; string C3OtherInfo1=""; string C3OtherInfo2=""; string C3OtherInfo3 = ""; string C3OtherInfo4 = ""; string C3OtherInfo5 = ""; string C3AcerStoreCode = dr[5].ToString(); string C3AcerStoreName = dr[6].ToString(); string DataSource = strFileName; //string InserData=DateTime.Now.ToString(); if (SaleDate == "" || C3AcerProductCode == "")//|| C3AcerStoreCode == "" || C3AcerStoreName == "" { strError += "数据问题 "; num++; var Collect = SaleDate == "" ? "销售日期 " : ""; Collect += C3AcerProductCode == "" ? "料号信息 " : ""; //Collect += C3AcerStoreCode == "" ? "32门店代码 " : ""; //Collect += C3AcerStoreName == "" ? "32门店名称 " : ""; ExcelList.Add(dr, Collect + "为空"); continue; } if (!DateTime.TryParse(SaleDate.ToString(), out date)) { SaleDate = "1990-1-1"; } else { SaleDate = date.ToString("yyyy-MM-dd"); } string strTail = "('" + DataRange + "','"+ SaleDate + "','" + C3AcerRegionTemp + "','" + C3ProvinceTemp + "','" + C3CityTemp + "','" + strCountryCode + "','" + DataType + "','" + C3BigAreaCode + "','" + C3BigAreaName + "','" + C3BranchCode + "','" + C3BranchName + "','" + C3StoreCode + "','" + C3StoreName + "','" + C3ProductCode + "','" + C3AcerProductCode + "','" + C3ProductName + "','" + C3BiProductName + "','" + C3Brand + "','" + C3ProductType1 + "','" + C3ProductType2 + "','" + C3ProductType2Name + "','" + C3CustomerCode + "','" + C3CustomerName + "','" + C3ChannelType + "','" + C3ChannelName + "'," + SaleQty + ",'" + C3BuyType + "','" + C3BuyOrganize + "','" + C3ShipAddr + "','" + C3SellType + "','" + C3OtherInfo1 + "','" + C3OtherInfo2 + "','" + C3OtherInfo3 + "','" + C3OtherInfo4 + "','" + C3OtherInfo5 + "','" + C3AcerStoreCode + "','" + C3AcerStoreName + "','" + DataSource + "',"+ "getdate())"; cmd.CommandText = strHead + strTail; cmd.ExecuteNonQuery(); } catch (Exception ex) { strError += ex.Message + " "; num++; ExcelList.Add(dr, ex.Message); } } con.Close(); Helper.AutomaticExcle(sErrorDirectory + FileName, @"销售日期,专区,省份,城市,销售门店,32门店代码,32门店名称,编码,料号,描述,数量", ExcelList, "POS3C_Sale"); var CurrentTime = DateTime.Now.ToString("yyyy-MM-dd"); Helper.SavaPOS_3CLog(" " + strFileName + " " + "成功:" + (num1-num) + "条,失败" + num + "条。", POS3CLog); Helper.SavaPOS_3CLog(strFileName + " " + strError, SaleLog); if (num == 0) { var ErrorContents = strFileName + "。excel中一共有" + num1 + "行数据,成功导入数据:" + num1 + "行。"; Mail.SendMail("(" + strCountryCode + ")POS3C Sale信息导入成功" + CurrentTime, "", ErrorContents); } else { sMoveDirectory = sErrorDirectory; strError = strFileName + " 错误信息!"; var ErrorContents = strFileName + "。 excel中一共有" + num1 + "行数据, 实际成功导入:" + (num1 - num) + "行。 执行失败:" + num + "行。详细信息请看附件"; Mail.SendMail("(" + strCountryCode + ")POS3C Sale错误信息" + CurrentTime, sErrorDirectory + FileName, ErrorContents); } //移动到的路径 string SubdirectoryPath = sMoveDirectory + "\" + DateTime.Now.ToString("yyyy-MM") + "\"; if (!System.IO.Directory.Exists(SubdirectoryPath)) { System.IO.Directory.CreateDirectory(SubdirectoryPath); } //使用复制为了覆盖文件夹下已有的该文件 File.Move(strPathFileName, SubdirectoryPath + "\" + strFileName); }