程式开发中导出数据到EXCEL中遇到的一个问题小解

问题描述:做一个项目,里面用到将资料导出到EXCEL,使用的是EXCEL.DLL,因为数据量比较大,如果用CELLS一个一个填充的话需要很久时间才能完成,故我采用的是将EXCEL做为DATATABLE来操作,但这样导出的EXCEL使用公式计算,比如SUM,得出的结果全为零,后来发现只要编辑一下单元格(双击单元格数据),该单元格就能参与公式计算了.这种问题甚是奇怪.
解决方法:只用放弃将EXCEL做为表来操作的方法.回到使用EXCEL组件来操作,不使用CELL一个一个填充,而是先选中要填充的范围,然后整个赋值,这种方法还是比较快的,这里只能使用FORMULAARRAY这个属性,才能使导出的EXCEL直接参与计算,不知为何?
以下为详细代码,以做MARK:
实现的功能:表头与数据来源可分开,生成EXCEL时可分别设置.
隐藏第一列,第2 3 4列合并相同的行.相同行的最后一行可设置颜色.
杀掉EXCEL进程.     

  string  FileFullPath  =    " ../Download/ "   +  Session[ " userID " ].ToString()  +   " _DPS_ "   +  DateTime.Now.ToString( " yyyyMMdd_hhmmss " )   +   " (本月).xls " ;
                     
            DateTime start 
=  DateTime.Now;             // 記錄進程開始的時間間隔
            Excel.Application app  =   new  Excel.ApplicationClass();
            app.Visible 
=   false ;
            app.DisplayInfoWindow 
=   false ;
            DateTime end 
=  DateTime.Now;                // 記錄進程的結束時間間隔
            Excel.Workbooks books  =  app.Workbooks;
            
