net mvc descargar con como asp archivos archivo c# asp.net excel telerik office-interop

c# - mvc - descargar pdf con asp net



¿Cómo puedo descargar un archivo de Excel a la carpeta de descarga del usuario? (2)

En un proyecto C #, asp.net 4.0, he creado un archivo Excel usando Microsoft.Office.Interop.Excel. El archivo se crea correctamente y se coloca en una carpeta en el servidor. Sin embargo, no he podido encontrar una forma de mostrar el archivo al cliente. ¿Alguien me puede ayudar?

Algunos antecedentes: estoy tratando de evitar el cambio de Microsoft que está bloqueando la apertura de archivos de Excel. Nuestra aplicación web utiliza una cuadrícula Telerik y esa cuadrícula se exporta a un archivo Excel utilizando la función ExportToTocel. Las descargas de archivos (van al archivo de descargas del usuario), pero cuando el usuario intenta abrirlas, obtienen una aplicación Excel en blanco. Hay soluciones alternativas como desinstalar el parche que creó este problema, desactivar las opciones de seguridad de Excel y hacer clic en desbloquear en las propiedades del archivo; Sin embargo, nuestro cliente no quiere hacer ninguno de estos. Así que estoy reescribiendo exportaciones para más de 40 cuadrículas.

Obtuve los datos de radGrid en una tabla de datos y los escribí en Excel usando este código que funciona:

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();

Mi problema surge cuando intento que el usuario descargue el archivo. Probé el código a continuación, pero aparece un error que dice "El proceso no puede acceder al archivo ''C: / Temp / MD20160802161458.xlsx'' porque lo está utilizando otro proceso." ¿Alguien puede explicar cómo desbloquear el archivo después de que ha sido creado por Excel o mostrarme otra forma de descargar el archivo al usuario?

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

También probé el código a continuación para abrir el archivo de Excel. El archivo se crea en el servidor, pero nunca se abre. Cuando intento abrir el archivo en el servidor, Excel se cuelga. Sospecho que esto se debe a que tengo Excel 2013 en mi máquina de desarrollo y Excel 2007 está en el servidor. Esto plantea otro problema porque no puedo garantizar qué versión de Excel sería en el eventual servidor de producción. Cualquier sugerencia sera apreciada.

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


Simplemente haciendo un seguimiento de la respuesta de DVK, no tuve más que problemas al usar las herramientas de interoperabilidad de Excel, pero si no necesitas producir archivos .XLS antiguos y estás bien con los archivos .XLSX, sugiero usar el SDK de OpenXML (es gratis). Hay varios ejemplos en línea en la producción de libros de Excel que lo usan. Aqui hay uno:

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


Lo primero que debe verificar es si el proceso de Excel aún se está ejecutando en el servidor. Microsoft recomienda encarecidamente no utilizar los componentes Microsoft Interop en un entorno de servidor de producción debido a una multitud de razones. Nunca fueron destinados para ese propósito. Este es el artículo más reciente que pude (rápidamente) encontrar:

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

Actualmente, Microsoft no recomienda, y no admite, la automatización de las aplicaciones de Microsoft Office desde cualquier aplicación o componente de cliente desatendido y no interactivo (incluidos ASP, ASP.NET, DCOM y NT Services), ya que Office puede presentar un comportamiento inestable y / o interbloqueo cuando Office se ejecuta en este entorno.

Intenté esta ruta (debido a los requisitos del cliente) en varias ocasiones, y todas generaron problemas. El mayor de ellos es que el componente de interoperabilidad de Excel tiene un hábito muy desagradable de no finalizar el proceso de Excel, lo que significa que Excel aún puede tener su archivo abierto cuando intenta abrirlo y enviarlo al cliente. Una solución alternativa es (literalmente) escribir código que enumera los procesos en ejecución en la máquina y cierra cualquier instancia de Excel, pero luego, por supuesto, está corriendo el riesgo de cerrar una instancia que está realizando un trabajo real.

Existen muchos componentes asequibles que funcionan de manera mucho más fiable (como ComponentPro, sin afiliación con ellos pero he utilizado sus componentes en muchas ocasiones) y pueden implementarse con muy poco esfuerzo.

Editar - Si debe usar interoperabilidad y forzar Excel para cerrar

Este artículo de tiene muchos mecanismos diferentes para hacerlo. Dependiendo de lo que esté haciendo exactamente, puede que tenga que probar múltiples rutas. Liberar el objeto COM me parece el más limpio.