Como utilizar COM Interop Office (Excel) en tus proyectos ASP.NET y no morir en el intento…

En el proyecto en el que me encuentro, tenemos desarrollada una librería .NET para obtener informes en Excel mediante la llamada a una BAPI de SAP. Esta librería trabaja con el objeto COM de Excel y al mismo tiempo es consumida desde ASP.NET, sí, ya se que Microsoft no recomienda el uso de componentes Office en aplicaciones ASP.NET, “COM Interop with Microsoft Office products from an ASP.NET web page. Excel was not designed to be used inthis way” pero esto es un caso de fuerza mayor y no hay mas narices, puesto que son informes bastantes complejos que no basta con utilizar un DataGrid y rendereizar su contenido y lanzar una salida con Response.Write y poner el Response.ContentType = “application/vnd.ms-excel, como tantos ejemplos hay por ahí.


El problema con el que me he encontrado es el siguiente:


Todas las pruebas realizadas han funcionado a la perfección en las máquinas de desarrollo (Eso de ser Administrador de máquina…) pero… cuando lo he montado en el servidor de pruebas y he hecho la primera petición de un informe me he encontrado con esto:


Acceso Denegado


Juer, pues si que empezamos bien. La primera conclusión es evidente: Falta de Permisos, así que le he arrancado el Debugger de mi máquina y le he pedido a mi compañero que hiciera una petición de informe para ver donde casca:


ApplicationClass objExcel = new ApplicationClass();


Le he dado permisos de Administrador a mi compañero en mi máquina, ha vuelto a ejecutar la petición y ¡Vualá! todo funciona, porque estas llamadas a objetos COM necesitan para ejecución local/remota unos privilegios mínimos.


La configuración del sitio web tiene el acceso anónimo deshabilitado y la autenticación windows integrada (Estamos en una intranet) y en el Web.Config impersonate a true con autenticación Windows.


Soluciones que no piensas:



  • Dar permisos de Adminsitrador a la cuenta MACHINEASPNET

ESTO NI SE TE OCURRA



  • Impersonar el hilo de ejecución de la aplicación con un usuario Adminsitrador

La gente de sistemas nunca te lo dará y además no me parece una buena solución puesto que vulnera muchos principios de seguridad como en el primer caso.



  • Hacer una impersonación sólo cuando generas el Informe con una cuenta de usuario que sea Adminsitrador 

La gente de sistemas nunca te lo dará


Bueno, pues visto que esto va a ser que no, de repente, cacharreando con los Servicios de Componentes encuentro una cosita que se llama Configuración DCOM (Distributted Component Object Model) y al expandirlo me encuanto con esto:



Síííííí!!!! Aplicación Microsoft Excel, esto pinta bien y además tiene propiedades, así que pinchamos:



Juer y encima tiene una pestaña de Seguridad



Así que marcamos el check Personalizar de los Permisos de inicio y activación y pulsamos el botón Modificar para dar permisos al Usuario/Grupo que desamos:



Aceptamos todo y con esto hemos resuelto el maldito error. En mi caso hemos dados permisos a un Grupo que contiene a los usuarios que acceden a la aplicación. (Aunque la imagen corresponde al equipo mio de casa ;))


Por último y por cuestiones de performance en nuestra aplicación es necesario liberar todos los objetos COM que utilicemos, para que no se queden esos malditos procesos llamados EXCEL (Os lo digo por experiencia propia), que aperecen a porrillo en el Administrador de Tareas, y para ello os dejo este enlace del Support de Microsoft:


La aplicación de Office no se cierra después de automatización desde cliente de Visual Studio . NET


Con la solución que propone conseguí eliminar eso malditos procesos que parecían desaparecer con el oApp.Quit(); oApp = null; pero que en realidad no desaparecían y se estaban acumulando llevandose 36 Mb de memoria cada uno.


Bueno pues espero que os sirva y que no tengáis que romperos tanto el coco y os encontréis tantos probelmas como me he encontrado yo.

