Microsoft Office 2003 Web Components 自动计数/自动求和
1.Microsoft Office 2003 Web Components 简介:
Microsoft Office Web Components are a collection of Component Object Model (COM) controls for publishing spreadsheets, charts, and databases to the Web. They are also used to view these items when published and to view data access pages.If you have Microsoft Office FrontPage 2003, Microsoft Office Access 2003, and Microsoft Office Excel 2003 installed, Office Web Components allow you to publish interactive data as part of a Web page. Used with Microsoft Internet Explorer version 5.01 or later, Office Web Components allow you to view a published control (spreadsheet, chart, or database) on a Web page and to view data access pages.
2.AxMicrosoft.Office.Interop.Owc11.AxSpreadsheet 也可以集成到WinForm程序上(添加Microsoft.Office.Interop.Owc11.dll引用),
但集成的时候是没有右下角的求和/计数显示的,而且Microsoft Office 2003 Web Components之后也没有更新的版本。
3.我们可以在Excel控件下面在添加一个Label控件(labelTotal),用来显示求和/计数;
具体代码如下:
(1):Excel控件的事件
ssExcel:AxMicrosoft.Office.Interop.Owc11.AxSpreadsheet 控件
1 using System.Collections.Generic; 2 using System.Linq; 3 using System.Text.RegularExpressions; 4 using Microsoft.Office.Interop.Owc11; 5 //https://www.cnblogs.com/yellow3gold/ 6 private List<Range> selectedRangeList = new List<Range>();//在Excel上选中的Range集合 7 8 //ssExcel为Excel控件 9 //鼠标操作事件 10 private void ssExcel_MouseUpEvent(object sender, AxMicrosoft.Office.Interop.Owc11.ISpreadsheetEventSink_MouseUpEvent e) 11 { 12 if (e.shift == 2) 13 selectedRangeList.Add(ssExcel.Selection); 14 else 15 { 16 selectedRangeList.Clear(); 17 selectedRangeList.Add(ssExcel.Selection); 18 } 19 AutoTotal(); 20 } 21 22 //键盘操作事件 23 private void ssExcel_KeyUpEvent(object sender, AxMicrosoft.Office.Interop.Owc11.ISpreadsheetEventSink_KeyUpEvent e) 24 { 25 /*e.shift=1/Shift 代表按住了Shift键 26 e.shift=2/Ctrl 代表按住了Ctrl键 27 e.shift=3/Ctrl+Shift 代表同时按住了Ctrl+Shift键*/ 28 if (e.shift == 0 && e.keyCode > 36 && e.keyCode < 41) 29 AutoTotal(); 30 if (e.shift > 0 && e.keyCode > 36 && e.keyCode < 41) 31 { 32 selectedRangeList.Clear(); 33 selectedRangeList.Add(ssExcel.Selection); 34 AutoTotal(); 35 } 36 }
(2):求和的方法
1 //labelTotal为显示求和/计数的label 2 public void AutoTotal() 3 { 4 //https://www.cnblogs.com/yellow3gold/ 5 var cellList = new List<object>(); 6 var rangeList = GetValidRangeList(selectedRangeList); 7 foreach (var range in rangeList) 8 { 9 var datas = GetRangeValue(range); 10 cellList.AddRange(datas.Cast<object>().Where(x => !string.IsNullOrWhiteSpace(Convert.ToString(x)))); 11 } 12 if (cellList.Count > 0) 13 { 14 decimal totalNum = 0M; 15 int totalCount = 0; 16 bool notnum = false; 17 try 18 { 19 var isallEmpty = cellList.All(x => string.IsNullOrWhiteSpace(Convert.ToString(x))); 20 if (isallEmpty) 21 { 22 labelTotal.Text = string.Empty; 23 return; 24 } 25 foreach (var item in cellList) 26 { 27 if (item != null && Regex.IsMatch(Convert.ToString(item), @"^-?\d+\.?\d*%$")) 28 { 29 totalNum += Convert.ToDecimal(Convert.ToString(item).Replace("%", "")) / 100; 30 totalCount += 1; 31 } 32 else if (item != null && Regex.IsMatch(Convert.ToString(item), @"^-?\d+\.?\d*$")) 33 { 34 totalNum += Convert.ToDecimal(Convert.ToString(item)); 35 totalCount += 1; 36 } 37 else 38 { 39 if (item != null && !string.IsNullOrWhiteSpace(Convert.ToString(item))) 40 { 41 notnum = true; 42 totalCount += 1; 43 } 44 } 45 } 46 if (notnum && totalCount != 0) 47 labelTotal.Text = @"计数:" + totalCount; 48 else 49 labelTotal.Text = @"求和:" + totalNum; 50 } 51 catch (Exception ex) 52 { 53 labelTotal.Text = string.Empty; 54 } 55 } 56 else 57 labelTotal.Text = string.Empty; 58 }
(3):一些的基础方法
1 //获取有效的选中区域 2 private List<Range> GetValidRangeList(List<Range> selectedRangeList) 3 { 4 List<Range> resultList = new List<Range>(); 5 Range uRange = ssExcel.ActiveSheet.UsedRange; 6 Range userRange = GetRange(0, 0, uRange.Column + uRange.Columns.Count - 1, uRange.Row + uRange.Rows.Count - 1); 7 foreach (Range range in selectedRangeList) 8 resultList.Add(LimiteRange(range, userRange)); 9 return resultList; 10 } 11 //https://www.cnblogs.com/yellow3gold/ 12 public Range GetRange(int row, int col, int width, int height) 13 { 14 return ssExcel.get_Range(ssExcel.Cells[row + 1, col + 1], ssExcel.Cells[row + height, col + width]); 15 } 16 //https://www.cnblogs.com/yellow3gold/ 17 //获取交集 18 private Range LimiteRange(Range range1, Range range2) 19 { 20 int width = range1.Columns.Count; 21 int height = range1.Rows.Count; 22 if (range1.Columns.Count >= range1.EntireRow.Columns.Count) 23 width = range2.Columns.Count - range1.Column + 1; 24 if (range1.Rows.Count >= range1.EntireColumn.Rows.Count) 25 height = range2.Rows.Count - range1.Row + 1; 26 if (width != range1.Columns.Count || height != range1.Rows.Count) 27 return GetRange(range1.Row - 1, range1.Column - 1, width, height); 28 else 29 return range1; 30 } 31 //https://www.cnblogs.com/yellow3gold/ 32 //获取选中区域的数据 33 private object[,] GetRangeValue(Range range) 34 { 35 if (range.Rows.Count == 1 && range.Columns.Count == 1) 36 { 37 object[,] datas = new object[2, 2]; 38 datas[1, 1] = range.get_Value(Type.Missing); 39 return datas; 40 } 41 else 42 return (object[,])range.get_Value(Type.Missing); 43 }