凯锐

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  96 随笔 :: 39 文章 :: 212 评论 :: 23 引用
C#導出Excel方法有多種﹐常用的按照Microsoft 的方法如下:
1﹑"Use Automation to Transfer Data Cell by Cell "
2﹑"Use Automation to Transfer an Array of Data to a Range on a Worksheet "
3﹑"Use Automation to Transfer an ADO Recordset to a Worksheet Range "
4﹑"Use Automation to Create a QueryTable on a Worksheet"
5﹑"Use the Clipboard"
6﹑"Create a Delimited Text File that Excel Can Parse into Rows and Columns"
7﹑"Transfer Data to a Worksheet Using ADO.NET "
在此本人主要使用第4種方法:即利用Excel的QueryTable導出海量數據。
要利用Excel的QueryTable的方法﹐首先需要引用Excel類庫。這個我就不多說了。
第二步就是新增一個窗體文件﹐為簡單起見﹐只在窗體上加一個button按鈕。在Button Click事件中加入操作的代碼。整個操作﹐我只在一個類中實現﹐源碼附貼如下(office2003)﹕
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication3
{
    
public partial class Form1 : Form
    {
        
private Microsoft.Office.Interop.Excel.Application m_objExcel = null;
        
private Microsoft.Office.Interop.Excel.Workbooks m_objBooks = null;
        
private Microsoft.Office.Interop.Excel._Workbook m_objBook = null;
        
private Microsoft.Office.Interop.Excel.Sheets m_objSheets = null;
        
private Microsoft.Office.Interop.Excel._Worksheet m_objSheet = null;
        
private Microsoft.Office.Interop.Excel.Range m_objRange = null;
        
//private Microsoft.Office.Interop.Excel.Font m_objFont = null;
        
//private Microsoft.Office.Interop.Excel.QueryTables m_objQryTables = null;
        private Microsoft.Office.Interop.Excel._QueryTable m_objQryTable = null;
        
// Frequenty-used variable for optional arguments.
        private object m_objOpt = System.Reflection.Missing.Value;
        
//DataBase-used variable
        private System.Data.SqlClient.SqlConnection sqlConn = null;
        
private string strConnect = "Data Source='localhost';Password = ;User ID=sa;Initial Catalog=TEST";
        
private System.Data.SqlClient.SqlCommand sqlCmd = null;

        
//Sheets variable
        private double dbSheetSize = 65535;//the hight limit number in one sheet
        private int intSheetTotalSize = 0;//total record can divied sheet number
        private double dbTotalSize = 0;//record total number

        
public Form1()
        {
            InitializeComponent();
        }

        
private int GetTotalSize()
        {
            sqlConn 
= new System.Data.SqlClient.SqlConnection(strConnect);
            sqlCmd 
= new System.Data.SqlClient.SqlCommand("Select Count(*) From PD_WORKBIL_MST", sqlConn);
            sqlConn.Open();
            dbTotalSize 
= (int)sqlCmd.ExecuteScalar();
            sqlConn.Close();
            
return (int)Math.Ceiling(dbTotalSize / this.dbSheetSize);
        }
        
private void DeclareExcelApp()
        {
            m_objExcel 
= new Microsoft.Office.Interop.Excel.Application();
            m_objBooks 
= (Microsoft.Office.Interop.Excel.Workbooks)m_objExcel.Workbooks;
            m_objBook 
= (Microsoft.Office.Interop.Excel._Workbook)(m_objBooks.Add(m_objOpt));
            m_objSheets 
= (Microsoft.Office.Interop.Excel.Sheets)m_objBook.Worksheets;
            intSheetTotalSize 
= GetTotalSize();
            
if (intSheetTotalSize <= 3)
            {
                
if (this.dbTotalSize <= this.dbSheetSize)
                {
                    
this.ExportDataByQueryTable(1false);
                    
return;
                }
                
else if (this.dbTotalSize <= this.dbSheetSize * 2)
                {
                    
this.ExportDataByQueryTable(1false);
                    
this.ExportDataByQueryTable(2true);
                    
return;
                }
                
else
                {
                    
this.ExportDataByQueryTable(1false);
                    
this.ExportDataByQueryTable(2true);
                    
this.ExportDataByQueryTable(3true);
                    
return;
                }
            } 
            
for (int i = 3; i < intSheetTotalSize; i++)
            {
                m_objSheets.Add(m_objOpt, m_objSheets.get_Item(i), m_objOpt, m_objOpt);
            }
            ExportDataByQueryTable(
1false);
            
for (int i = 2; i <= m_objSheets.Count; i++)
            {
                ExportDataByQueryTable(i,
true);
            }
        }
        
private void SaveExcelApp()
        {
            
string excelFileName = string.Empty;
            SaveFileDialog sf 
= new SaveFileDialog();
            sf.Filter 
= "*.xls|*.*";
            
if (sf.ShowDialog() == DialogResult.OK)
            {
                excelFileName 
= sf.FileName;
            }
            
else
            {
                
return;
            }
            m_objBook.SaveAs(excelFileName, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt,
                Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 
                m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
        }
        
private void ExportDataByQueryTable(int intSheetNumber,bool blIsMoreThan)
        {
            
string strQuery = string.Empty;
            
if (blIsMoreThan)
            {
                strQuery 
= "Select Top " +
                
this.dbSheetSize + " * From PD_WORKBIL_MST Where Not  CMPID In (Select Top " +
                dbSheetSize 
* (intSheetNumber-1+ "  CMPID From PD_WORKBIL_MST)";
            }
            
else
            {
                strQuery 
= "Select Top " +this.dbSheetSize + " * From PD_WORKBIL_MST ";

            }
            m_objSheet 
= (Microsoft.Office.Interop.Excel._Worksheet)(m_objSheets.get_Item(intSheetNumber));
            m_objSheet.get_Range(
"A1", m_objOpt).set_Value(m_objOpt, "中文測試一");
            m_objSheet.get_Range(
"B1", m_objOpt).set_Value(m_objOpt, "中文測試二");
            m_objSheet.get_Range(
"C1", m_objOpt).set_Value(m_objOpt, "中文測試三");
            m_objSheet.get_Range(
"D1", m_objOpt).set_Value(m_objOpt, "中文測試四");
            m_objSheet.get_Range(
"E1", m_objOpt).set_Value(m_objOpt, "中文測試五");
            m_objRange 
= m_objSheet.get_Range("A2", m_objOpt);
            m_objQryTable 
= m_objSheet.QueryTables.Add("OLEDB;Provider=SQLOLEDB.1;" + strConnect, m_objRange, strQuery);
            m_objQryTable.RefreshStyle 
= Microsoft.Office.Interop.Excel.XlCellInsertionMode.xlInsertEntireRows;
            m_objQryTable.FieldNames 
= false;
            m_objQryTable.Refresh(
false);
        }
        
private void button1_Click(object sender, EventArgs e)
        {
            DeclareExcelApp();
            SaveExcelApp();
        }
    }
}

使用office2000的話﹐好像類庫有些不同﹐為給大家一個比較﹐也將源碼附貼如下﹕
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
    
public partial class Form1 : Form
    {
        Excel.Range m_objRange 
= null;
        Excel.Application m_objExcel 
= null;
        Excel.Workbooks m_objBooks 
= null;
        Excel._Workbook m_objBook 
= null;
        Excel.Sheets m_objSheets 
= null;
        Excel._Worksheet m_objSheet 
= null;
        Excel.QueryTable m_objQryTable 
= null;
        
object m_objOpt = System.Reflection.Missing.Value;
        
//DataBase-used variable
        private System.Data.SqlClient.SqlConnection sqlConn = null;
        
private string strConnect = "Data Source='localhost';Password = ;User ID=sa;Initial Catalog=TEST";
        
private System.Data.SqlClient.SqlCommand sqlCmd = null;

        
//Sheets variable
        private double dbSheetSize = 65535;//the hight limit number in one sheet
        private int intSheetTotalSize = 0;//total record can divied sheet number
        private double dbTotalSize = 0;//record total number

        
public Form1()
        {
            InitializeComponent();
        }

        
private int GetTotalSize()
        {
            sqlConn 
= new System.Data.SqlClient.SqlConnection(strConnect);
            sqlCmd 
= new System.Data.SqlClient.SqlCommand("Select Count(*) From PD_WORKBIL_MST", sqlConn);
            sqlConn.Open();
            dbTotalSize 
= (int)sqlCmd.ExecuteScalar();
            sqlConn.Close();
            
return (int)Math.Ceiling(dbTotalSize / this.dbSheetSize);
        }
        
private void DeclareExcelApp()
        {
            m_objExcel 
= new Excel.ApplicationClass();
            m_objBooks 
= (Excel.Workbooks)m_objExcel.Workbooks;
            m_objBook 
= (Excel._Workbook)(m_objBooks.Add(m_objOpt));
            m_objSheets 
= (Excel.Sheets)m_objBook.Worksheets;
            intSheetTotalSize 
= GetTotalSize();
            
if (intSheetTotalSize <= 3)
            {
                
if (this.dbTotalSize <= this.dbSheetSize)
                {
                    
this.ExportDataByQueryTable(1false);
                    
return;
                }
                
else if (this.dbTotalSize <= this.dbSheetSize * 2)
                {
                    
this.ExportDataByQueryTable(1false);
                    
this.ExportDataByQueryTable(2true);
                    
return;
                }
                
else
                {
                    
this.ExportDataByQueryTable(1false);
                    
this.ExportDataByQueryTable(2true);
                    
this.ExportDataByQueryTable(3true);
                    
return;
                }
            }
            
for (int i = 3; i < intSheetTotalSize; i++)
            {
                m_objSheets.Add(m_objOpt, m_objSheets.get_Item(i), m_objOpt, m_objOpt);
            }
            ExportDataByQueryTable(
1false);
            
for (int i = 2; i <= m_objSheets.Count; i++)
            {
                ExportDataByQueryTable(i, 
true);
            }
        }
        
private void SaveExcelApp()
        {
            
string excelFileName = string.Empty;
            SaveFileDialog sf 
= new SaveFileDialog();
            sf.Filter 
= "*.xls|*.*";
            
if (sf.ShowDialog() == DialogResult.OK)
            {
                excelFileName 
= sf.FileName;
            }
            
else
            {
                
return;
            }
            m_objBook.SaveAs(excelFileName, m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt, 
                Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
        }
        
private void ExportDataByQueryTable(int intSheetNumber, bool blIsMoreThan)
        {
            
string strQuery = string.Empty;
            
if (blIsMoreThan)
            {
                strQuery 
= "Select Top " +
                
this.dbSheetSize + " * From PD_WORKBIL_MST Where Not  CMPID In (Select Top " +
                dbSheetSize 
* (intSheetNumber-1+ "  CMPID From PD_WORKBIL_MST)";
            }
            
else
            {
                strQuery 
= "Select Top " + this.dbSheetSize + " * From PD_WORKBIL_MST ";

            }
            m_objSheet 
= (Excel._Worksheet)(m_objSheets.get_Item(intSheetNumber));
            m_objSheet.Cells[
1,1= "中文測試一";
            m_objSheet.Cells[
1,2= "中文測試二";
            m_objSheet.Cells[
1,3= "中文測試三";
            m_objSheet.Cells[
1,4= "中文測試四";
            m_objSheet.Cells[
1,5= "中文測試五";
            m_objRange 
= m_objSheet.get_Range("A2", m_objOpt);
            m_objQryTable 
= m_objSheet.QueryTables.Add("OLEDB;Provider=SQLOLEDB.1;" + strConnect, m_objRange, strQuery);
            m_objQryTable.RefreshStyle 
= Excel.XlCellInsertionMode.xlInsertEntireRows;
            m_objQryTable.FieldNames 
= false;
            m_objQryTable.Refresh(
false);
        }

        
private void button1_Click(object sender, EventArgs e)
        {
            DeclareExcelApp();
            SaveExcelApp();

        }

    }
}

在本篇中﹐是將13萬多條記錄分多個Sheet導出。如果你的機器大概像我這樣:P4CPU,1G內存的話。全部導出包括保存也就是20秒左右就可以全部搞定。
也許大家會有更好的方法來實現﹐歡迎各位交流﹗

posted on 2006-08-18 13:38 凯锐 阅读(9610) 评论(29)  编辑 收藏 所属分类: C# Programing

评论

#1楼  2006-08-18 13:55 林子      
可以参考写成通过的导出类库!
前段时间看到的JAVA中的JExcelApi做的不错,也是关于Excel导入导出的,是个通用类库!

前段时间偶也写了个Excel管理类库,功能比你这个多一点点吧!
一直没时间整理,有时间整理一个贴到blog上吧!
  回复  引用  查看    

#2楼 [楼主] 2006-08-18 14:08 精浪      
@林子
MS提供的類庫上的相關文檔﹐我也看過﹐就是我文章開頭提到的那七種方法﹐是嗎?
直接導出65536條記錄的Excel方法﹐期待能早日看到你的Excel管理類庫!


  回复  引用  查看    

#3楼  2006-08-18 15:36 不再忧郁      
不推荐这种做法!
不是所有机器都装有Office,特别是服务器上。查过很多资料都说是在web上的实现,可在web服务器上用这种方法会导致Excel进程关不掉
  回复  引用  查看    

现在使用最新的VSTO for office 2007 CTP
导出Excel已经很方便了~
其实使用一些组件或者调用外部程序也许更好
系统的耦合性可能会更低(前一段时间一条公文流转系统就是这样处理的)

支持LZ!!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
我的Blog,创业、思考与探讨下一代计算技术:
http://computebank.spaces.live.com/
http://www.zhangcheng.name
  回复  引用    

#5楼 [楼主] 2006-08-18 16:30 精浪      
@不再忧郁
其實﹐我這篇文章是在Windows程序中實現的。你說無法關掉Excel進程﹐這個我承認﹐我在代碼中沒有體現﹐在button1_Click方法的最后﹐應加入如下几句﹕
//Clean-up
m_objRange = null;
m_objSheet = null;
m_objSheets = null;
m_objBooks = null;
m_objBook = null;
m_objExcel = null;
GC.Collect();
另外﹐企業Windows程序﹐客戶端不可能沒有裝office吧?呵呵...
  回复  引用  查看    

#6楼  2006-08-18 17:18 不再忧郁      
@精浪
恩,在windows桌面上没什么问题的,可在web中执行操作的帐号是匿名用户就关不掉了。
有关web中文件输出准备写篇文章
  回复  引用  查看    

#7楼 [楼主] 2006-08-18 18:00 精浪      
@不再忧郁
恩﹐由于我現在是在企業里面﹐做的很多都是windows的桌面程序﹐Web文件輸出就准備關注你的文章啦,呵呵...
  回复  引用  查看    

#8楼 [楼主] 2006-08-18 18:12 精浪      
網上有人給出殺Excel進程的源碼:
private void KillProcess(string processName)
{
System.Diagnostics.Process myproc= new System.Diagnostics.Process();
//得到所有打开的进程
try
{
foreach (Process thisproc in Process.GetProcessesByName(processName))
{
if(!thisproc.CloseMainWindow())
{
thisproc.Kill();
}
}
}
catch(Exception Exc)
{
throw new Exception("",Exc);
}
}
  回复  引用  查看    

#9楼  2006-08-19 09:28 林子      
@精浪

文章已经发在blog上,包括源码,使用文档等,请查看,不明白地方留言给偶吧!

  回复  引用  查看    

#10楼  2006-08-19 10:01 林子      
楼上的朋友,其实网上已经有很多关于杀进程的例子了!

可以参见偶的blog:http://linfuguo.cnblogs.com/
其它有你所需要的东东。

TO:精浪
由于office的Excel本身的一些限制,像单sheet表数据导出大于65535
单cell数据大于255等必须遵循Excel的限制,这些相关问题的解决办法
请看我blog上发的ExcelManager使用说明,里面有相关约束项。


  回复  引用  查看    

#11楼  2006-08-19 14:41 myrondai      
如果在2003里,考虑直接使用xml么
  回复  引用  查看    

#12楼  2006-08-19 14:55 不再忧郁      
@精浪
@林子
在web上开启进程的是Iuser_computername帐户
由于是匿名帐户所以没有权限关闭打开的进程,是系统所限不是代码能解决的

@myrondai
我的方案就是用XML,所以客户端一定要OfficeXP以上才能打开
  回复  引用  查看    

#13楼  2006-08-19 15:57 Edward.Net      
我已经写了一个使用mhtml的方式导出Excel的类库,现在已经在我们的项目中开始使用了。可以兼容Office97以上的所有版本,而且也不需要服务器安装Office,就是不知道公司让不让开源。
  回复  引用  查看    

#14楼 [楼主] 2006-08-19 16:05 精浪      
@myrondai
@不再忧郁
使用XML不是不可以﹐只是有時客戶需要一定的格式的﹐比如說合并單元格啦﹐計算求和等...﹐如此一來﹐覺得還是使用MS的Office好一點。畢竟會Office的人比較多的吧!呵呵....
  回复  引用  查看    

#15楼 [楼主] 2006-08-19 16:14 精浪      
@Edward.Net
你所說的是不是網上流傳的SmartExcel?
不使用office組件﹐直接將文件導出Excel也聽人討論過可以實現﹐問題是時間效率方面﹐我沒有試過smartExcel導出的時間﹗但我想應該不會快過MS Excel的QueryTable的吧。
  回复  引用  查看    

#16楼 [楼主] 2006-08-21 23:38 精浪      
@林子

本来想将JExcelAPI重构成C#版,殊不知,已经有人已经重构过来了。在这里可以下载:
http://sourceforge.net/projects/nexcel
  回复  引用  查看    

#17楼  2006-08-30 08:21 macro [未注册用户]
strQuery = "Select Top " +
this.dbSheetSize + " * From PD_WORKBIL_MST Where Not CMPID In (Select Top " +
dbSheetSize * (intSheetNumber-1) + " CMPID From PD_WORKBIL_MST)";

这语句执行效率不高吧,有没有等价的方法呀?
  回复  引用    

#18楼 [楼主] 2006-08-31 13:38 精浪      
網上發現有很多人引用該篇文章﹐可有人只是單純的復制。并沒有注明出處﹐在此﹐請轉載的朋友注明出處:中國博客--精浪

  回复  引用  查看    

#19楼  2006-09-02 01:00 RicCC      
WorkBook对象有Close方法,Application对象有Quit方法,最好都显示调用一下,再释放COM对象。

"在windows桌面上没什么问题的,可在web中执行操作的帐号是匿名用户就关不掉了"
--操作Excel对象时,Framework 1.1用的是ASP.Net帐号、2.0默认用的是NetWork Service帐号,而不是那个匿名。COM对象的操作权限,由DCOMCNFG里面的配置来决定的,可以进行配置。

很多时候Excel对象释放不了,有可能是:
1. 异常时可能没有捕获并释放对象。
2. 对Excel对象的控制不全面。例如如果Excel里面有远程文档的连接,我们打开文件时可能无法连接到那个文件进行更新,Excel就会弹出一个对话框需要确认一下。如果我们是在后台代码里面控制打开这个文件,默认情况下同样会是这种情况,结果打开文件的方法一直都无法返回,永远停在那里。所以在调用Workbooks.Open的时候,需要指定一个正确的连接更新方式(一般的情况下大家调用Open方法就只会给一个文件名路径)。
3. Web程序中很明显的,Excel进程在使用完之后不会立即退出,因为我们也不可能随意的让GC强制回收。但一般应该持续不太长的时间后会自动退出的,一直不退出就是出问题了。
  回复  引用  查看    

#20楼  2006-09-07 14:10 夏天愛 [未注册用户]
請教樓主,以上代碼測試成功,但保存出的只是 含有“中文測試一”至“中文測試五”的文字,如果將數據表的欄位信息綁定出來呢?“m_objSheet.get_Range("A1", m_objOpt).set_Value(m_objOpt, "中文測試一");”--->這句代碼應如何修改呢?
我郵箱是summerlove521521@163.com
謝謝!

  回复  引用    

#21楼 [楼主] 2006-09-07 18:55 精浪      
@夏天愛
http://www.cnblogs.com/jinliangliu/archive/2006/09/01/492633.html
中我已将该源码全部封装成了ExcelManager类,调用方法也有作详细说明,你参考一下。
exc.DeclareExcelApp(new string[] { "编号","供应商编号" }, " OrderID,CustomerID ", "Orders", "报表标题");
这一句中的new string[] { "编号","供应商编号" }, " 就是你的表头的中文文字。而接下来的就是你的数据表的栏位,然后是数据表名,最后就是你的报表的标题。


  回复  引用  查看    

#22楼  2006-10-23 11:23 夏天愛 [未注册用户]
Dear@精浪
提問完當晚就收到你的郵件,真的是非常感謝,但是目前我又遇到一個問題,感謝!
現系統需要將一服務器上的文件夾共享,系統操作時,將此文件夾的內容導至另一台服務器上的SQL Server裡,兩台Server都是用的Windows 2003 Server,不在一個域裡,用的是工作組,但互訪不成功,因為需要Windows用戶名和密碼的驗證,[ string Access_Con = "provider=Microsoft.JET.OLEDB.4.0; "+"data source = \\\\192.168.3.100\\logDb\\"; ]-->這是聯接文件夾的路徑,請問是不是需要在這裡邊加入用戶名和密碼就可以?若是這樣的話,請問寫入格式是什麼?

感謝!



  回复  引用    

#23楼 [楼主] 2006-10-23 16:59 精浪      
@夏天愛
從你的要求來看﹐是將Excel文件導至SQL Server吧。這個我給出一個實現的SQL Script吧。你改成C#代碼就成了:

SELECT [調研時間], [調研部門], [調研對象], [調研內容], [調研人員]
INTO NewTable
FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',
'Data Source="D:\工作報告\Start060922.xls";User ID=Admin;Password=;Extended properties=Excel 8.0')...[Sheet2$]
  回复  引用  查看    

#24楼  2006-10-25 12:38 夏天愛 [未注册用户]
@精浪
呵呵,謝謝! 我想可能我表達的有點模糊,這是另外的一個問題,是訪問 ACCESS裡的數據,然後導至SQL中,ACCESS數據庫沒有用戶名及密碼,SQL有,但訪問ACCESS所在的服務器時,要求輸入Windows的用戶名及密碼,我覺得可能是因為在工作組裡的問題,因為我在做測試時,用的是域,就可以成功訪問,沒有彈出需要輸入Windows用戶名及密碼。
請問你是否遇到過這樣的問題,因為若是程序可以解決的話,就不用組建域,若是程序解決不了,就只能組建域再來做測試,這樣比較費資源,因此想問一下能否從程序上解決。
謝謝!

  回复  引用    

#25楼 [楼主] 2006-10-25 19:35 精浪      
@夏天愛
由于我使用的office 2003都没有Access啦,所以我无法测试,但我用Excel试了,这句话是没有问题的:
SELECT [調研時間], [調研部門], [調研對象], [調研內容], [調研人員]
INTO NewTable
FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',
'Data Source="\\192.168.1.100\工作報告\Start060922.xls";User ID=Admin;Password=;Extended properties=Excel 8.0')...[Sheet2$]
当然,首先将"工作报告"文件夹共享
我的sql server机在一个域中,有"工作报告"文件夹的机器没在域中。两台机器均为xp sp2 英文版!

  回复  引用  查看    

在导出的excel表中,右键单击单元格。出现编辑查询。能否删除这个ole db查询属性? 在数据区域属性中,去掉“保存查询定义”的勾选即可以删除这个编辑查询,请问在c#中应该调用哪些函数或属性呢??
谢谢
  回复  引用    

#27楼 [楼主] 2007-12-19 19:58 旌浪      
@cc11111111
這個,你上msdn找一下就可以了,呵呵...,由於現在沒有環境,也不好調試了。
  回复  引用  查看    

如何发布程序呢?需要安装什么必要的软件??
我使用的是win2003 sp2
程序是web的。
安装了excel、.net2.0框架
还是不行?
  回复  引用    

#29楼  2008-01-14 15:17 adsfasdf [未注册用户]
<a href='http://www.alimama.com/membersvc/rd.do?w=p_10400264&p=&f=http://www.alimama.com/membersvc/promotion/tjyj.htm' target='_blank'><img border="0" src="http://img.alimama.cn/images/adzone/banner_tjyj_250x60.gif" /></a>
  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首