41 comentarios en “Como utilizar COM Interop Office (Excel) en tus proyectos ASP.NET y no morir en el intento…”

  1. Excelente artículo… que recuerdos ver pantallazos del dcomcnfg.exe a estas alturas de la vida con .Net 3.0 rulando por ahí… DCOM forever!!

  2. jejeje
    36Mb de memoria cada uno = una instancia de Excel … el gran problema de la interfaz com q exporta excel es q e no es un com, es un activex exe !!! (el RCW se vuelve loco)
    Y pensar que hace unos años una herramienta conocida de reporting “incluia” las capacidades de reporting de excel y word. Yo me quede flipado y cuando comence a hacer una reverse engineering para ver q hacian, como bien tu dices desp del oApp.Quit(), llamaban a un servicio externo q se recorria todos los procesos existentes y se calzaba a los exceles … curioso no ?

    Saludos

  3. Gracias por el aporte Bruno, desconocía que se tratase de un ActiveX.

    Y como en el enlace que he puesto al support, no dejes de liberar ninguno o el proceso se queda.

    Salu2

  4. Es verdad que MS no recomienda el uso de excel en el server side pero también lo tacha de ilegal, pues si, si algún día la gente esta de software association llega con la Policía a tus oficinas y ven que estas haciendo esta atrocidad no solo te golpearan por mal programador sino que también te secuestraran tus servidores. Para prevenir esto MS creo el famoso excel services que corre en SharePoint o también puedes usar ASPOSE que son componentes .net creados para este fin.

    NUNCA implementen una aplicacion de este tipo

  5. Ante una aclaración de este tipo por tu parte, creo que aparte de llamarme Mal Programador deberías argumentar tu crítica para saber porqué es ilegal.

    Yo por mi parte, te dejo un documento donde advierten que no recomienda el uso para server-side pero en ningún momento dicen nada sobre “Malos Programadores”, “Golpes”, “Policía”… es más como dije al principio ha sido un requerimiento especial y no ha habido mas cojo… aunque claramente digo que Microsoft no lo recomienda:

    Considerations for server-side Automation of Office

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757

    Salu2

  6. Hola

    Tu articulo esta muy interesante y funciona bien, ahora yo tengo ese problema pero con word 🙁 y no hay un application Word en el adm de componentes alguna vez hiciste con word?? si lo hiciste a quien hay que dar permisos ??

    salu2
    sergio

  7. Hola

    Por lo que leí esta bastante interesante e ASPOSE lo unico malo es que no es gratis 🙂

    Te cuento que estoy utulizando ado.net para cargar una planilla desde un datatable, pero he notado que para cargar miles de registros, uno a uno se pone lento, mas de lo que quisiera, y me preguntaba si no conoces alguna forma de llenar todo un datatable direco a un excel , pero de preferencia con ado.net sin componentes que comprar 🙂

    Por otro lado he dejado de utilizar el word y estoy utilizando archivos RTF de forma que los abro y hago la manipulacion del stream, no me salio tan dificil, y funciona bien no mas. Lo que yo necesitaba era cartas y sobres tipo que luego se deben combinar con N registros. Lo unico que no me gusta es la manipulacion de los codigos de rtf es un poco lioso y puede ser suceptible a errores.

    Salu2
    SergioT

  8. HOla.
    El articulo me parece muy interesante pero cuando ingreso al MTC no aparece la carpeta Configuración DCOM y no puedo asignarles permisos, y cuando entro jecutando dcomcnfg si me aparece el EXCEL, pero no me permite ingresar a las pestañas de configuración. Hay alguna manera de restaurar la carpeta de configuración DCOM , tengo un windows 200 como servidor

  9. “…Excel was not designed to be used inthis way” ni en “another way” jeje. A ver si alguien ha pasado por esto..

    El interop, al cargar los datos de un archivo excel en un datagrid es lento de narices, xo si además quieres mostrar el formato…ya te mueres.

    ¿Existe alguna forma que yo no conozca? o ¿alguna forma de incrustar la tabla excel con formato y todo en un formulario?

  10. Hola, una dudota, esto mismo que se explica en este articulo aplica para word?, porque tengo una aplicación que usa word y en mi maquina funciona, pero como se menciona en el articulo, pues la gente de sistemas no me va a dar un usuario administrador, y con el que me dieron me marca un error al momento de generar el archivo de word “Word cannot open the existing”, alguien podria ayudarme con esto.

  11. Hola Luis, gracias por contestar, pues ya cheque el dcomcnfg y ahi esta ademas de excel tambien el word, e intente hacer algo similar a lo que esta en el articulo pero no he tenido exito, me marca algunos errores como que no tiene suficiente memoria o que el tiempo de espera termino, en fin no he tenido exito. Alguna idea de lo que puede estar pasando?

  12. Hola. Buscando soluciones a este error me he encontrado con esta. Pero mi situacion particular es con Word. Pretendo instanciar una aplicacion word de la siguiente manera:

    Dim oWordApp As New Microsoft.Office.Interop.Word.Application

    y me genera el error:

    Error al recuperar un generador de clases COM para el componente con
    CLSID {000209FF-0000-0000-C000-000000000046} debido al siguiente error: 80070005.

    He estado probando las soluciones para excel pero nada. No sé a qué puede ser debido y la solución posible. Alguien tiene alguna propuesta??

  13. Hola me parece muy interesante todo lo que han mencionado. Por mi cuenta ya pase por el problema de los permisos para utilizar los COM de excel pero ahora me surge un nuevo problema al publicar dicha aplicacion en un servidor Win 2000 que tiene Excel 2000. El error es el siguiente:

    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.: at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad)

    En algun lado encontre que no es posible utilizar estos componentes con Excel 2000 lo cual no me convence.

    Cualquier ayuda que me puedan dar será mas que bienvenida gracias…

  14. Queria consultarlos porque hice una aplicacion que levanta un excel del lado del servidor, a pesar de no estar aconsejado…..y me encontre que al querer levantar mas de una instancia me da un error de concurrencia…….Alguien tiene alguna data de porque puede suceder algo asi???? gracias!
    Diego

  15. Muy bueno el artículo, me ayudó a avanzar un poco. Ahora ya me deja ejecutar el código pero al hacerlo se abre una instancia del WINWORD.exe pero se queda en el taskmgr sin hacer nada y en la aplicación web da un tiemout. ¿Alguien sabe la causa y como resolvrlo?

  16. Sres

    Agradeceria que me puedan ayudar urgentemente, al inicio tuve un problema de acceso denegado para crear un objeto de tipo excel, luego añadi la cuenta con la que estoy trabajando al DCOM, le di todos los permisos (ojo q la cuenta no es administrador).
    Despues de esto ejecuto la primera linea q muestro acontinuacion sin problemas,pero en la tercera linea mi aplicativo se cae, al querer abrir una hoja excel para trabajar. Sale error

    1004 – No se puede abrir o guardar más documentos debido a que el espacio en disco o la memoria son insuficientes. • Para disponer de más memoria cierre los libros o programas que no necesite. • Para liberar espacio en el disco, elimine los archivos que no necesita del disco en el que desea guardar los documentos.

    Set lobjExcel=CreateObject(“Excel.Application”)
    lobjExcel.Application.Visible=True
    Set lxlsWorkbook=lobjExcel.Workbooks.Add

    Verifique si tenia objetos excel abierto en el task manager pero no encontre ninguno.ademas tengo suficiente espacio en disco.

    ¿que puedo hacer?

  17. Nadie ha dado con el problema de :

    1004 – No se puede abrir o guardar más documentos debido a que el espacio en disco o la memoria son insuficientes. • Para disponer de más memoria cierre los libros o programas que no necesite. • Para liberar espacio en el disco, elimine los archivos que no necesita del disco en el que desea guardar los documentos.

    He buscado y buscado información y nada…

    Parece que muchos se rindieron y quienes lo lograron no lo publicaron 🙁

  18. Hola a mi me marca el siguiente error:

    Error Object reference not set to an instance of an object.

    Aun cuando ya tengo instalado Office en el Servidor. Yo se que no recomiendan la automatizacion de Office de lado del servidor pero en mi caso es una necesidad y no tenemos otra alternativa

  19. hola…hice todo pero no me muestra el archivo de excel que creo….se crean procesos de excel.exe en el servidor, pero no me muestra el archivo! en la pc de desarrollo anda lo mas bien, pero en el server no! AYUDA!

  20. Hola, yo tengo un pequeño detalle cuando le doy clic al boton para que me de el reporte en excel no hace nada ni me marca error :S que puedo hacer…

    Saludos

  21. Hola ya he podido pero tengo un inconveniente, el documento se abre en el servidor de aplicaciones(Servidor web) y no en el ordenador desde donde lo ejecuto..que debo hacer???

  22. Sabes, quiero abrir un libro de excel con parametros enviados desde una grilla.

    Dim xlApp As Object ‘Un Libro de Excel
    Dim xlBook As Excel.Workbook ‘ Una hoja del libro
    Dim xlSheet As Excel.Worksheet ‘Inicializar Excel y obtener un objeto de Aplicacion

    Dim ruta_excel As String

    ruta_excel = Server.MapPath(“/” & “plantilla_nomina_EAC.xlt”)

    xlApp = Nothing
    xlApp = CreateObject(“Excel.Application”)
    xlBook = Nothing
    xlBook = xlApp.Workbooks.Open(ruta_excel)
    xlSheet = xlBook.Worksheets(1)
    xlApp.Visible = True

    Cuando se ejecuta este codigo me arroja el siguiente error:

    NO SE PUEDE MOSTRAR UN CUADRO DE DIALOG O FORMULARIO MODAL CUALDO LA APLICACION NO ESTA EN MODO INTERACTIVE. ESPECIFIQUE ESTILO SERVICENOTIFICACION O DEFAULT DESKTOPONLY PARA MOSTRAR UNA NOTIFICACION DE UNA APLICAICON DE SERVICIO.

    QUE PODRA SER??

  23. Bueno yo he realizado los pasos descrito pero mi aplicación me sigue mandando el mismo error al tratar de mostrar los datos en ecxel desde una máquina cliente (No se puede crear el componente ActiveX). Desde mi máquina si de desarrollo funciona perfectamente.

  24. Ramón: Bueno yo he realizado los pasos descrito pero mi aplicación me sigue mandando el mismo error al tratar de mostrar los datos en Excel desde una máquina cliente (No se puede crear el componente ActiveX). Desde mi máquina de desarrollo funciona perfectamente. Alguien tiene otra solución o me falta algo por incluir en el servidor o en mi aplicación para que funcione, gracias de antemano.

  25. Hola.
    Sabes que tengo el mismo problema, pero con outlook 2003 y VS2005(estoy atrasada lo se, pero mi empresa no entiende esa parte), y he mirado en el DCOMCNFG pero no existe nada aparte de algo para los datos adjuntos de Outlook y otro para el buscador de outlook.
    En modo debug funciona sin problemas, pero al instalarlo(como servicio windows) me envia el error mencionado. Este error es tanto en la máquina cliente como en el servidor.
    Help me please!!!!

  26. Primero creo los objetos
    Dim xlWorkBook As Excel.Workbook
    Dim xlWorkSheet As Ecel.Worksheet
    Me sale esto cuando hago la asignacion de memoria
    xlWorkBook = New Excel.Application().Workbooks.Add(Missing.Value)
    {System.UnauthorizedAccessException} System.Exception
    Ya hice lo q pones arriba y nada… revise el web.config y esta en mode Windows… alguna ayuda sera agradecida 😀

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *