openxml учебник
Начало работы с openxml
В этом разделе представлен обзор того, что такое openxml, и почему разработчик может захотеть его использовать.
Следует также упомянуть о любых крупных предметах в openxml и ссылки на связанные темы. Поскольку Documentation for openxml является новым, вам может потребоваться создать начальные версии этих связанных тем.
Установка SDK OpenXML и инструмента повышения производительности на вашем компьютере
Перейдите по ссылке Microsoft для загрузки SDK OpenXML . Нажмите красную кнопку загрузки. На следующем экране щелкните поле рядом с OpenXMLSDKToolV25.msi и нажмите кнопку «Далее», чтобы начать загрузку.
После завершения загрузки запустите OpenXMLSDKToolV25.msi и следуйте инструкциям на экране.
Установщик помещает файлы в следующий каталог по умолчанию:
«C:Program Files (x86)Open XML SDKV2.5»
В этом каталоге находится readme, в котором объясняется, как использовать SDK и readme для инструмента повышения производительности.
xml чем открыть?
Создайте новую таблицу с OpenXML
Этот метод создаст новую электронную таблицу Excel. Перейдите в fileName которое является полным именем пути к файлу.
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System; . void Create(string fileName) < using (SpreadsheetDocument document = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook)) < var relationshipId = «rId1»; //build Workbook Part var workbookPart = document.AddWorkbookPart(); var workbook = new Workbook(); var sheets = new Sheets(); var sheet1 = new Sheet() < Name = «First Sheet», SheetId = 1, >; sheets.Append(sheet1); workbook.Append(sheets); workbookPart.Workbook = workbook; //build Worksheet Part var workSheetPart = workbookPart.AddNewPart(relationshipId); var workSheet = new Worksheet(); workSheet.Append(new SheetData()); workSheetPart.Worksheet = workSheet; //add document properties document.PackageProperties.Creator = «Your Name»; document.PackageProperties.Created = DateTime.UtcNow; >
Для этого проекта обязательно включите ссылку на DocumentFormat.OpenXml . Это расположено в пути, указанном в примере установки OpenXML.
Электронная таблица будет создана с вашим именем в качестве автора и первым листом с именем First Sheet .
Использование инструментария Open XML SDK 2.5
Чтение спецификации форматов документов в OpenXML может занять много времени. Иногда вы просто хотите посмотреть, как создать определенную функцию в текстовом документе. Инструмент производительности Open XML SDK 2.5 для Microsoft Office (OpenXmlSdkTool.exe) делает именно это. Его основные функции:
- См. Структуру файла — в каких хml-частях он содержит
- Перемещайте xml в каждой из этих частей
- Сгенерировать c # -код для создания выбранной части документа
- Ссылка на спецификацию формата файла, описывающая более подробную информацию
- Документ OpenXML Validation
Это позволяет очень эффективно использовать определенную функцию:
Чем открыть формат xml?
- Произведите пример-документ (fx — текстовый документ)
- Откройте документ в инструменте производительности
- Используйте «Код отражения» для генерации кода
Источник: learntutorials.net
Исследование качества кода Open XML SDK от Microsoft
Моё знакомство с Open XML SDK началось с того, что мне понадобилась библиотека для создания документов Word с некоторой отчётностью. После работы с Word API более 7 лет, захотелось попробовать что-нибудь новое и более удобное. Так я узнал, что у Microsoft есть альтернативное решение. По традиции, используемые в компании программы и библиотеки мы предварительно проверяем с помощью анализатора PVS-Studio.
Введение
Office Open XML, также известный как OpenXML или OOXML, представляет собой формат на основе XML для офисных документов, включая текстовые документы, электронные таблицы, презентации, а также диаграммы, фигуры и другой графический материал. Спецификация была разработана Microsoft и принята ECMA International в 2006 году. В июне 2014 года Microsoft выпустила Open XML SDK в open source. Сейчас исходники доступны на GitHub под лицензий MIT.
Для поиска ошибок в исходном коде библиотеки использовался PVS-Studio. Это инструмент для выявления ошибок и потенциальных уязвимостей в исходном коде программ, написанных на языках С, C++, C# и Java. Работает в 64-битных системах на Windows, Linux и macOS.
Проект достаточно маленький и предупреждений нашлось немного. Но выбор титульной картинки основывался как раз на результатах. Уж очень много бесполезных условных операторов в коде нашлось. Мне кажется, если отрефакторить все такие места в коде, то объём заметно сократится. Вследствие чего ещё и читаемость кода повысится.
Почему Word API, а не Open XML SDK
Как Вы могли догадаться из заголовка, я продолжил использовать Word API. У этого способа достаточно много минусов:
- Старый неудобный API;
- Должен быть установлен Microsoft Office;
- Необходимость распространять дистрибутив с библиотеками Office;
- Зависимость работы Word API от настроек локали системы;
- Низкая скорость работы.
Перечисляя всё это, я снова задумался, почему я до сих пор этим пользуюсь…
Но нет, Word API мне пока нравится больше, и вот почему.
OOXML выглядит таким образом:
This is a paragraph. This is another paragraph.
Где (Word Run) — не предложение, и даже не слово, а любой фрагмент текста, имеющий атрибуты, отличные от соседних фрагментов текста.
Программируется это примерно таким кодом:
Paragraph para = body.AppendChild(new Paragraph()); Run run = para.AppendChild(new Run()); run.AppendChild(new Text(txt));
У документа специфичная внутренняя структура, и в коде нужно создавать те же самые элементы. У Open XML SDK, я считаю, недостаточно абстрактный уровень доступа к данным. Создание документа с помощью Word API будет более понятым и коротким. Особенно, когда дело дойдёт до таблиц и других сложных структур данных.
В свою очередь, Open XML SDK решает большой ряд задач. С ним можно создавать документы не только для Word, но и для Excel и PowerPoint. Наверное, для некоторых задач эта библиотека больше подходит, но я решил пока остаться на Word API. Полностью от него отказаться в любом случае не получится, т.к. для внутренних нужд мы разрабатываем плагин для Word, а там возможно использование только Word API.
Два значения для string
V3008 The ‘_rawOuterXml’ variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 164, 161. OpenXmlElement.cs 164
internal string RawOuterXml < get =>_rawOuterXml; set < if (string.IsNullOrEmpty(value)) < _rawOuterXml = string.Empty; >_rawOuterXml = value; > >
Тип string может иметь 2 типа значений: null и текстовое значение. Использовать текстовое значение определённо безопаснее, но оба подхода имеют права на существование. Вот в этом проекте значение null использовать неприемлемо и его перезаписывают на string.Empty… по крайней мере, так задумывалось. Но из-за ошибки в RawOuterXml всё же можно записать null, а потом обратиться к этому полю, получив NullReferenceException.
V3022 Expression ‘namespaceUri != null’ is always true. OpenXmlElement.cs 497
public OpenXmlAttribute GetAttribute(string localName, string namespaceUri) < . if (namespaceUri == null) < // treat null string as empty. namespaceUri = string.Empty; >. if (HasAttributes) < if (namespaceUri != null) // . > . >
В этом фрагменте используется тот же самой подход, автор кода не сделал какую-то серьёзную ошибку, но всё ещё чувствуется запах неудачного рефакторинга. Скорее всего, одну проверку тут можно удалить, что уменьшит ширину кода, а, следовательно, повысит его читаемость.
Про компактность кода
V3009 It’s odd that this method always returns one and the same value of ‘».xml»‘. CustomXmlPartTypeInfo.cs 31
internal static string GetTargetExtension(CustomXmlPartType partType) < switch (partType) < case CustomXmlPartType.AdditionalCharacteristics: return «.xml»; case CustomXmlPartType.Bibliography: return «.xml»; case CustomXmlPartType.CustomXml: return «.xml»; case CustomXmlPartType.InkContent: return «.xml»; default: return «.xml»; >>
Не знаю, имеет ли место тут какая-нибудь опечатка или просто автор кода написал «красивый» код по его мнению. Я уверен, что нет смысла возвращать из функции столько однотипных значений и код можно сильно сократить.
Это не единственное такое место. Вот ещё парочка таких предупреждений:
- V3009 It’s odd that this method always returns one and the same value of ‘».xml»‘. CustomPropertyPartTypeInfo.cs 25
- V3009 It’s odd that this method always returns one and the same value of ‘».bin»‘. EmbeddedControlPersistenceBinaryDataPartTypeInfo.cs 22
V3139 Two or more case-branches perform the same actions. OpenXmlPartReader.cs 560
private void InnerSkip() < Debug.Assert(_xmlReader != null); switch (_elementState) < case ElementState.Null: ThrowIfNull(); break; case ElementState.EOF: return; case ElementState.Start: _xmlReader.Skip(); _elementStack.Pop(); GetElementInformation(); return; case ElementState.End: case ElementState.MiscNode: // cursor is end element, pop stack _xmlReader.Skip(); _elementStack.Pop(); GetElementInformation(); return; . >. >
К этому коду возникает меньше вопросов. Скорее всего, идентичные кейсы можно объединить и код станет короче и очевиднее.
Ещё несколько таких мест:
- V3139 Two or more case-branches perform the same actions. OpenXmlMiscNode.cs 312
- V3139 Two or more case-branches perform the same actions. CustomPropertyPartTypeInfo.cs 30
- V3139 Two or more case-branches perform the same actions. CustomXmlPartTypeInfo.cs 15
- V3139 Two or more case-branches perform the same actions. OpenXmlElement.cs 1803
Те самые Always true/false
Настало время привести примеры кода, которые определили мой выбор титульной картинки.
Предупреждение 1
V3022 Expression ‘Complete()’ is always false. ParticleCollection.cs 243
private bool IsComplete => Current is null || Current == _collection._element.FirstChild; public bool MoveNext() < . if (IsComplete) < return Complete(); >if (. ) < return Complete(); >return IsComplete ? Complete() : true; >
Свойство IsComplete используется 2 раза, и по коду легко понять, что его значение не изменится. Таким образом, в конце функции можно просто возвращать второе значение тернарного оператора – true.
Предупреждение 2
V3022 Expression ‘_elementStack.Count > 0’ is always true. OpenXmlDomReader.cs 501
private readonly Stack _elementStack; private bool MoveToNextSibling() < . if (_elementStack.Count == 0) < _elementState = ElementState.EOF; return false; >. if (_elementStack.Count > 0) // else < // no more element, EOF _elementState = ElementState.EOF; >. >
Очевидно, что если в стеке_elementStack не 0 элементов, то их больше. Код можно сократить как минимум на 8 строк.
Предупреждение 3
V3022 Expression ‘rootElement == null’ is always false. OpenXmlPartReader.cs 746
private static OpenXmlElement CreateElement(string namespaceUri, string name) < if (string.IsNullOrEmpty(name)) < throw new ArgumentException(. ); >if (NamespaceIdMap.TryGetNamespaceId(namespaceUri, out byte nsId) ElementLookup.Parts.Create(nsId, name) is OpenXmlElement element) < return element; >return new OpenXmlUnknownElement(); > private bool ReadRoot() < . var rootElement = CreateElement(. ); if (rootElement == null) // . >
Функция CreateElement не может вернуть null. Если в компании было принято правило писать методы для создания xml-нод, которые либо возвращают валидный объект, либо кидают исключение, то пользователям таких функций можно не злоупотреблять дополнительными проверками.
Предупреждение 4
V3022 Expression ‘nameProvider’ is always not null. The operator ‘?.’ is excessive. OpenXmlSimpleTypeExtensions.cs 50
public static XmlQualifiedName GetSimpleTypeQualifiedName(. ) < foreach (var validator in validators) < if (validator is INameProvider nameProvider nameProvider?.QName is XmlQualifiedName qname) // > return type.GetSimpleTypeQualifiedName(); >
Оператор is имеет такой паттерн:
expr is type varname
Если результат выражения is будет true, то в varname будет записана ненулевая ссылка, так что дополнительная её проверка на null является лишней.
Предупреждение 5
Предупреждение 7
V3022 Expression ‘OpenSettings.MarkupCompatibilityProcessSettings == null’ is always false. OpenXmlPackage.cs 661
public MarkupCompatibilityProcessSettings MarkupCompatibilityProcessSettings < get < if (_mcSettings is null) < _mcSettings = new MarkupCompatibilityProcessSettings(. ); >return _mcSettings; > set < _mcSettings = value; >> public MarkupCompatibilityProcessSettings MarkupCompatibilityProcessSettings < get < if (OpenSettings.MarkupCompatibilityProcessSettings == null) // else < return OpenSettings.MarkupCompatibilityProcessSettings; >> >
Свойство MarkupCompatibilityProcessSettings никогда не возвращает null. Если в геттере выясняется, что поле класса имеет значение null, то объект перезаписывается на новый. Ещё обратите внимание, что это не рекурсивный вызов одного свойства, а это одноимённые свойства из разных классов. Возможно, некоторая путаница и привела к написанию лишних проверок.
Остальные предупреждения
Предупреждение 1
V3080 Possible null dereference. Consider inspecting ‘previousSibling’. OpenXmlCompositeElement.cs 380
public OpenXmlElement PreviousSibling() < if (!(Parent is OpenXmlCompositeElement parent)) < return null; >. > public override T InsertBefore(T newChild, OpenXmlElement referenceChild) < . OpenXmlElement previousSibling = nextNode.PreviousSibling(); prevNode.Next = nextNode; previousSibling.Next = prevNode; //
А вот пример, где дополнительной проверки как раз не хватает. Метод PreviousSibling как раз может вернуть значение null, а результат этой функции сразу используется без проверки.
Ещё 2 опасных места:
- V3080 Possible null dereference. Consider inspecting ‘prevNode’. OpenXmlCompositeElement.cs 489
- V3080 Possible null dereference. Consider inspecting ‘prevNode’. OpenXmlCompositeElement.cs 497
V3093 The ‘ . foreach (var e in root.Descendants(. )) < if (e != element > . >
Некоторые любят применять оператор ‘ private string _message; [NonSerialized] private readonly object _sender; [NonSerialized] private OpenXmlPart _subPart; [NonSerialized] private OpenXmlPart _part; . internal DataPartReferenceRelationship DataPartReferenceRelationship < get; set; >//
Сериализация класса OpenXmlPackageValidationEventArgs может стать неудачной из-за того, что одно из свойств забыли пометить несериализуемым. Либо необходимо доработать возвращаемый тип этого свойства до сериализуемого, иначе может возникать исключение в рантайме.
Заключение
Мы в компании любим проекты и технологии Microsoft. В разделе, где мы перечисляем Open Source проекты, проверенные с помощью PVS-Studio, мы даже выделили для Microsoft отдельный раздел. Там уже накопился 21 проект, про которые написано 26 статей. Это 27-я.
Уверен, Вас интересует, есть ли среди наших клиентов Microsoft. Ответ – да! Но не будем забывать, что это огромная корпорация, ведущая разработку по всему миру. Определённо есть подразделения, которые уже используют PVS-Studio в своих проектах, но тех, которые не используют, ещё больше! И наш опыт работы с открытыми проектами показывает, что им явно не хватает хорошего инструмента для поиска ошибок ;).
Ещё из новостей, кому интересен анализ кода на C++, C# и Java: мы недавно добавили поддержку стандарта OWASP и активно увеличиваем его покрытие.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Svyatoslav Razmyslov. Analyzing the Code Quality of Microsoft’s Open XML SDK.
Источник: habr.com
Что делать, если не удается открыть файл Office Open XML: как исправить
Почему появляется ошибка «не удается открыть файл Office Open XML» в продуктах Office
Чаще всего такая ошибка связана с внутренним содержимым. Но самое интересное, что она возникает совершенно внезапно в тот момент, когда ее меньше всего ждешь. В любом случа е т акая ошибка возникает при ошибке в последнем редактировании документа в формате Office Open XML.
На самом деле, заострять свое внимание и просто гадать, почему возникли проблемы , не стоит. Лучше приступать к поиску проблем и решать их , т ем более что у всех вероятных причин возникновения этой ошибки алгоритм исправления один.
Ошибка «не удается открыть файл Office Open XML»: как исправить
- обычный текст;
- графическое изображение;
- ссылки на веб-сайты;
- таблицы с информацией;
- различные диаграммы;
- и многое другое.
- Программа «Notepad++». Отлично сработает в тех случаях, если документ в формате Office Open XML является текстовым. Notepad++ в этом случае легко откроет его и поможет восстановить текстовые данные, даже если Word не смог это го сделать. Но у такого способа есть один минус — Notepad++ не поддерживает «текстовое форматирование». Простым языком : у вас перед глазами будет только текст без заголовков и абзацев — все это нужно будет восстановить «вручную» , з ато сам текст сохранится полностью.
- Программа «WordPad». Это малоизвестный встроенный в операционную систему Windows текстовый редактор. Он не функциональный и не имеет таких возможностей , как Notepad++ или Word, поэтому им мало кто пользуется. Но он всегда рядом и может открыть документ, когда другие «офисные программы» пишут: «не удается открыть файл Office Open XML». Наведите на проблемный файл курсор и откройте меню «Открыть с помощью. ». Там найдите WordPad и откройте свой документ. Кстати, он работает с текстом, изображениями и ссылками, поэтому поможет восстановить данные этих видов.
- Программа «XMLPad». Это сторонняя программа, которую нужно скачать из интернета. Она простая и бесплатная, но в вашем проблемном случае должна помочь. Она способна открыть файлы разных форматов, в том числе и формата «Office Open XML». Обычно она открывает этот формат даже в тех случаях, когда «родные» программы выдают ошибку. Но вся ее прелесть в том, что она не просто открывает проблемный документ, а еще и показывает , в какой строке и каком месте возникла ошибка, мешающая «родным» программам.
- Другие «офисы». Иногда ошибка «не удается открыть файл Office Open XML» решается очень просто. Нужно поменять «офисный пакет». Чаще всего такая ошибка появляется именно у MS Office, поэтому попробуйте открыть проблемный документ в Libre Office или Open Office. Кстати, оба «офисных пакета» бесплатны и некоторым пользователям помогли решить проблему с этой ошибкой.
Заключение
Практика показала, что чаще всего ошибка «не удается открыть файл формата Office Open XML» появляется в Microsoft Office, когда в документе преобладают технические формулы, а сам документ разрастается до больших размеров. Это указывает на то, что с большими размерами и формулами у «офисного пакета» есть некоторые проблемы.
Понятно, что от формул в документе никуда не денешься, если они там должны быть. Но вот с «большими размерами» документа можно бороться. Все , что нужно делать , — это заранее сохранять небольшие резервные части своей работы. Например , вы работаете над курсовой или дипломной работой, а может , пишете книгу.
В этом случа е н аписали 50-100 страниц работы, тогда сохраните ее отдельным файлом и дальше продолжайте работу. Потом еще 50-100 страниц — опять сохраните отдельным файлом. В этом случае, если в конце с документом возникнет какая-то проблема, тогда у вас всегда будут работающие копии на руках.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Источник: codernet.ru
Конструкция OPENXML в T-SQL – описание и примеры
Всем привет! Сейчас мы рассмотрим возможность Microsoft SQL Server получать из XML данных привычные для нас табличные данные, иными словами, мы поговорим о том, как извлекать данные из XML документа. В языке T-SQL это реализуется с помощью специальной конструкции OPENXML.
Ранее, в материале «Создание XML данных с помощью конструкции FOR XML», мы рассмотрели возможность SQL Server формировать XML документы на языке T-SQL, например, для того чтобы передавать их какому-нибудь клиентскому приложению. Сегодня мы научимся обрабатывать XML данные, которые поступают к нам, например, все от того же клиентского приложения. Если Вам необходимо просто сохранить XML документ, то, конечно же, извлекать из него данные необязательно, Вам достаточно сохранить их в таблице в столбце с типом данных XML. Но если Вам нужна информация, которая есть в этом XML документе, например, для ее сохранения в определённой табличной структуре, то Вам придётся обработать этот XML документ и извлечь из него соответствующие данные.
В Microsoft SQL Server извлечь данные из XML документа можно с помощью функции OPENXML.
OPENXML в Microsoft SQL Server
OPENXML – это специальная функция, которая извлекает данные из XML документа. Другими словами, она может на входе получить XML данные, а на выходе дать нам результирующий набор строк, как будто это результат запроса к обычным таблицам или представлениям. Эти данные мы, соответственно, можем сохранить или сразу провести какой-то анализ.
OPENXML — это не просто табличная функция, как было уже отмечено, это целая конструкция, так как чтобы использовать функцию, XML документ предварительно необходимо подготовить. А делается это с помощью системной хранимой процедуры sp_xml_preparedocument, которая проводит синтаксический анализ XML данных и возвращает дескриптор XML документа, который мы и передаем в функцию OPENXML для извлечения данных.
После того как мы извлечем данные, дескриптор XML документа необходимо удалить системной процедурой sp_xml_removedocument, для того чтобы освободить память. Можно этого и не делать, тогда в этом случае дескриптор будет существовать до конца сеанса (но чтобы избежать проблем с недостатком памяти, рекомендовано вручную удалять дескриптор, т.е. использовать процедуру).
Функция OPENXML имеет несколько параметров:
После функции, с помощью ключевого слова WITH, указывается формат набора выходных строк, т.е. мы перечисляем столбцы и их тип данных.
Примеры работы функции OPENXML в T-SQL
Для того чтобы посмотреть, как работает данная функция, давайте сначала сформируем XML документ, а затем извлечем из него данные в табличном виде. Для этого нам нужны данные, давайте их добавим.
Примечание! Начинающим рекомендую ознакомиться с материалом «Справочник по Transact-SQL».
Исходные данные для примера
—Инструкция создания таблицы CREATE TABLE TestTable( [ProductId] INT IDENTITY(1,1) NOT NULL, [CategoryId] INT NOT NULL, [ProductName] VARCHAR(100) NOT NULL, [Price] MONEY NULL ) GO —Инструкция добавления данных INSERT INTO TestTable VALUES (1,’Клавиатура’, 100), (1, ‘Мышь’, 50), (2, ‘Телефон’, 300) GO —Запросы на выборку SELECT * FROM TestTable
Извлечение данных из XML документа функцией OPENXML
Чтобы сформировать XML документ, мы используем конструкцию FOR XML. Затем с помощью функции OPENXML мы извлечем данные из полученного документа. Код в примере ниже я прокомментировал.
В функцию OPENXML мы передаем переменную с дескриптором, указываем, какой элемент будет являться строкой, в нашем случае каждый элемент Product это строка, а также уточняем, какой метод сопоставления использовать, в нашем случае с использованием элементов.
После того как XML документ мы обработали, удаляем его дескриптор процедурой sp_xml_removedocument, передав в нее, соответственно, переменную с дескриптором.
Заметка! Для профессионального изучения языка T-SQL рекомендую посмотреть мои видеокурсы по T-SQL.
Источник: info-comp.ru