首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

200分,谋生成excel的一些解决方案

2011-12-15 
200分,求生成excel的一些解决方案我现在需要做这样一个软件,自动生成Excel,现在我有几个问题,请大家帮忙解

200分,求生成excel的一些解决方案
我现在需要做这样一个软件,自动生成Excel,现在我有几个问题,请大家帮忙解答一下
1.生成的问题:我在网上找了一下,基本就是“使用Excel的com组件生成”,“使用第三方直接生成二进制Excel文件”,“生成Excel 2003后支持的XML文件”,我需要生成二进制文件,不知道使用COM和第三方组件,哪个比较好一点?生成的文件将会很复杂。还有一点就是,如果使用了Excel自带的组件,那么在发行后,对客户端安装的Excel有没有要求,比如我开发用的是2003,而对方装了2005就不能生成了?

2.模板的问题:当一个用户设计好Excel生成样式后,其他用户只要导入这个“模板”文件,就能生成一样的Excel文件(不包含数据),这点一般是怎么做的?我现在的想法是把模式存为XML,到时候解析还原。

3.合成的问题:有好几个一样的Excel文件,有没有快速的方法,合并成一个文件?

分晚上可以加了就加上

[解决办法]
用excel的com,什么复杂的东西都可以实现(只要excel可以实现的)
你用2003的,客户就算装的是2007也是可以用的.

第三方的没用过..看看其它人怎么说.
[解决办法]

探讨
谢谢,发布的时候,需要带上2003的DLL吗?

[解决办法]
添加引用 :
Microsoft.Office.Tools.Excel

同时添加COM:EXCEL.EXE和EXCEL.DLL.....EXCEL.DLL的生成方法网上很多..

关于Microsoft.Office.Tools.Excel建议楼主去查MSDN.你会发现操作EXCEL原来如此简单.
[解决办法]
建议LZ使用oledb进行操作,这样可以摆脱对office的依赖,就算客户机没有安装office也可以进行导出!
例子:
 1.使用oledbconnection打开连接,连接语句 "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='Excel 8.0;HDR=No';Data Source= "+路径;
2.使用sql语句创建工作表:create Table [" + 工作表名称+ "](["+列名称+"]"+类型(一般为nvarchar(200))+")";执行
3.使用sql的insert语句进行插入操作:insert into [" + 工作表名称 + "]("+列名称+") values("+值+");执行
ok了

[解决办法]
可以考虑做成csv格式的文件,字段用,隔开就可以了。
[解决办法]
1。使用COM 调用EXCEL 网上资料比较多
2。加载模板 就相当于读取一个EXCEL文件
3。不知道你合并的具体要求,简单处理 是把所有EXCEL文件中的sheet对象集合在一个新的EXCEL文件中
[解决办法]
C# code
 

private void Button2_Click(object sender, System.EventArgs e)
{
if (dlFS.SelectedValue=="0")
{

string s ;
string mycgmxid="0" ;

for(int i = 0;i <= dgDetail.Items.Count - 1;i++)
{

if (((System.Web.UI.WebControls.CheckBox)dgDetail.Items[i].FindControl("cbqx")).Checked )
{
mycgmxid=mycgmxid+","+dgDetail.Items[i].Cells[0].Text ;

}
}

DataSet myds ;
DataGrid mydg =new DataGrid()  ;

s = "XXXXXXXXXXXXXXXXXXXX";


myds = Wefeel.Data.Sql.GetDataSet (s) ;
mydg.DataSource = myds ;
mydg.DataBind() ;


mPublic.ExportToExcel_dg(Page, mydg) ;

}


Excel.Application  oExcel =new  Excel.ApplicationClass();
Excel.Workbooks oBooks ;
Excel.Workbook oBook;


Excel.Sheets  oSheets ;
     
Excel.Range oCells ;

string sFile , sTemplate;

sFile = Server.MapPath(Request.ApplicationPath) + "\\purchase\\cgd.xls" ;
//'定义模版文件
sTemplate = Server.MapPath(Request.ApplicationPath) + "\\purchase\\cgdtmp.xls";
oExcel.Visible = false;
oExcel.DisplayAlerts = false;
//'定义一个新的工作簿
oBooks = oExcel.Workbooks;

//oBook.Open(Server.MapPath(Request.ApplicationPath) + "\\purchase\\cgdtmp.xls");

oBook = oBooks.Add (sTemplate);

oSheets = oBook.Worksheets;

Excel.Worksheet oSheet ;


//'Dim oSheet() As Microsoft.Office.Interop.Excel.Worksheet = New Microsoft.Office.Interop.Excel.Worksheet(lbbm.Items.Count) {}

string mycgmxid="0" ;

for(int i = 0;i <= dgDetail.Items.Count - 1;i++)
{

if (((System.Web.UI.WebControls.CheckBox)dgDetail.Items[i].FindControl("cbqx")).Checked )
{
mycgmxid=mycgmxid+","+dgDetail.Items[i].Cells[0].Text ;

}
}

string s="";

s = "xxxxxxxxxxxxxxxxxxxxxxxxx"


DataSet myds1 = Wefeel.Data.Sql.GetDataSet(s) ;
 

 
     

 
oSheet= ( Excel.Worksheet) oSheets[1];

oSheet.Copy(oSheet,Type.Missing);

oSheet.Name =lbbm.Items[i].Text ;
       

oSheet=(Excel.Worksheet) oSheets[1]  ;
oSheet.Delete() ;




//'保存
     
oBook.SaveCopyAs(sFile);

oBook.Close(  false,  null,  null  ); 
oExcel.Workbooks.Close(); 




//      '退出Microsoft.Office.Interop.Excel,并且释放调用的COM资源
oExcel.Quit();

System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheets);
     