try
            {
                Excel.Workbook book 
=  books.Add(Missing.Value);
                Excel.Worksheet sheet 
=  (Excel.Worksheet) book.Sheets[ 1 ];
                sheet.Name 
=   " 2007-08-10 " ;           
                
string  SheetName  =  sheet.Name;            // 工作表名稱

                
// 標題頭,在excel第一列寫入標題
                 string [] headdata  =  btnExcel.Attributes[ " headdata " ].Split( " | " .ToCharArray()); // 表头数据
                 for ( int  i = 0 ; i < headdata.Length; i ++ )
                {
                    Excel.Range range 
=  (Excel.Range) sheet.Cells[ 1 , i  +   1 ];
                    range.NumberFormatLocal 
=   " @ " ;        // 設定為文本格式
                    range.HorizontalAlignment  =  Excel.Constants.xlCenter;
                    range.set_Value(Missing.Value, headdata[i].Replace(
" <br> " " \r\n " ));
                }
                
// 輸出標題頭結束

                
// 以下輸出數據列
                ArrayList tmpRange  =   new  ArrayList();     // 保存需要變色的行
                 string [] size  =  { "" , "" ,gridData.Items[ 0 ].Cells[ 2 ].Text.Trim(),gridData.Items[ 0 ].Cells[ 3 ].Text.Trim(),gridData.Items[ 0 ].Cells[ 4 ].Text.Trim()};
                
string [,] ss  =   null ;            // 保存數據的二維數組
                 int  row  =   0 ,colCount  =   0 ;       // 有多少行數據,多少列
                 for ( int  i = 0 ; i < gridData.Items.Count; i ++ )
                {
                    Button button 
=  (Button) gridData.Items[i].Cells[ 0 ].Controls[ 0 ];
                    
string [] rowdata  =  button.Attributes[ " rowdata " ].Split( " | " .ToCharArray());
                    
if (i == 0 )
                    {
                        row 
=  gridData.Items.Count;
                        colCount 
=  rowdata.Length;
                        ss 
=   new   string [row,colCount];
                    }
                    
for ( int  j = 0 ;j < rowdata.Length;j ++ )
                    {
                        ss[i,j] 
=  rowdata[j].Replace( " &nbsp; " , "" ); // 將數據保存在二維數組中
                    }
                    
for ( int  h = 2 ;h < 5 ;h ++ )                       // 將第2列到第4列相同行的列數值保存起來用於后面合并單元格
                    {
                        
if (gridData.Items[i].Cells[h].Text  !=  size[h] )     // 某個panelsize改變后變色
                        {
                            
string  rownum  =   "" ; // 行數不能超過10萬,不然合并會出錯的,可以通過下面添加0擴大範圍
                             switch ((i + 2 ).ToString().Length)
                            {
                                
case   1 :
                                    rownum 
=   " 00000 "   +  (i + 2 ).ToString();
                                    
break ;
                                
case   2 :
                                    rownum 
=   " 0000 "   +  (i + 2 ).ToString();
                                    
break ;
                                
case   3 :
                                    rownum 
=   " 000 "   +  (i + 2 ).ToString();
                                    
break ;
                                
case   4 :
                                    rownum 
=   " 00 "   +  (i + 2 ).ToString();
                                    
break ;
                                
case   5 :
                                    rownum 
=   " 0 "   +  (i + 2 ).ToString();
                                    
break ;
                            }
                            
string  tmpValue  =  h.ToString()  +   " , "   +  rownum;
                            
if ( ! tmpRange.Contains(tmpValue))
                                tmpRange.Add(tmpValue);                              
                            size[h] 
=  gridData.Items[i].Cells[h].Text.Trim();                        
                        }
                        
else
                            
if ( i  ==  (row - 1 ))
                        {
                            
string  rownum  =   "" ; // 行數不能超過10萬,不然合并會出錯的,可以通過下面添加0擴大範圍
                             switch ((i + 3 ).ToString().Length)
                            {
                                
case   1 :
                                    rownum 
=   " 00000 "   +  (i + 3 ).ToString();
                                    
break ;
                                
case   2 :
                                    rownum 
=   " 0000 "   +  (i + 3 ).ToString();
                                    
break ;
                                
case   3 :
                                    rownum 
=   " 000 "   +  (i + 3 ).ToString();
                                    
break ;
                                
case   4 :
                                    rownum 
=   " 00 "   +  (i + 3 ).ToString();
                                    
break ;
                                
case   5 :
                                    rownum 
=   " 0 "   +  (i + 3 ).ToString();
                                    
break ;
                            }
                            
string  tmpValue  =  h.ToString()  +   " , "   +  rownum;
                            
if ( ! tmpRange.Contains(tmpValue))
                                tmpRange.Add(tmpValue);                              
                        }
                    }
                }
                Excel.Range rng1 
=  (Excel.Range)sheet.Cells[ 2 , 1 ];        // 選中開始的第一個格
                rng1  =  rng1.get_Resize(row,colCount);                    // 選中要填充的範圍
                rng1.NumberFormatLocal  =   " #,##0_  " ;                      // 千分號
                rng1.FormulaArray  =  ss;                                  // 好象必用此方法,導出的excel才能用公式計算,此法比cell填充效率快很多
                
// 輸出數據列結束

                
// 設置樣式
                sheet.UsedRange.Columns.AutoFit();
                Excel.Borders borders 
=  ((Excel.Borders) sheet.UsedRange.Borders);
                borders.LineStyle 
=  Excel.XlLineStyle.xlContinuous;
                borders.Weight 
=  Excel.XlBorderWeight.xlHairline;

                ((Excel.Range) sheet.Columns[
" A:A " , Missing.Value]).Hidden  =   true // 隱藏第一列
                
// 凍結儲存格
                ((Excel.Range) sheet.Cells[ 2 , 6 ]).Select();
                app.ActiveWindow.FreezePanes 
=   true ;
//                 app.ActiveWorkbook.ExclusiveAccess();   // 去掉"共用",不能用

                
// 合并相同的列
                tmpRange.Sort();                
                
string [] ChangeColors  =  tmpRange.ToArray( typeof (System.String))  as   string [];     
                
int  startrow  =   2 ;
                ArrayList tmpArray 
=   new  ArrayList();
                
foreach ( string  index  in  ChangeColors)
                {
                    
int  colNum  =   int .Parse(index.Split( " , " .ToCharArray())[ 0 ]);             // 列數值
                     if ( ! tmpArray.Contains(colNum))
                    {
                        startrow 
=   2 ;
                        tmpArray.Add(colNum);
                    }                   
                    
int  rowNum  =   int .Parse(index.Split( " , " .ToCharArray())[ 1 ]);             // 行數值
                    Excel.Range range  =  (Excel.Range)sheet.get_Range(sheet.Cells[startrow,colNum],sheet.Cells[rowNum - 1 ,colNum]);
                    
string  Value  =  ((Excel.Range)sheet.Cells[startrow,colNum]).Text.ToString() ;
                    range.ClearContents();
                    range.MergeCells 
=   true ;
                    range.set_Value(Type.Missing,Value);
                    range.HorizontalAlignment 
=  Excel.XlHAlign.xlHAlignCenter;
                    range.VerticalAlignment 
=  Excel.XlVAlign.xlVAlignCenter;
                    startrow 
=  rowNum;

                    
// 相同行的最后一行變色
//                     Excel.Range rng = (Excel.Range)sheet.Rows[rowNum-1,Type.Missing];
//                     rng.Interior.ColorIndex = 50;  
                }  
               
                
// 保存成文件
                book.SaveAs(Server.MapPath(FileFullPath), Missing.Value, Missing.Value, Missing.Value, 
                    Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlShared, Excel.XlSaveConflictResolution.xlLocalSessionChanges, 
                    Missing.Value,Missing.Value, Missing.Value, Missing.Value); 

                book.Close(
true , Missing.Value, Missing.Value);
                
#endregion
                
// 開始下載生成的文件
                Response.Redirect(FileFullPath, true );
            }
            
catch (Exception Err)
            {
                getMessage(Err.Message);
            }
            
finally
            {
                app.Quit();
                
if (app  !=   null )
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                    app 
=   null ;
                }
                
if (Server.MachineName.ToUpper()  !=  DataOP.Instance.MachineName.ToUpper())
                    DataOP.Instance.KillExcelProcess(start,end);
                GC.Collect(); 
            }  

      

转载于:https://www.cnblogs.com/zzyyll2/archive/2007/09/12/890818.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值