0

我有一个 C# .Net MVC 应用程序。我已经完成了Export to Excel用于导出存储在datatable. 我已经存储了datatable会话,直到用户按下导出按钮。当用户按下导出时,我datatable通过 Ajax 调用获取数据并将其导出。数据导出成功时,我还保留了一条消息。

问题是它在调试应用程序时工作正常,但是当我部署应用程序时它不起作用。但它显示成功消息而不是错误消息。应用程序中用于获取数据或存储数据的其他 ajax 调用工作正常。

我试图调试部署的应用程序;异常发生在行 Excel.Application excelApp = new Excel.Application();

例外是

System.UnauthorizedAccessException was caught
  Message=Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).

导出到 Excel 功能

public static void ExportExcel(this DataTable Tbl, string ExcelFilePath = null)
        {
            try
            {
                if (Tbl == null || Tbl.Columns.Count == 0)
                    //throw new Exception("ExportToExcel: Null or empty input table!\n");
                    Console.WriteLine("ExportToExcel: Null or empty input table!\n");

                // load excel, and create a new workbook
                Excel.Application excelApp = new Excel.Application();
                excelApp.Workbooks.Add();

                // single worksheet
                Excel._Worksheet workSheet = excelApp.ActiveSheet;

                // column headings
                for (int i = 0; i < Tbl.Columns.Count; i++)
                {
                    workSheet.Cells[1, (i + 1)] = Tbl.Columns[i].ColumnName;
                    workSheet.Cells[1, (i + 1)].Font.Bold = true;
                    workSheet.Cells[1, (i + 1)].Font.Size = 12;
                }

                // rows
                for (int i = 0; i < Tbl.Rows.Count; i++)
                {
                    // to do: format datetime values before printing
                    for (int j = 0; j < Tbl.Columns.Count; j++)
                    {
                        workSheet.Cells[(i + 2), (j + 1)] = Tbl.Rows[i][j];
                    }
                }
                //int k = Tbl.Rows.Count;
                // check fielpath
                if (ExcelFilePath != null && ExcelFilePath != "")
                {
                    try
                    {
                        workSheet.SaveAs(ExcelFilePath);
                        excelApp.Quit();
                        //MessageBox.Show("Excel file saved!");
                    }
                    catch (Exception ex)
                    {
                        //throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"+ ex.Message);
                        Console.WriteLine("ExportToExcel: Excel file could not be saved! Check filepath.\n"+ ex.Message);
                    }
                }
                else    // no filepath is given
                {
                    excelApp.Visible = true;
                }
            }
            catch (Exception ex)
            {
                //throw new Exception("ExportToExcel: \n" + ex.Message);
                Console.WriteLine("ExportToExcel: \n" + ex.Message); 
            }
        }

这是调用函数的代码

public ActionResult JsonExportToExcel()
        {
            DataTable table = (DataTable)Session["filterCRMRequestDatatable"];
            ExportToExcel.ExportExcel(table, "");
            var result = "true";
            return Json(result, JsonRequestBehavior.AllowGet);
        }

ajax调用代码

$("#ExportToExcel").click(function () {
                //blur page
                $('#loading_div').removeClass("loading-css-back").addClass("loading-css-front");
                $('#loading_div').fadeIn();
                $('#Full_page_content').removeClass("main-div-front").addClass("main-div-back");
                $('#Full_page_content').fadeOut();
                $.ajax({
                    url: '/FilterCRMRequest/JsonExportToExcel/',
                    type: "POST",
                    dataType: "json",
                    success: function (data) {
                        alert("Data Exported Successfully");
                        //active the page
                        $('#loading_div').removeClass("loading-css-front").addClass("loading-css-back");
                        $('#loading_div').fadeOut();
                        $('#Full_page_content').removeClass("main-div-back").addClass("main-div-front");
                        $('#Full_page_content').fadeIn();
                    },
                    error: function (xhr, props) {
                        if (xhr.status == 401) {
                            alert("Session Expired. Please Login Again");
                            window.location.href = "/CRMLogin/LogOn";
                        }
                        else {
                            alert("Sorry some Error occured. Please Try again.");
                            //active the page
                            $('#loading_div').removeClass("loading-css-front").addClass("loading-css-back");
                            $('#loading_div').fadeOut();
                            $('#Full_page_content').removeClass("main-div-back").addClass("main-div-front");
                            $('#Full_page_content').fadeIn();
                        }
                    }
                });
            });
4

1 回答 1

0

我没有看到您抛出任何异常或返回任何错误代码 - 这可能就是您仍然看到成功消息的原因。

拒绝访问可能是权限问题。您在部署应用程序的服务器上是否安装了 MS Excel?- 从 Server 2003 切换到 Server 2012 后,我也收到拒绝访问,并且无法再解决问题。即使我发现了几个地方,您可以更改网站访问 MS-Office 应用程序的权限,但它们都没有帮助。

最后我发现了几篇文章,你不应该在服务器上使用 Office Interop,因为:

  • 它最终使用实际的 Office 应用程序
    • 这使得它变得缓慢且消耗资源
    • 很难同时处理多个请求
    • 如果代码失败,应用程序可能会继续运行 => 它可能永远不会再次运行,直到您重新启动进程

您可能需要考虑使用 apache POI- NPOI的 .net 实现。使用这个库,您可以操作 Excel、Word 和 PowerPoint 文件。如果您可以使用新的基于 xml 的 Excel 文件 (xlsx),您也可以直接使用Microsoft 的 OpenXML SDK或该库的包装器 - SpreadsheetLight

于 2013-08-22T19:06:53.627 回答