Неофициальный русский перевод. Первоисточник: Microsoft Learn.
Работа с листами
В этом разделе рассматриваются классы Open XML SDK Worksheet, Chartsheet и DialogSheet, а также их связь со схемой SpreadsheetML формата файлов Open XML. Дополнительные сведения об общей структуре частей пакета и элементов, составляющих документ SpreadsheetML, см. в разделе Структура документа SpreadsheetML.
Листы в SpreadsheetML
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент sheet (<sheet/>).
Листы являются центральными структурами в книге и служат местом, где пользователь выполняет большую часть работы с электронной таблицей. Наиболее распространённым типом листа является рабочий лист, представленный в виде сетки ячеек. Ячейки рабочего листа могут содержать текст, числа, даты и формулы. Ячейки также можно форматировать. Книги обычно содержат более одного листа. Для содействия анализу данных и принятию обоснованных решений приложения электронных таблиц часто реализуют возможности и объекты, которые помогают вычислять, сортировать, фильтровать, организовывать и графически отображать сведения. Поскольку эти возможности часто очень тесно связаны с сеткой электронной таблицы, они также включаются в определение листа на диске.
К другим типам листов относятся листы диаграмм и листы диалогов.
© ISO/IEC 29500: 2016
Класс Open XML SDK Worksheet
Класс Open XML SDK Worksheet представляет элемент worksheet (<worksheet/>), определённый в схеме формата файлов Open XML для документов SpreadsheetML. Используйте класс Worksheet для работы с отдельными элементами <worksheet/> в документе SpreadsheetML.
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент worksheet (<worksheet/>).
Экземпляр части пакета этого типа содержит все данные, формулы и характеристики, связанные с данным рабочим листом.
Пакет ДОЛЖЕН (SHALL) содержать ровно одну часть пакета Worksheet для каждого рабочего листа.
В частности, атрибут id элемента sheet ДОЛЖЕН (SHALL) ссылаться на требуемую часть пакета Worksheet.
Корневым элементом части пакета с этим типом содержимого ДОЛЖЕН (SHALL) быть worksheet.
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают минимальный сценарий рабочего листа.
Наименьший возможный (пустой) лист выглядит следующим образом:
<worksheet>
<sheetData/>
</worksheet>
Пустая коллекция sheetData представляет пустую сетку; этот элемент является обязательным. Как определено в схеме, некоторые необязательные коллекции свойств листа могут располагаться перед sheetData, а некоторые — после него. Чтобы упростить логику, необходимую для вставки новой коллекции sheetData в существующий (но пустой) лист, коллекция sheetData является обязательной даже в пустом виде.
© ISO/IEC 29500: 2016
Типичная электронная таблица имеет по меньшей мере один рабочий лист. Рабочий лист содержит табличную структуру для определения данных, представленную элементом sheetData. Лист, содержащий данные, использует элемент worksheet в качестве корневого элемента для определения рабочих листов. Внутри рабочего листа данные разделены на три отдельные секции. Первая секция содержит необязательные свойства листа. Вторая секция содержит данные с использованием обязательного элемента sheetData. Третья секция содержит необязательные вспомогательные возможности, такие как защита листа и сведения о фильтрах. Для определения пустого рабочего листа достаточно использовать только элементы worksheet и sheetData. Элемент sheetData может быть пустым.
Чтобы создать новые значения для рабочего листа, определите строки внутри элемента sheetData. Эти строки содержат ячейки, содержащие значения. Элемент row определяет новую строку. Обычно первая строка в sheetData является первой строкой на видимом листе. Внутри строки создаются новые cells с использованием элемента <c/>. Значения для ячеек можно задать, сохранив элемент <v/> внутри ячейки. Обычно элемент <v/> содержит текущее значение ячейки рабочего листа. Если значение является числовым, оно хранится непосредственно в элементе <v/> в XML-файле. Если значение является строковым, оно хранится в таблице общих строк. Дополнительные сведения об использовании таблицы общих строк для хранения строковых значений см. в разделе Работа с таблицей общих строк.
В следующей таблице перечислены распространённые классы Open XML SDK, используемые при работе с классом Worksheet.
| Элемент SpreadsheetML | Класс Open XML SDK |
|---|---|
<sheetData/> |
SheetData |
<row/> |
Row |
<c/> |
Cell |
<v/> |
CellValue |
Дополнительные сведения о необязательных элементах электронной таблицы, таких как свойства листа и вспомогательные возможности листа, см. в спецификации ISO/IEC 29500.
Класс SheetData
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент данные листа (<sheetData/>).
Таблица ячеек является основной структурой рабочего листа. Она состоит из всего текста, чисел и формул в сетке.
© ISO/IEC 29500: 2016
Класс Row
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент row (<row/>).
Ячейки в таблице ячеек организованы по строкам. Каждая строка имеет индекс (атрибут r), поэтому пустые строки можно не записывать. Каждая строка указывает число определённых для неё ячеек, а также их относительное положение на листе. В этом примере первой строкой данных является строка 2.
© ISO/IEC 29500: 2016
Класс Cell
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент cell (<c/>).
Сама ячейка выражается коллекцией c. Каждая ячейка указывает своё расположение в сетке с использованием ссылочной нотации в стиле A1. Ячейка также может указывать идентификатор стиля (атрибут s) и тип данных (атрибут t). К типам ячеек относятся строка, число и логическое значение. Для оптимизации операций загрузки и сохранения значения данных по умолчанию не записываются.
© ISO/IEC 29500: 2016
Класс CellValue
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент значение ячейки (<v/>).
Ячейки содержат значения независимо от того, были ли значения введены непосредственно (например, ячейка A2 в нашем примере имеет значение External Link:) или являются результатом вычисления (например, ячейка B3 в нашем примере имеет формулу B2+1).
Строковые значения в ячейке не хранятся в таблице ячеек, если они не являются результатом вычисления. Поэтому вместо External Link в качестве содержимого узла v ячейки отображается отсчитываемый от нуля индекс в таблице общих строк, где эта строка хранится однократно. Это делается для оптимизации производительности загрузки и сохранения, а также для уменьшения дублирования сведений. Чтобы определить, является ли 0 в v числом или индексом строки, необходимо проверить тип данных ячейки. Если тип данных указывает строку, это индекс, а не числовое значение.
© ISO/IEC 29500: 2016
Пример кода Open XML SDK
Следующий пример кода создаёт документ электронной таблицы с указанным именем файла и создаёт экземпляр класса Worksheet, затем добавляет строку и добавляет ячейку в таблицу ячеек в позиции A1. Затем значению ячейки A1 присваивается числовое значение 100.
static void CreateSpreadsheetWorkbook(string filepath)
{
// Use 'using' block to ensure proper disposal of the document
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
{
// Add a WorkbookPart to the document.
WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add Sheets to the Workbook.
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
// Append a new worksheet and associate it with the workbook.
Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "mySheet" };
sheets.Append(sheet);
// Get the sheetData cell table.
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>() ?? worksheetPart.Worksheet.AppendChild(new SheetData());
// Add a row to the cell table.
Row row = new Row() { RowIndex = 1 };
sheetData.Append(row);
// In the new row, find the column location to insert a cell in A1.
Cell? refCell = null;
foreach (Cell cell in row.Elements<Cell>())
{
if (string.Compare(cell.CellReference?.Value, "A1", true) > 0)
{
refCell = cell;
break;
}
}
// Add the cell to the cell table at A1.
Cell newCell = new Cell() { CellReference = "A1" };
row.InsertBefore(newCell, refCell);
// Set the cell value to be a numeric value of 100.
newCell.CellValue = new CellValue("100");
newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
}
}
Sub CreateSpreadsheetWorkbook(filepath As String)
' Use 'Using' block to ensure proper disposal of the document
Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook)
' Add a WorkbookPart to the document.
Dim workbookPart As WorkbookPart = spreadsheetDocument.AddWorkbookPart()
workbookPart.Workbook = New Workbook()
' Add a WorksheetPart to the WorkbookPart.
Dim worksheetPart As WorksheetPart = workbookPart.AddNewPart(Of WorksheetPart)()
worksheetPart.Worksheet = New Worksheet(New SheetData())
' Add Sheets to the Workbook.
Dim sheets As Sheets = workbookPart.Workbook.AppendChild(Of Sheets)(New Sheets())
' Append a new worksheet and associate it with the workbook.
Dim sheet As Sheet = New Sheet() With {
.Id = workbookPart.GetIdOfPart(worksheetPart),
.SheetId = 1,
.Name = "mySheet"
}
sheets.Append(sheet)
' Get the sheetData cell table.
Dim sheetData As SheetData = If(worksheetPart.Worksheet.GetFirstChild(Of SheetData)(), worksheetPart.Worksheet.AppendChild(Of SheetData)(New SheetData()))
' Add a row to the cell table.
Dim row As Row = New Row() With {
.RowIndex = 1
}
sheetData.Append(row)
' In the new row, find the column location to insert a cell in A1.
Dim refCell As Cell = Nothing
For Each cell As Cell In row.Elements(Of Cell)()
If String.Compare(cell.CellReference?.Value, "A1", True) > 0 Then
refCell = cell
Exit For
End If
Next
' Add the cell to the cell table at A1.
Dim newCell As Cell = New Cell() With {
.CellReference = "A1"
}
row.InsertBefore(newCell, refCell)
' Set the cell value to be a numeric value of 100.
newCell.CellValue = New CellValue("100")
newCell.DataType = New EnumValue(Of CellValues)(CellValues.Number)
End Using
End Sub
Созданный SpreadsheetML
При выполнении кода Open XML SDK следующий XML записывается в документ SpreadsheetML, на который ссылается код. Чтобы просмотреть этот XML, откройте файл "sheet.xml" в папке "worksheets" ZIP-файла.
<?xml version="1.0" encoding="utf-8"?>
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:sheetData>
<x:row r="1">
<x:c r="A1" t="n">
<x:v>100</x:v>
</x:c>
</x:row>
</x:sheetData>
</x:worksheet>
Класс Open XML SDK Chartsheet
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент chartsheet (<chartsheet/>).
Экземпляр части пакета этого типа представляет диаграмму, которая хранится на собственном листе.
Пакет МОЖЕТ (MAY) содержать ноль или более частей пакета Chartsheet.
Пример: sheet1.xml ссылается на рисунок, являющийся целью связи в элементе связей части пакета Chartsheet:
<chartsheet xmlns:r="…" …>
<sheetViews>
<sheetView scale="64"/>
</sheetViews\>
<drawing r:id="rId1">
</chartsheet>
© ISO/IEC 29500: 2016
В следующей таблице перечислены распространённые классы Open XML SDK, используемые при работе с классом Chartsheet.
| Элемент SpreadsheetML | Класс Open XML SDK |
|---|---|
<drawing/> |
Drawing |
Класс Drawing
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент drawings (<wsDr/>).
Экземпляр части пакета этого типа содержит сведения о представлении и компоновке одного или более элементов рисунков, присутствующих на этом рабочем листе.
Пакет МОЖЕТ (MAY) содержать одну или более частей пакета Drawings, и каждая такая часть пакета ДОЛЖНА (SHALL) быть целью явной связи из части пакета Worksheet (§12.3.24) или части пакета Chartsheet (§12.3.2). На каждый рабочий лист или лист диаграммы ДОЛЖНА (SHALL) приходиться только одна часть пакета Drawings.
© ISO/IEC 29500: 2016
Класс Open XML SDK Dialogsheet
Приведённые ниже сведения из спецификации ISO/IEC 29500 описывают элемент dialogsheet (<dialogsheet/>).
Экземпляр части пакета этого типа содержит сведения об устаревшем пользовательском диалоговом окне для пользовательской формы.
Пакет МОЖЕТ (MAY) содержать одну или более частей пакета Dialogsheet.
Корневым элементом части пакета с этим типом содержимого ДОЛЖЕН (SHALL) быть dialogsheet.
Пример: sheet1.xml содержит следующее:
<dialogsheet xmlns:r="…" …>
<sheetPr>
<pageSetUpPr/>
</sheetPr>
<sheetViews>
…
</sheetViews>
…
<legacyDrawing r:id="rId1"/>
</dialogsheet>
© ISO/IEC 29500: 2016
Лицензия исходного репозитория Microsoft (оригинал)
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE