最近一个朋友问起有没有使用EXCEL做过报表,如实说在很久之前一个对日项目中使用过ASP.NET调用EXCEL生成报表。不知道为什么日本人那么喜欢使用EXCEL做东西!
在这里我先说一下大概的思路,首先需要做EXCEL模板,将基本的报表框架画出来,设置控制信息页。然后程序从数据库取出需要显示在报表上的数据,将其按一定的格式写入模板中的隐藏页,利用ASP.net启动模板,利用宏启动报表的信息填充,报表格式的绘画,显示报表等工作。这就当时所做的基本思路。
说实话报表启动的非常缓慢,并且在VBA的调试时非常麻烦,并且客户端必须要装EXCEL,否则是看不到报表的,还有就是不适合普遍应用。好处是在开发的过程中不需要额外的报表软件,也不需要掌握高深的技巧,打印方面只要把模板画好就算OK了。我建议朋友的方案是使用EXCEL做前端的报表显示,将不需要变化的部分先画到报表上,然后将表格控制方法(单元格合并,计算列等)以VBA函数的形式写到EXCEL中。ASP.NET中提供数据源,将Excel.dll引入工程中调用相应的方法对报表文件进行赋值。
注:机器上需要安装Office;
为了在VS2005中,对Excel文件进行操作,需要用到Excel.dll,方法是将Office目录下的Excel.exe文件拷出来,把 Excel.exe文件考到C:"Program Files"Microsoft Visual Studio 8"SDK"v2.0"Bin里
然后运行VS2005命令提示输入TlbImp EXCEL.EXE Excel.dll
以下是部分代码:

Code
//提供VBA方法的调用,数组下标0是VBA方法名称,以后是所需要参数
object[] paraObjects = new object[] { "test" ,"6"};
string filename = Server.MapPath("doc");
filename = filename + "\\test.xls";
object Nothing = System.Reflection.Missing.Value;
Excel.ApplicationClass myExcel = new Excel.ApplicationClass();
Excel.Workbooks books = myExcel.Workbooks;
Excel._Workbook oBook = null;
oBook = books.Open(filename, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing);
//随便写一些数据到EXCEl中
myExcel.Cells["6", "C"] = "A";
myExcel.Cells["6", "F"] = "cca";
myExcel.Cells["6", "I"] = "'123";
myExcel.Cells["7", "C"] = "B";
myExcel.Cells["7", "I"] = "'111";
//使用RunMacro方法对VBA方法进行调用
object ret = this.RunMacro(myExcel,paraObjects);
paraObjects = new object[] { "CellMerge", "E6","G7" };
ret = this.RunMacro(myExcel, paraObjects);
//保存在EXCEl的修改,否则不会起作用
oBook.Save();
//释放对象
oBook.Close(false, Nothing, Nothing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook);
oBook = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(books);
books = null;
myExcel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel);
myExcel = null;
GC.Collect();
int intStart = 0;
//以下是将报表文件写到输出流,将做好的报表提供给客户端下载
string saveFileName = filename.Substring(intStart, filename.Length - intStart);
System.IO.FileInfo fi = new System.IO.FileInfo(filename);
string fileextname = fi.Extension;
Response.Clear();
Response.Charset = "utf-8";
Response.Buffer = true;
this.EnableViewState = false;
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.AppendHeader("Content-Disposition", "attachment;filename=" + saveFileName);
Response.ContentType = fileextname;
Response.WriteFile(filename);
Response.Flush();
Response.Close();
Response.End();
}
//调用VBA方法
private object RunMacro(object oApp, object[] oRunArgs)
{
try
{
object objRtn;
objRtn = oApp.GetType().InvokeMember(
"Run",
System.Reflection.BindingFlags.Default |
System.Reflection.BindingFlags.InvokeMethod,
null,
oApp,
oRunArgs
);
return objRtn;
}
catch (Exception ex)
{
if(ex.InnerException.Message.ToString().Length > 0)
{
throw ex.InnerException;
}
else
{
throw ex;
}
}
}