如何将Excel文件下载给用户';的下载文件夹

本文关键字:下载 文件夹 给用户 Excel 文件下载 | 更新日期: 2023-09-27 18:00:05

在C#的asp.net 4.0项目中,我使用Microsoft.Office.Interop.Excel创建了一个Excel文件。该文件将正确创建并放置在服务器上的文件夹中。然而,我一直无法想出一种方法来向客户端显示该文件。有人能帮我吗?

一些背景:我正在努力解决微软阻止打开Excel文件的更改。我们的web应用程序使用Telerik网格,该网格使用ExportToExcel函数导出到Excel文件中。文件下载(转到用户的下载文件),但当用户尝试打开它时,他们会得到一个空白的Excel应用程序。有一些解决方法,如卸载导致此问题的修补程序、关闭Excel安全选项以及单击文件属性中的取消阻止;然而,我们的客户不想做这些。所以我正在重写40多个网格的导出。

我将数据从radGrid中获取到一个数据表中,并使用以下代码将其写入Excel:

            Microsoft.Office.Interop.Excel.Application m_objExcel = null;
            Microsoft.Office.Interop.Excel.Workbooks m_objBooks = null;
            Microsoft.Office.Interop.Excel._Workbook m_objBook = null;
            Microsoft.Office.Interop.Excel.Sheets m_objSheets = null;
            Microsoft.Office.Interop.Excel._Worksheet m_objSheet = null;
            object m_objOpt = System.Reflection.Missing.Value;
            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;
            m_objSheet = (Microsoft.Office.Interop.Excel._Worksheet)(m_objSheets.get_Item(1));
            int colcount = 1;
            foreach (DataColumn col in dt.Columns)
            {
                m_objSheet.Cells[1, colcount] = col.ColumnName;
                colcount++;
            }
            int rowcount = 2;
            foreach (DataRow row in dt.Rows)
            {
                for (int i = 1; i < dt.Columns.Count; i++)
                {
                    m_objSheet.Cells[rowcount, i] = row[i - 1].ToString();
                }
                rowcount++;
            }
            string currentDateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
            m_objBook.SaveAs("C:''Temp''MD" + currentDateTime + ".xlsx");
            m_objBook.Close();
            m_objExcel.DisplayAlerts = false;
            m_objExcel.Quit();

当我试图让用户下载文件时,我的问题就来了。我尝试了下面的代码,但我收到一个错误:"该进程无法访问文件C:''Temp''MD20160802161458.xlsx,因为它正被另一个进程使用。"有人能解释如何在Excel创建文件后取消阻止该文件,或者向我展示另一种将该文件下载给用户的方法吗?

 string fileName = "C:''Temp''MD" + currentDateTime + ".xlsx", myStringWebResource = null;
 WebClient myWebClient = new WebClient();
 myStringWebResource = fileName;
 myWebClient.DownloadFile(myStringWebResource, fileName);

我还尝试了下面的代码来打开Excel文件。该文件是在服务器上创建的,但从未打开。当我试图在服务器上打开文件时,Excel崩溃。我怀疑这是因为我的开发机器上有Excel 2013,服务器上有Excel 2007。这引发了另一个问题,因为我无法保证最终生产服务器上的Excel版本。如有任何建议,我们将不胜感激。

            var excelApp = new Microsoft.Office.Interop.Excel.Application();
            excelApp.Visible = true;
            excelApp.Workbooks.Open("C:''Temp''MD" + currentDateTime + ".xlsx");
            m_objExcel.Quit();

如何将Excel文件下载给用户';的下载文件夹

刚刚跟进DVKs的答案,我在使用Excel互操作程序时遇到了问题,但如果您不需要生成较旧的.XLS文件,并且可以使用.XLSX文件,我建议使用OpenXML SDK(免费)。网上有很多使用它制作Excel工作簿的例子

http://www.codeproject.com/Articles/670141/Read-and-Write-Microsoft-Excel-with-Open-XML-SDK

首先要检查的是Excel进程是否仍在服务器上运行。由于多种原因,Microsoft强烈建议不要在生产服务器环境中使用Microsoft Interop组件。它们从来就不是为了这个目的。这是我能(很快)找到的最新文章:

https://support.microsoft.com/en-us/kb/257757

Microsoft目前不建议也不支持从任何无人参与的非交互式客户端应用程序或组件(包括ASP、ASP.NET、DCOM和NT服务)自动化Microsoft Office应用程序,因为在这种环境中运行Office时,Office可能会表现出不稳定的行为和/或死锁。

我已经尝试过很多次这种路线(由于客户的要求),但都出现了问题。其中最大的一点是,Excel互操作组件有一个非常讨厌的习惯,即不终止Excel进程,这意味着当你试图打开文件并将其发送到客户端时,Excel可能仍会打开你的文件。一种解决方法是(从字面上)编写代码,枚举计算机上正在运行的进程,并关闭Excel的任何实例,但当然,您要冒关闭正在执行实际工作的实例的风险。

有许多价格合理的组件工作起来更加可靠,而且可以毫不费力地实现。

编辑-如果必须使用interop并强制Excel关闭

这篇StackOverflow文章有很多不同的机制。根据你正在做的事情,你可能需要尝试多个路由。释放COM对象对我来说似乎是最干净的。