4

Working with Office's XML files can sometimes be a convenient way of quickly manipulating a document.

I.e. searching through the ZIP data of a PowerPoint file and changing the XML within the file.

I wonder if there is a way to access and manipulate a document's (PowerPoint, or otherwise) XML from within a VSTO Add-In and have the changes be reflected in the currently opened document in real-time? (E.g. when replacing a string).

I am looking for a solution that does not require the document to be re-opened.

The answer may well be that this is not possible/supported since I could not find official documentation in the Office Interop API.

JDR
  • 1,094
  • 1
  • 11
  • 31

1 Answers1

1

This should do the job, but keep in mind even if it does not require to reopen the document, the full content of the document is reloaded ... for a huge documents it will be slow.

For the example i am using Word document.

var wordDocument = app.ActiveDocument;
var openXmlFormattedStr = wordDocument.Content.WordOpenXML;
var manipulatedOpenXmlFormattedStr = .....; // do something with the xml
wordDocument.Content.InsertXML(manipulatedOpenXmlFormattedStr, null);

EDIT 2017-12-15: Power Point and Excel interop does not expose direct access to the open xml format. The only way is to use .SaveAs with the appropriate openxml format and then read the content from the file system.

vasil oreshenski
  • 2,788
  • 1
  • 14
  • 21
  • 1
    Thank you very much - this seems to work for [Word](https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word._document.wordopenxml.aspx) - but I could not find a comparable property in the [PowerPoint API](https://msdn.microsoft.com/en-us/library/microsoft.office.interop.powerpoint.presentation_members(v=office.14).aspx). Would you happen to know if the OpenXML API can be accessed differently? `CustomXMLPart`, for one, doesn't seem to be what exposes the OpenXML. – JDR Dec 15 '17 at 08:16
  • Sorry, i did not make enough research on the topic. After reading several other posts and play a bit the code it turns out that this is only possible with Word. Check edit. – vasil oreshenski Dec 15 '17 at 08:59
  • Thank you - that definitely answers the question, and also thanks for referring to the SaveAs method. – JDR Dec 15 '17 at 10:10
  • For what it is worth, note that you can call `WordOpenXML` and `InsertXML` on any `Word.Range`, so if you know where the change is made, you might save on reloading time by narrowing down to the range to which you apply the XML changes. One way could be to first load the overall contents (as in the response) but only to search where you want the change to be made (sort of an implicit read-only); then you can target the relevant paragraph and do `TargetPara.Range.InsertXML = GetChanges(TargetPara.Range.WordOpenXML)`. – Ama Jul 06 '21 at 15:02
  • Similarly, you can also access the XML at the level of an Excel data Sheet, by calling on `Excel.Range.Value(xlRangeValueXMLSpreadsheet)`, for example `MyWorkbook.ActiveSheet.UsedRange.Value(xlRangeValueXMLSpreadsheet)`. You would still have to iterate each sheet individually, but this already gives a lot of options. – Ama Jul 06 '21 at 15:13