{"id":13706482,"url":"https://github.com/Alex-Butenko/OpenXML-for-VSTO","last_synced_at":"2025-05-05T20:31:35.956Z","repository":{"id":114960060,"uuid":"263514920","full_name":"Alex-Butenko/OpenXML-for-VSTO","owner":"Alex-Butenko","description":"Enable OpenXML for VSTO add-ins","archived":false,"fork":false,"pushed_at":"2024-07-25T17:03:07.000Z","size":77,"stargazers_count":7,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-18T18:08:56.123Z","etag":null,"topics":["excel","excel-addin","excel-automation","interop","msword","openxml","openxml-excel","powerpoint","powerpoint-add-in","powerpoint-automation","vsto","word-add-in","word-automation"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alex-Butenko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-13T03:25:05.000Z","updated_at":"2024-07-25T17:03:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"1ce9d215-5858-4fee-8b93-66b50181ca44","html_url":"https://github.com/Alex-Butenko/OpenXML-for-VSTO","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Butenko%2FOpenXML-for-VSTO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Butenko%2FOpenXML-for-VSTO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Butenko%2FOpenXML-for-VSTO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alex-Butenko%2FOpenXML-for-VSTO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alex-Butenko","download_url":"https://codeload.github.com/Alex-Butenko/OpenXML-for-VSTO/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252571097,"owners_count":21769775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["excel","excel-addin","excel-automation","interop","msword","openxml","openxml-excel","powerpoint","powerpoint-add-in","powerpoint-automation","vsto","word-add-in","word-automation"],"created_at":"2024-08-02T22:00:57.673Z","updated_at":"2025-05-05T20:31:35.500Z","avatar_url":"https://github.com/Alex-Butenko.png","language":"C#","funding_links":[],"categories":["C# #"],"sub_categories":[],"readme":"# OpenXML-for-VSTO\nOpenXML-for-VSTO provides the ability to process content as OpenXML from VSTO-addins\n\n* [Introduction](#introduction)\n* [How it works?](#How-it-works)\n* [Where to use](#Where-to-se)\n* [Where not to use](#Where-not-to-use)\n* [Benchmark](#Benchmark)\n* [Issues](#Issues)\n* [Tips and tricks](#Tips-and-tricks)\n\n## Introduction\nOne of the problems of creating VSTO add-ins for MS Office is the performance of access to a large number of elements. Access is through the boundaries of the AppDomains, with a lot of Reflection. Each call can read/write only one parameter at a time, therefore, for large tables/documents, the add-in have to make millions of such calls. Moreover, these calls are performed in the UI thread, blocking or slowing down user input and worsening the user experience.\nUsing OpenXML would be a good solution, but unfortunately, the Office API does not provide easy access to OpenXML.\nThis library provides the ability to get/set an OpenXML object directly from/to VSTO add-in.\n\n## How it works\n* Copy an object to a file using Clipboard.\n* Work with the file as with any other OpenXML file.\n* Copy the object back.\n\n## When to use\nIn VSTO add-ins, in operations with thousands of objects, involving styles and formats.\n\n## When not to use\n* Office Interop except for VSTO add-ins. In this case the library does not give any advantage, as you can replace interop with any OpenXML library all at once.\n* Operations with small sets of objects - each copy paste has significant overhead that does not worth it for small sets.\n* Operations with values/formulas in Excel - these can be much faster accessed throuch 2d arrays.\n\n## Benchmark\n### Excel\nBenchmark is based on writing and reading cells - 1, 100, 10,000 or 1,000,000 two different ways - using this library (and ClosedXML) and with pure Excel interop. Each individual cell value, background color, font color, font size, italic and bold status and number format. No optimizations.\n\nWriting operations:\n\n|                 | Pure VSTO  | Using OpenXML-for-VSTO |\n|-----------------|------------|------------------------|\n| 1 cell          |00:00:00.254|    00:00:00.938        |\n| 100 cells       |00:00:00.302|    00:00:01.225        |\n| 10000 cells     |00:00:09.709|    00:00:01.967        |\n| 1,000,000 cells |00:18:31.897|    00:01:28.600        |\n\nReading operations:\n\n|                 | Pure VSTO  | Using OpenXML-for-VSTO |\n|-----------------|------------|------------------------|\n| 1 cell          |00:00:00.009|    00:00:00.754        |\n| 100 cells       |00:00:00.045|    00:00:00.740        |\n| 10000 cells     |00:00:03.287|    00:00:01.476        |\n| 1,000,000 cells |00:05:45.179|    00:00:47.838        |\n\nEven though performance for Excel can be improved in some scenarios by using union ranges, ClosedXML algorithms are less than optimal in this scenario as well, and most likely in real scenario performance gain can be much bigger.\n\n### Word\nBenchmark is based on writing and reading runs of text - 1, 100, 10,000, 100,000 or 1,000,000 two different ways - using this library  and with pure Word interop. Each individual run text, background color, font color, font size, italic and bold status. No optimizations.\n\nWriting operations:\n\n|                 | Pure VSTO  | Using OpenXML-for-VSTO |\n|-----------------|------------|------------------------|\n| 1 run           |00:00:00.027|     00:00:00.828       |\n| 100 runs        |00:00:00.623|     00:00:00.583       |\n| 10,000 runs     |00:02:10.232|     00:00:01.360       |\n| 100,000 runs    |00:51:37.007|     00:00:09.061       |\n| 1,000,000 runs  |            |     00:01:36.512       |\n\nReading operations:\n\n|                 | Pure VSTO  | Using OpenXML-for-VSTO |\n|-----------------|------------|------------------------|\n| 1 run           |00:00:00.013|     00:00:00.519       |\n| 100 runs        |00:00:00.150|     00:00:00.186       |\n| 10,000 runs     |00:00:16.284|     00:00:01.377       |\n| 100,000 runs    |00:03:02.905|     00:00:08.515       |\n| 1,000,000 runs  |            |     00:01:23.920       |\n\n\n## Issues\n* It uses the clipboard, so after each operation it looses data user potentiall saved there. There are workaronds, like save and restore clipboard for each operation, but these are not part of this library\n* Beginning from certain size (around 12 mb) of objects, the library may cause IsolatedStorageException. This exception happens because VSTO appdomain has incorrect Evidence. It is easy to fix by calling this code once before using OpenXML-for-VSTO with big objects:\n```c#\nSystem.Security.Policy.Evidence newEvidence = new System.Security.Policy.Evidence();\nnewEvidence.AddHostEvidence(new System.Security.Policy.Zone(System.Security.SecurityZone.MyComputer));\n\nSystem.AppDomain.CurrentDomain\n    .GetType()\n    .GetField(\"_SecurityIdentity\", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)?\n    .SetValue(System.AppDomain.CurrentDomain, newEvidence);\n```\n\n## Tips and tricks\nYou can save a copy of the whole workbook without using this library by using Workbook.SaveCopyAs method.\nThis does not work with Word documents, but then you can cast Document to [IPersistFile](https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-ipersistfile?redirectedfrom=MSDN) and use method Save\n\n```c#\nusing System.Runtime.InteropServices.ComTypes;\n\nIPersistFile persistFile = (IPersistFile) doc;\npersistFile.Save(\u003cpath\u003e, false);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlex-Butenko%2FOpenXML-for-VSTO","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAlex-Butenko%2FOpenXML-for-VSTO","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlex-Butenko%2FOpenXML-for-VSTO/lists"}