System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheets) ;
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks) ;
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel);

oExcel= null ;
oBooks = null ;
oBook = null;
oSheets = null ;
oCells = null;
System.GC.Collect();


Response.ContentType = "application/vnd.ms-Microsoft.Office.Interop.Excel";
Response.Charset = "utf-8";
Response.Redirect("cgd.xls") ;
     

}


[解决办法]
1.首先声明,这些方法也都是本人搜集的资料,然后为已所用,程序中不足之处,还请高手指点.
2.网上有好多关于用SQL语句导入导出的例子,这里不再重复写了。

方法1:调用com组件,导出access数据到Excel,就是直接调用access的导出功能,此方法速度超级快
using Access;

Access.ApplicationClass oAccess = new Access.ApplicationClass();
oAccess.Visible = false;
try
{
//ACCESS9:
oAccess.OpenCurrentDatabase("d:\\wcf.mdb",false,"");
//导出到excel
oAccess.DoCmd.TransferSpreadsheet(Access.AcDataTransferType.acExport,Access.AcSpreadSheetType.acSpreadsheetTypeExcel9,"工作表名","d:\\wcf.xls",true,null,null);
//导入txt
// oAccess.DoCmd.TransferText(Access.AcTextTransferType.acExportDelim,"","Enterprise","d:\\wcf.txt",true,"",0);
oAccess.CloseCurrentDatabase();
oAccess.DoCmd.Quit(Access.AcQuitOption.acQuitSaveNone);
System.Runtime.InteropServices.Marshal.ReleaseComObject (oAccess);
oAccess = null;
MessageBox.Show("导入成功");
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
GC.Collect();
}
方法2:此方法速度也是超级快,只不过导出的格式非标准的Excel格式,默认工作表名与文件名相同
string FileName="d:\\abc.xls";
System.Data.DataTable dt=new System.Data.DataTable();
FileStream objFileStream;
StreamWriter objStreamWriter;
string strLine="";
objFileStream = new FileStream(FileName,FileMode.OpenOrCreate,FileAccess.Write);


objStreamWriter = new StreamWriter(objFileStream,System.Text.Encoding.Unicode);

for(int i=0;i<dt.Columns.Count;i++)
{
strLine=strLine+dt.Columns[i].ColumnName.ToString()+Convert.ToChar(9);
}
objStreamWriter.WriteLine(strLine);
strLine="";

for(int i=0;i<dt.Rows.Count;i++)
{
strLine=strLine+(i+1)+Convert.ToChar(9);
for(int j=1;j<dt.Columns.Count;j++)
{
strLine=strLine+dt.Rows[i][j].ToString()+Convert.ToChar(9);
}
objStreamWriter.WriteLine(strLine);
strLine="";
}
objStreamWriter.Close();
objFileStream.Close();

方法3:用Ado.net 此方法速度较以上两个显得慢了一些,数据量越大越明显
int Id=0;
string Name="测试";
string FileName="d:\\abc.xls";
System.Data.DataTable dt=new System.Data.DataTable();
long totalCount=dt.Rows.Count;
long rowRead=0;
float percent=0;
OleDbParameter[] parm=new OleDbParameter[dt.Columns.Count];
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FileName +";Extended Properties=Excel 8.0;";
OleDbConnection objConn = new OleDbConnection(connString);
OleDbCommand objCmd = new OleDbCommand();
objCmd.Connection = objConn;
objConn.Open();
//建立表结构
objCmd.CommandText = @"CREATE TABLE Sheet1(序号 Integer,名称 varchar)";
objCmd.ExecuteNonQuery();
//建立插入动作的Command
objCmd.CommandText = "INSERT INTO Sheet1("+Id+","+Name+")";
parm[0]=new OleDbParameter("@Id", OleDbType.Integer);
objCmd.Parameters.Add(parm[0]);
parm[1]=new OleDbParameter("@Company", OleDbType.VarChar);
objCmd.Parameters.Add(parm[1]);
//遍历DataTable将数据插入新建的Excel文件中
for(int i=0;i<dt.Rows.Count;i++)
{
parm[0].Value=i+1;
for(int j=1;j<parm.Length;j++)
{
parm[j].Value =dt.Rows[i][j];
}
objCmd.ExecuteNonQuery();
rowRead++;
percent=((float)(100*rowRead))/totalCount;
// this.FM.CaptionText.Text = "正在导出数据,已导出[" + percent.ToString("0.00") + "%]...";
if(i==dt.Rows.Count-1)
// this.FM.CaptionText.Text = "请稍后......";
System.Windows.Forms .Application.DoEvents();
}
objConn.Close();
//this.FM.CaptionText.Text = "";

