Автоматизация Excel с использованием ASP.NET
Фон
Мы разрабатываем некоторые собственные утилиты с использованием ASP.NET 2.0. Одним из них является извлечение некоторой информации из баз данных и создание рабочей книги Excel, содержащей ряд электронных таблиц с данными на основе запросов в базу данных.
проблема
Прототип проверочной концепции (простая страница ASP.NET, которая запрашивает отдельный элемент из базы данных и открывает Excel для добавления данных на лист), хорошо работает при локальном запуске на машинах разработки, успешно создавая и отображая электронную таблицу Excel как просили. Однако при запуске на нашем сервере мы получаем следующую ошибку при попытке создать экземпляр Excel.
Невозможно привести объект COM типа "Microsoft.Office.Interop.Excel.ApplicationClass" к типу интерфейса "Microsoft.Office.Interop.Excel._Application". Эта операция завершилась неудачно, поскольку вызов QueryInterface для компонента COM для интерфейса с IID '{000208D5-0000-0000-C000-000000000046}' завершился неудачно из-за следующей ошибки: такой интерфейс не поддерживается (Исключение из HRESULT: 0x80004002 (E_NOINTERFACE)),
Решение?
Мы используем PIA для Excel 2003, и на сервере установлены Excel 2003 и PIA. Кто-нибудь может объяснить, почему это не работает, или дать нам несколько советов о том, как мы можем отследить проблему?
Спасибо за любую помощь, которую вы можете предоставить.
5 ответов
Может ли пользователь, под которым работает пул приложений ASP.NET, иметь доступ к приложению? Попробуйте войти в систему под этим пользователем (или измените пул приложений для запуска под этим пользователем) и откройте Excel. Если это работает, попробуйте запустить приложение WinForms на сервере как пользователь с кодом, который не работает.
Не уверен, но я думаю, что сборки PIA, возможно, должны быть зарегистрированы через regsvr32.
Я подозреваю, что если вы работаете в качестве сетевой службы, вы не сможете запустить Excel (без интерактивного входа, ограниченной учетной записи и т. Д.). Ваш код ASP.NET выполняется внутри пула приложений. Вы можете изменить пользователя, из которого запускается пул приложений, с помощью диспетчера IIS. Если вы хотите проверить, какой код выполняется в данный момент, посмотрите на процесс w3wp в диспетчере задач.
Для тестирования измените пул приложений, чтобы он работал как пользователь, которого вы знаете, работает с Excel.
Мы используем Aspose (коммерческий). Офис на сервере не очень веселый.
- Вы должны быть осторожны с лицензированием.
- Время от времени вам нужно убивать процесс зависания.
- Правильное получение прав требует определенных усилий.
Это называется PI(t)A по причине...
От Microsoft, (выделение в оригинале):
В настоящее время Microsoft не рекомендует и не поддерживает автоматизацию приложений Microsoft Office из любых необслуживаемых, неинтерактивных клиентских приложений или компонентов (включая ASP, ASP.NET, DCOM и NT Services), поскольку Office может демонстрировать нестабильное поведение и / или или тупик, когда Office работает в этой среде.
Со списком причин, почему вы не должны это делать:
- ... Многие службы работают под учетными записями, которые не имеют пользовательских профилей (например, учетная запись SYSTEM или IWAM_[имя_сервера]). Поэтому Office может не правильно инициализироваться при запуске. В этой ситуации Office возвращает ошибку в функцию CreateObject или функцию CoCreateInstance. Даже если приложение Office может быть запущено, другие функции могут работать неправильно, если профиль пользователя не существует.
- Если возникает непредвиденная ошибка или если для завершения функции требуется неуказанный параметр, Office предназначен для запроса пользователю модального диалогового окна, в котором спрашивается, что пользователь хочет сделать. Модальное диалоговое окно на неинтерактивном рабочем столе не может быть закрыто. Поэтому этот поток перестает отвечать (зависает) на неопределенный срок. Хотя определенные методы кодирования могут помочь уменьшить вероятность этой проблемы, эти методы не могут полностью предотвратить проблему. Уже один этот факт делает запуск приложений Office из серверной среды рискованным и неподдерживаемым.
- Компоненты на стороне сервера должны быть многопоточными COM-компонентами с высокой степенью реентерабельности и минимальными издержками и высокой пропускной способностью для нескольких клиентов. Офисные приложения практически во всех отношениях с точностью до наоборот. Офисные приложения - это не требующие повторного использования серверы автоматизации на основе STA, разработанные для обеспечения разнообразных, но ресурсоемких функций для одного клиента.
И ваш код может выдать следующие ошибки:
CoCreateInstance
- Ошибка выполнения '429': компонент ActiveX не может создать объект
- Ошибка времени выполнения "70": в доступе отказано
- CO_E_SERVER_EXEC_FAILURE (0x80080005): сбой при выполнении сервера
- E_ACCESSDENIED (0x80070005): доступ запрещен
- виснет
- возвращается без ошибок, но не работает
И наконец:
Из-за ограничений в дизайне Office изменений в конфигурации Office недостаточно для решения всех проблем. Microsoft настоятельно рекомендует использовать несколько альтернатив, которые не требуют установки Office на стороне сервера, и которые могут выполнять наиболее распространенные задачи более эффективно и быстрее, чем автоматизация. Прежде чем использовать Office в качестве серверного компонента в своем проекте, рассмотрите альтернативные варианты.
Рассмотрите возможность работы с файлами XLSX (впервые в Office 2007, но есть плагин для Office 2003), которые представляют собой просто ZIP-файлы, содержащие XML-файлы, которыми вы можете манипулировать без использования Excel. SpreadsheetML (на основе XML) хорошо документирован и не слишком сложен для программирования (вы даже можете найти LINQ для SpreadsheetML где-нибудь в Интернете).
Как указывалось выше, Excel на самом деле не является серверным продуктом, и при его использовании на сервере вы можете столкнуться с различными проблемами.
Я думаю, что проблема заключается в том, что после развертывания приложения в IIS вы внезапно запускаетесь в MTA COM Apartment. Я считаю, что Excel является компонентом STA и поэтому не может быть создан внутри MTA. Вам нужно будет установить опцию aspcompat на странице, которую вы используете
<%@ page aspcompat=true %>