B/S软件做好了,接下来开始做报表了,目前想到两种方案:
1.用类似于水晶报表之类的第三方控件(我用的是devexpress),好处是功能强大,而且也可以"跨平台",在linux下浏览没问题,缺点是报表和程序无法分离(至少我没有做到),当增加/删除/修改报表后,要把整个网站重新上传.
2.用execl,优点是程序和报表分离,在本地编辑好EXCEL模版,上传到服务器(我用二进制方式保存到数据库里面),报表时,由服务器把模版取出,按约定的接口,把实际数据写入,发送给浏览器,这样可以通过程序更改报表而无须发布网站,缺点是客户端需要安装office,在linux下无法打开
不知道还有没有其他办法,最好是报表模版和程序分离

解决方案 »

  1.   

    第二种方式,把生成的报表,生成一份对应的html. 就像在excel中可以把文件另存为网页形式,然后用传送给客户端。
      

  2.   

    理论上虽然如此,其实一般不必把“客户端需要安装Excel”看做多么严重的问题。这年头嘴上最恶毒的反微软的人也还是要使用微软的东西的。你可以有两个报表,一个是Excel,一个是最简单的html,第二个只是作为补充而已。如果做得好,其实在提供Excel报表的时候还应该同时提供pdf报表。
      

  3.   

    我已经按照第二中方案完成了,同事解决了EXCEL不能完全退出的BUG,主要代码如下:
     public clsReport(System.Web.UI.Page p_Page, DataRow p_TitleRow, DataTable p_Table, string p_ReportId, bool p_AddBorder)
            {
                if (p_Table == null || p_Table.Rows.Count == 0)
                    return;//无数据
                Process[] P0, P1;
                P0 = Process.GetProcessesByName("Excel");//得到原来的EXCEL进程,便于查询新进程
                try
                {
                    GC.Collect();
                    object missing = Missing.Value;
                    string strSql = string.Format("select * from {0} where 序号={1}", SpecialTableName.ReportTableName, p_ReportId);
                    DataRow rowModel = Tools.CurDataAccess.GetValueDataRow(strSql);
                    if (rowModel == null)//无模版
                        return;
                   .....                Excel.Application myExcelApp = new Excel.Application();
                    //重新遍历进程,查出多余的EXCEL,多出来的就是当前的EXCEL,便于后面强行释放
                    int nNew, nOld;
                    P1 = Process.GetProcessesByName("Excel");
                    //  比较前后 多出的Excel.exe 的pid
                    nNew = 0;
                    if (P1.Length > 1)
                    {
                        for (nNew = 0; nNew < P1.Length; nNew++)
                        {
                            for (nOld = 0; nOld < P0.Length; nOld++)
                            {
                                if (P0[nOld].Id == P1[nNew].Id)
                                {
                                    break;
                                }
                            }
                            if (nOld == P0.Length) break;
                        }
                    }
                    Process P = P1[nNew];//多出来的                string strWorker = OpInfo.CurWorkName(p_Page);
                    string strReportName = rowModel["报表名称"].ToString();
                    string strFileName = Tools.TempFileDirectory + "\\" + strWorker + strReportName + "." + rowModel["扩展名"].ToString();
                    Tools.DownLoadFile((byte[])rowModel["文件内容"], strFileName);
                    //打开新文件
                    myExcelApp.DisplayAlerts = false;
                    myExcelApp.Visible = false;
                    myExcelApp.Application.Workbooks.Open(strFileName,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing,
                      missing);
                    //得到当前的工作簿
                    Excel.Workbook myExcelWorkBook = myExcelApp.Workbooks[1];
                    Excel.Worksheet myExcelSheet = (Excel.Worksheet)myExcelWorkBook.Worksheets[1];
    .......                myExcelWorkBook.Close(missing, missing, missing);
                    myExcelApp.Workbooks.Close();
                    myExcelApp.Quit();
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(r);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelApp);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelSheet);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcelWorkBook);
                    r = null;
                    myExcelWorkBook = null;
                    myExcelSheet = null;
                    myExcelApp = null;
                    if (P.ToString() != "")
                    {
                        P.Kill();//杀死EXCEL
                    }
                    GC.Collect();                byte[] bytes = Tools.UpLoadFile(strFileName);
                    File.Delete(strFileName);
                    Tools.SendFileToClient(p_Page, strReportName + "." + rowModel["扩展名"].ToString(), bytes);
                }
                catch (Exception ee)
                {
                    p_Page.Response.Write(ee.Message);
                }
            }