Как добавить пользовательский XML в открытую книгу Excel 2007 с помощью С#?

Я пытаюсь добавить пользовательский XML в открытую книгу Excel 2007 с помощью С#. Я использую Microsoft.Office.Interop.Excel как интерфейс. Я обнаружил там класс CustomXMLPart, но я не могу понять, как его использовать. Первоначально я ожидал, что код будет чем-то простым:

CustomXMLPart myXMLPart = новый CustomXMLPart (xmlString);

myWorkBook.XMLCustomParts.Add(myXMLPart);

но это не близко к работе.

Я пробовал найти примеры в Интернете, но они сбивают с толку сложные разговоры о пакетах, добавлениях, OpenXML, потоках VSTO и т.д. Я распаковал подходящую книгу (xlsx) и обнаружил, что у нее есть элемент docProps/custom.xml.

Я просто хочу добавить подобный custom.xml в новую книгу (2007), прежде чем сохранять его. Это возможно? Обратите внимание: я не могу установить дополнительные пакеты или библиотеки.

Изменить: я сделал немного больший прогресс, исследуя эту проблему. Я уверен, что у меня есть правильная ссылка Office (Microsoft Office 12.0 Object Library в COM) и ссылка на Interop (Microsoft.Office.Interop.Excel под GAC).

Объявление

Microsoft.Office.Core.CustomXMLParts myCustomXMLParts;

компилируется, однако

Microsoft.Office.Core.CustomXMLParts myCustomXMLParts =
    Microsoft.Office.Interop.Excel.Workbook.CustomXMLParts;

выводится сообщение об ошибке: Ошибка CS0029: Невозможно неявно преобразовать тип "Microsoft.Office.Core.CustomXMLParts" в "Microsoft.Office.Core.CustomXMLParts.

Когда я нахожусь над свойством Excel CustomXMLParts, он утверждает, что возвращает объект CustomXMLParts, который в некотором смысле является объектом Microsoft.Office.Core.CustomXMLParts, но не таким же, как в сборке Office. Таким образом, здесь явно существует некоторая несовместимость, но я не могу ее разрешить. У меня установлены Microsoft Office Professional Plus 2007 (12.0.6612.1000) и Office 2007 Primary Interop Assemblies (12.0.4518.1014).

Изменить: Я вполне уверен, что это проблема с DLL Office. В Add-Reference я вижу "Библиотеку объектов Microsoft Office 12.0" и могу добавить ее без каких-либо ошибок. Он выглядит просто как "Офис" в разделе "Ссылки". Однако он кажется невидимым для компилятора, хотя он по-прежнему утверждает, что Microsoft.Office.Core определен в сборке, на которую не ссылаются, и указывает сборку 'office', Version = 12.0.0.0.

Ссылка на My Office связана с MSO.DLL под Microsoft Shared/OFFICE12 и имеет майор версии 2, малой версии 4 в разделе "Свойства". Это имеет значение? Или это сообщение об ошибке, указывающее, что по какой-либо причине это не обрабатывается?

Изменить: добавление COM-объекта "Библиотека объектов Microsoft Office 12.0" определенно кажется проблемой. Из других сообщений форума я обнаружил, что другие люди видят ссылку на "Microsoft.Office.Core", но я вижу только "Office". Я пробовал редактировать файл .csproj напрямую, и это действительно дает "Microsoft.Office.Core", но он все еще не работает. Единственный вывод, который я могу сделать, заключается в том, что мой MSO.DLL для Office 12 Professional Plus (версия (12.0.6612.1000) на самом деле не содержит сборки Microsoft.Office.Core или, во всяком случае, не раскрывает их должным образом.

Ответы

Ответ 1

Документы MSDN дают пример использования VSTO, и я адаптировал его для работы с приложением Winform.

Трюк (в этой ситуации) заключается в ссылке на PIA , см. подсказку подсказки Excel Reference на скриншоте ниже. ПРИМЕЧАНИЕ. Я не использовал вкладки ссылок .Net или COM, мне пришлось "просмотреть" для DLL Excel.


Ниже приведен код Winform рабочего примера с использованием Excel PIA (также версия 12.0.4518.1014). См. Снимок экрана для более подробной информации о Book1.xlsx, переименованном в zip и извлеченном после запуска кода вместе с результирующим файлом item1.xml в папке CustomXML:
private void button1_Click(object sender, EventArgs e)
{
    string path = @"c:\temp\test\Book1.xlsx";
    var xlApp = new Microsoft.Office.Interop.Excel.Application();
    Workbook wb = xlApp.Workbooks.Open(path);

    string xmlString =
    "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
    "<employees xmlns=\"http://schemas.microsoft.com/vsto/samples\">" +
        "<employee>" +
            "<name>Karina Leal</name>" +
            "<hireDate>1999-04-01</hireDate>" +
            "<title>Manager</title>" +
        "</employee>" +
    "</employees>";

    wb.CustomXMLParts.Add(xmlString, Type.Missing);
    wb.Save();
}

Большой вид скриншота: http://i.stack.imgur.com/O8Qhm.png

enter image description here

Если вы хотите получить customXML из рабочей книги, посмотрите этот ответ: fooobar.com/questions/383593/....


EDIT:

У меня также есть Microsoft.Office.Core ActiveX, ссылающийся на GAC: C:\Windows\assembly\GAC_MSIL\Office\15.0.0.0__71e9bce111e9429c\Office.dll и Microsoft VBIDE.Interop из GAC, а также C:\Windows\assembly\GAC_MSIL\Microsoft.Vbe.Interop\15.0.0.0__71e9bce111e9429c\Microsoft.Vbe.Interop.dll.

Вот мой проект, пожалуйста, попробуйте, и, надеюсь, вы увидите, чего не хватает в вашем решении, кроме моего, который работает: http://JeremyThompson.Net/Rocks/OfficeExcelCustomXML.zip

Обратите внимание, что zip содержит DLL GAC в папке Bin\Debug.

Ответ 2

Я думаю, что было бы еще более подходящим для вас, чтобы полностью отказаться от пути через автоматизацию excel. Вероятно, достаточно было бы открыть файл excel через System.IO.Packaging Namespace. Здесь вы можете найти полный образец: Добавить пользовательские части XML в документы без запуска Microsoft Office

В отличие от других опубликованных ответов, это решение не требует ссылок на Office PIA. Вам просто нужно добавить ссылку на WindowsBase, которая включена в .NET. Он может даже обрабатывать другие форматы документов OpenXML, такие как docx, pptx...

Ответ 3

В вашем втором фрагменте Microsoft.Office.Interop.Excel.Workbook.CustomXMLParts является типом, вы не можете назначить его переменной myCustomXMLParts. Вы должны были бы

Microsoft.Office.Interop.Excel.Workbook myWorkbook = <some appropriate constructor>;
...
Microsoft.Office.Interop.Excel.Workbook.CustomXMLParts myParts = myWorkbook.CustomXMLParts;