方法4:此方法调用com组件,速度都慢于以上3个方法
using Excel;

System.Data.DataTable dt=new System.Data.DataTable();
string FileName="d:\\abc.xls";

long totalCount=dt.Rows.Count;
long rowRead=0;
float percent=0;
Excel.Application xlApp=null;
xlApp=new Excel.Application();
Excel.Workbooks workbooks=xlApp.Workbooks;
Excel.Workbook workbook=workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet worksheet=(Excel.Worksheet)workbook.Worksheets[1];//取得sheet1
Excel.Range range;

//写入字段
for(int i=0;i<dt.Columns.Count;i++)
{
worksheet.Cells[1,i+1]=dt.Columns[i].ColumnName;
range=(Excel.Range)worksheet.Cells[1,i+1];
}
for(int r=0;r<dt.Rows.Count;r++)
{
worksheet.Cells[r+2,1]=r+1;
for(int i=0;i<dt.Columns.Count;i++)
{
// worksheet.Cells[r+2,i+1]=dt.Rows[r][i];
if(i+1!=dt.Columns.Count)
worksheet.Cells[r+2,i+2]=dt.Rows[r][i+1];
}
rowRead++;
percent=((float)(100*rowRead))/totalCount;
// this.FM.CaptionText.Text = "正在导出数据,已导出[" + percent.ToString("0.00") + "%]...";
System.Windows.Forms .Application.DoEvents();


}
range=worksheet.get_Range(worksheet.Cells[2,1],worksheet.Cells[dt.Rows.Count+2,dt.Columns.Count]);
workbook.Saved =true;
workbook.SaveCopyAs(FileName);
//this.FM.CaptionText.Text = "";

方法5:利用剪贴板 ,有人说此方法很快,但是我用时,这种方法最慢,请高手指点.
System.Data.DataTable dt=new System.Data.DataTable();
string filePath=@"d:\abc.xls";

object oMissing = System.Reflection.Missing.Value;
Excel.ApplicationClass xlApp = new Excel.ApplicationClass();
try
{
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
Excel.Workbooks oBooks = xlApp.Workbooks;
Excel._Workbook xlWorkbook = null;
xlWorkbook = oBooks.Open(filePath,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,
oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing,oMissing);

Excel.Worksheet xlWorksheet;
// 添加入一个新的Sheet页。
xlWorksheet = (Excel.Worksheet)xlWorkbook.Worksheets.Add(oMissing,oMissing,1,oMissing);
// 以TableName作为新加的Sheet页名。
xlWorksheet.Name ="企业名录";
// 取出这个DataTable中的所有值,暂存于stringBuffer中。
string stringBuffer = "";

for( int j=0; j<dt.Rows.Count; j++ )
{
for( int k=0; k<dt.Columns.Count; k++ )
{
stringBuffer += dt.Rows[j][k].ToString();
if( k < dt.Columns.Count - 1 )
stringBuffer += "\t";
}
stringBuffer += "\n";
}
// 利用系统剪切板
System.Windows.Forms.Clipboard.SetDataObject("");
// 将stringBuffer放入剪切板。
System.Windows.Forms.Clipboard.SetDataObject(stringBuffer);
// 选中这个sheet页中的第一个单元格
((Excel.Range)xlWorksheet.Cells[1,1]).Select();
// 粘贴!
xlWorksheet.Paste(oMissing,oMissing);
// 清空系统剪切板。
System.Windows.Forms.Clipboard.SetDataObject("");

// 保存并关闭这个工作簿。
xlWorkbook.Close( Excel.XlSaveAction.xlSaveChanges, oMissing, oMissing );
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook);
xlWorkbook = null;

这些方法都没有关闭Excel进程,这种资料很多,在此不多写了,希望这些能对一些人带来方便.

[解决办法]
关闭Excel进程的方法很简单
把你生成Excel的代码写成一个过程
在过程后面加一句GC.Collect();

比如 

protected void btnExport_Click(object sender, EventArgs e)
{
ExcelExport();
GC.Collect();
}

protected void ExcelExport()

Excel.ApplicationClass my = new Excel.ApplicationClass();

my.Visible = false;
object objMissing = System.Reflection.Missing.Value;

.....

}

热点排行