Ole Db ,NPOI/TOXY, VSTO混合编程
来源:互联网 发布:淘宝卖人参 编辑:程序博客网 时间:2024/05/22 06:10
这个软件的功能主要实现了ERP或者叫CIMS中计划管理的核心功能,此类ERP基本就是按企业管理定制,很难有软件能适用所有企业,每个企业管理水平,资源配置,人员素质等等都 不一样,
原本想采用BS结构做一个数据库程序,但是需求是不断改变的,而且任务非常急。采用EXCEL做平台可以省去做界面的时间,也可以省去做数据库的时间,同时还省去了培训的时间。软件是随时管理需求在不断变化。Excel在不需要安装特别的客户端,有很多现成的图表可以使用。现在的代码量大约是10K行,当然也有许多垃圾在里面,
不吹牛了,两年前采用C++的一个类写了一个仪器的上位机程序,最后数据存到EXCEL,是通过COM来操作的,但C++在处理这些不确定类型的时候感觉比较麻烦(也许是自己水平不够),类型转换到现在都还是晕的,, 要用的时候只能去查了。虽然 我一直希望把C++坚持下去,但C++做这些的高层应用,是太麻烦了。
C#之前开发过一个AUTOCAD的插件,虽然最后做了大半中止了,但核心功能都实现了。
采用VSTO也是看了微软的说明 ,推荐使用.net,正好自己也用过C#,感觉效率比C++要高,
核心代码主要经过了几次大修改。
第1版主要是采用全部采用COM来读写cell数据。
第2版采用OLE DB来读数据,写采用COM。
第3版采用OLE DB读 ,,写是通过WIN剪切板。
第4版采用OLE DB读,写是通过TOXY/NPOI
每次的修改都是为了读写性能的提升,程序运行在至强CPU上面,第4版之前,统计全部数据最长时间需要4小时。第4版统计现在最多2分钟。
本想第4版把读取也改为toxy/NPOI,最近太忙也没时间,性能已完全满足需求了,所以也不花时间在上面了。
以下函数是初始化EXCEL模板的,有个问题要注意就是EXCEL的XML文件中,所有的样式都是引用的样式的ID,而不是引用样式本身,如果有5种样式就要创建5个
workbook.CreateCellStyle(),分别赋予,,而不能只能创建一个。
void init_npoi_workbook() { workbook = new XSSFWorkbook(); titlecellstyle = workbook.CreateCellStyle(); titlecellstyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; titlecellstyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; titlecellstyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; titlecellstyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; titlecellstyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; titlecellstyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; titlecellstyle.WrapText = true; for (int j = 0; j < block_count_weight_array.GetLength(1); j++) { cellstyle_array[j] = workbook.CreateCellStyle(); cellstyle_array[j].Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; cellstyle_array[j].VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; cellstyle_array[j].BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin; cellstyle_array[j].BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin; cellstyle_array[j].BorderRight = NPOI.SS.UserModel.BorderStyle.Thin; cellstyle_array[j].BorderTop = NPOI.SS.UserModel.BorderStyle.Thin; cellstyle_array[j].WrapText = true; cellstyle_array[j].BottomBorderColor = rowcolor[j]; cellstyle_array[j].TopBorderColor = rowcolor[j]; cellstyle_array[j].LeftBorderColor = rowcolor[j]; cellstyle_array[j].RightBorderColor = rowcolor[j]; cfont1[j] = workbook.CreateFont(); cfont1[j].Color = rowcolor[j]; cellstyle_array[j].SetFont(cfont1[j]); } foreach (int column in count_columns) { //按周、月统计周期0为周,1为月 int cols_4_count = 0; //if (0 == count_type) //{ cols_4_count = count_countperoids; ISheet sht = workbook.CreateSheet(column.ToString()); for (int j = 0; j < wlcountline_start; j++) { for (int i = 0; i < count_countperoids + 2; i++) { sht.CreateRow(j).CreateCell(i); } } //用来滚动周次日期 DateTime date_roll = new DateTime(); DateTime date_current_start = cal_week_year_start(count_startdate); //表头周历的第一周的第一天,循环过程中累加日期 date_roll = date_current_start.AddDays((cal_date_Year_week(count_startdate) - 1) * 7); //周历第一天,计算起点 if (1 == count_type) { d_year_start = date_roll; } IRow row = sht.CreateRow(4 - 1); for (int m = 0; m < cols_4_count; m++) { //填写表头上统计周期 sht.GetRow(4 - 1).CreateCell(wlcountline_column_start + m * wlcountline_column_per_month); //sht.CreateRow(4 - 1).CreateCell(wlcountline_column_start + m * wlcountline_column_per_month - 1); //sht.CreateRow(4 - 1).CreateCell(wlcountline_column_start + m * wlcountline_column_per_month ); // regon = new CellRangeAddress(4 - 1, 4 - 1, wlcountline_column_start + m * wlcountline_column_per_month - 1, wlcountline_column_start + m * wlcountline_column_per_month); // sht.AddMergedRegion(regon); //日 if (0 == count_type) { sht.GetRow(4 - 1).CreateCell(wlcountline_column_start + m * wlcountline_column_per_month - 1).SetCellValue(d_year_start.AddDays(m).ToShortDateString()); // sht.GetRow(4 - 1).GetCell( wlcountline_column_start + m * wlcountline_column_per_month - 1).SetCellValue() = "yyyy-m-d"; } //周 else if (1 == count_type) { string st1 = ""; st1 = cal_date_year(date_roll).ToString() + "-W" + cal_date_Year_week(date_roll).ToString() + "\n(" + date_roll.ToShortDateString() + ")"; row.CreateCell(wlcountline_column_start + m * wlcountline_column_per_month - 1).SetCellValue(st1); date_roll = date_roll.AddDays(7); } //月 else if (2 == count_type) { DateTime d_start; if (count_startdate.Day >= count_month_start) { //下月起始时间 d_start = new DateTime(count_startdate.AddMonths(m + 1).Year, count_startdate.AddMonths(m + 1).Month, count_month_start); } else { //本月的起始时间 d_start = new DateTime(count_startdate.AddMonths(m).Year, count_startdate.AddMonths(m).Month, count_month_start); } sht.GetRow(4 - 1).CreateCell(wlcountline_column_start + m * wlcountline_column_per_month - 1).SetCellValue(d_start.Year.ToString() + "-M" + d_start.Month.ToString()); } regon = new CellRangeAddress(4 - 1, 4 - 1, wlcountline_column_start + m * wlcountline_column_per_month - 1, wlcountline_column_start + m * wlcountline_column_per_month ); sht.AddMergedRegion(regon); } } }
以下是将统计结果从内存数组写到文件中,
public void toxy_writecache() { Excel.Application app = App; // app.ScreenUpdating = false; //try //{ // workbook = new XSSFWorkbook(); //} //catch (Exception ex) //{ // MessageBox.Show(ex.Message + ex.StackTrace); //} ICell cell, cell2; foreach (int column in count_columns) { ISheet sheet = workbook.GetSheet(column.ToString()); IRow row; for (int j = 0; j < block_count_weight_array.GetLength(1); j++) { row = sheet.CreateRow(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j - 1); //边框颜色 //cellstyle.BottomBorderColor = rowcolor[j]; //cellstyle.TopBorderColor = rowcolor[j]; //cellstyle.LeftBorderColor = rowcolor[j]; //cellstyle.RightBorderColor = rowcolor[j]; cellstyle = cellstyle_array[j]; for (int m = 0; m < 2; m++) { cell = row.CreateCell(m); cell.CellStyle = cellstyle; } int length = 0; // row = sheet.CreateRow( j); //分段清单明细,每2列填1列, for (int k = 0; k < block_count_weight_array.GetLength(2); k += 2) { cell = row.CreateCell(k + 2); cell2 = row.CreateCell(k + 1 + 2); regon = new CellRangeAddress(cell.RowIndex, cell.RowIndex, cell.ColumnIndex, cell.ColumnIndex + 1); cell.CellStyle = cellstyle; cell2.CellStyle = cellstyle; sheet.AddMergedRegion(regon); cell.SetCellValue(block_array[column, j, k]); if (length < block_array[column, j, k].Length) { length = block_array[column, j, k].Length; } } Int16 height = Convert.ToInt16(length / 17 * 15 * 8); if (height < 15) { height = 15; } // row.Height = 80; row = sheet.CreateRow(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j); for (int m = 0; m < 2; m++) { cell = row.CreateCell(m); cell.CellStyle = cellstyle; } for (int k = 0; k < block_count_weight_array.GetLength(2); k++) { if (k % 2 == 1) { cell = row.CreateCell(k + 2); cell.CellStyle = cellstyle; cell.SetCellValue("数量"); } else { cell = row.CreateCell(k + 2); cell.CellStyle = cellstyle; cell.SetCellValue("重量"); } } row = sheet.CreateRow(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j + 1); for (int m = 0; m < 2; m++) { cell = row.CreateCell(m); cell.CellStyle = cellstyle; } for (int k = 0; k < block_count_weight_array.GetLength(2); k++) { cell = row.CreateCell(k + 2); cell.CellStyle = cellstyle; cell.SetCellValue(block_count_weight_array[column, j, k]); } regon = new CellRangeAddress(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j, wlcountline_start + shipindex * temp_rows_4_ship + 3 * j + 1, 1, 1); sheet.AddMergedRegion(regon); sheet.GetRow(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j - 1).GetCell(1).SetCellValue(shipprojectname); sheet.GetRow(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j).GetCell(1).SetCellValue(rowname[j]); if (j == block_count_weight_array.GetLength(1) - 1) { regon = new CellRangeAddress(wlcountline_start + shipindex * temp_rows_4_ship - 1, wlcountline_start + shipindex * temp_rows_4_ship + 3 * j + 1, 0, 0); sheet.AddMergedRegion(regon); sheet.GetRow(wlcountline_start + shipindex * temp_rows_4_ship - 1).GetCell(0).SetCellValue(shipindex + 1); } } } }
附上剪切板写入EXCEL的函数
public void Write_cache() { Excel.Application app = App; // app.ScreenUpdating = false; Excel.Worksheet count_start_sheet = null; object m_objOpt = System.Reflection.Missing.Value; foreach (int column in count_columns) { //先按列名与统计表的表名比较得到表对象 for (int i = 0; i < wlbookcount.Worksheets.Count; i++) { if (wlbookcount.Worksheets.get_Item(i + 1).Name == column.ToString()) { count_start_sheet = wlbookcount.Worksheets.get_Item(i + 1); } } //输出至剪切板,再粘贴 int col_total = 0; if (count_type == 0) { col_total = 54; } else { col_total = 12; } for (int j = 0; j < block_count_weight_array.GetLength(1); j++) { string sData = ""; bool data_ed = false; for (int k = 0; k < block_count_weight_array.GetLength(2); k += 2) { if (k < block_count_weight_array.GetLength(2) - 2) //if (block_array[column, j, k] == "") // sData += "\t\t"; //else { sData += block_array[column, j, k] + "\t\t"; data_ed = true; } else //if (block_array[column, j, k] == "") // sData += "\t\r\n"; //else { sData += block_array[column, j, k] + "\t\r\n"; data_ed = true; } //if (k >= col_total) //{ // break; //} } if (data_ed) { System.Windows.Forms.Clipboard.SetDataObject(sData); Excel.Range rg = count_start_sheet.Cells.get_Item(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j, 3); count_start_sheet.Activate(); count_start_sheet.Paste(rg, false); } } for (int j = 0; j < block_count_weight_array.GetLength(1); j++) { string sData = ""; bool data_ed = false; for (int k = 0; k < block_count_weight_array.GetLength(2); k++) { if (k < block_count_weight_array.GetLength(2) - 1) //if (block_count_weight_array[column, j, k] > 0.1f) { sData += block_count_weight_array[column, j, k].ToString() + "\t"; data_ed = true; } //else // sData += "0\t"; else //if (block_count_weight_array[column, j, k] > 0.1f) { sData += block_count_weight_array[column, j, k].ToString() + "\r\n"; data_ed = true; } //else // sData += "0\r\n"; } if (data_ed) { System.Windows.Forms.Clipboard.SetDataObject(sData); Excel.Range rg = count_start_sheet.Cells.get_Item(wlcountline_start + shipindex * temp_rows_4_ship + 2 + 3 * j, 3); count_start_sheet.Activate(); count_start_sheet.Paste(rg, false); } } /* for (int j = 0; j < block_array.GetLength(1); j++) { for (int k = 0; k < block_array.GetLength(2); k += 2) { if (block_array[column, j, k] != "") count_start_sheet.Cells.get_Item(wlcountline_start + shipindex * temp_rows_4_ship + 3 * j, wlcountline_column_start + k).Value = block_array[column, j, k]; } } for (int j = 0; j < block_count_weight_array.GetLength(1); j++) { for (int k = 0; k < block_count_weight_array.GetLength(2); k++) { if (block_count_weight_array[column, j, k] > 0.1) count_start_sheet.Cells.get_Item(wlcountline_start + shipindex * temp_rows_4_ship + 2 + 3 * j, wlcountline_column_start + k).Value = block_count_weight_array[column, j, k]; } } */ // app.ScreenUpdating = false; } }
另,引这个库的时候报了一个异常,在NPOI的群中询问也没得到结果,最后是直接在VS的异常监控中把这个项去掉就行了,程序工作正常。
TOXY、NPOI的功能远不止读写EXCEL文件,其他 的功能没有用过,就不作讨论了。
水平有限,如有错误 ,敬请指出。
在此要感谢TONY Qu,他是toxy /NPOI的作者,
npoi.codeplex.com
toxy.codeplex.com
- Ole Db ,NPOI/TOXY, VSTO混合编程
- OLE DB 的概念和编程
- ole db的概念与编程
- OLE DB
- OLE DB
- OLE DB
- ole db
- OLE DB
- OLE DB API 程序设计
- OLE DB备考
- OLE DB 的概念
- ADO ,OLE DB ,ODBC
- OLE DB 源
- ODBC, OLE DB, ADO
- ole db 连接oracle
- OLE DB 是什么?
- PB下的OLE DB
- ADO/OLE DB数据源对话框
- Top 10 jQuery Mobile Code Snippets that you need to know
- Java-反射
- Fedora 20下安装Google PinYin输入法
- nike WzK54 8q5V 89Vd
- ubuntu tomcat开机自动启动
- Ole Db ,NPOI/TOXY, VSTO混合编程
- [大洋] Unity3D架构系列之- FSM有限状态机设计一至四
- IOS SDK详解之KVO
- for标签之从大到小和嵌套循环
- poj 1655 树形dp求取树的重心
- Unity3D架构系列之- FSM有限状态机设计四至六
- 配置恢复出发异常中断的解析
- [麦克死特] ugui 一点点看法
- Matlab接收串口数据