From a3c25101566e92412e884d8286f852f5f88f8561 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 5 Dec 2023 14:17:39 -0800 Subject: [PATCH 01/21] closes #295 --- ...at-receives-a-relationship-id-to-a-package.md | 13 +------------ ...ow-to-add-a-new-document-part-to-a-package.md | 6 +----- ...l-package-part-to-a-document-part-in-a-dif.md | 13 +------------ docs/general/how-to-create-a-package.md | 16 +--------------- ...contents-of-a-document-part-from-a-package.md | 13 +------------ ...w-to-remove-a-document-part-from-a-package.md | 13 +------------ ...e-theme-part-in-a-word-processing-document.md | 16 +--------------- ...search-and-replace-text-in-a-document-part.md | 13 +------------ .../includes/word/packages-and-document-parts.md | 13 +++++++++++++ docs/word/how-to-set-the-font-for-a-text-run.md | 13 +------------ 10 files changed, 22 insertions(+), 107 deletions(-) create mode 100644 docs/includes/word/packages-and-document-parts.md diff --git a/docs/general/how-to-add-a-new-document-part-that-receives-a-relationship-id-to-a-package.md b/docs/general/how-to-add-a-new-document-part-that-receives-a-relationship-id-to-a-package.md index 3c742e0a..512f0346 100644 --- a/docs/general/how-to-add-a-new-document-part-that-receives-a-relationship-id-to-a-package.md +++ b/docs/general/how-to-add-a-new-document-part-that-receives-a-relationship-id-to-a-package.md @@ -24,18 +24,7 @@ processing document. ----------------------------------------------------------------------------- -## Packages and Document Parts -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] ----------------------------------------------------------------------------- diff --git a/docs/general/how-to-add-a-new-document-part-to-a-package.md b/docs/general/how-to-add-a-new-document-part-to-a-package.md index eb869c04..40021a8f 100644 --- a/docs/general/how-to-add-a-new-document-part-to-a-package.md +++ b/docs/general/how-to-add-a-new-document-part-to-a-package.md @@ -17,11 +17,7 @@ ms.localizationpriority: medium This topic shows how to use the classes in the Open XML SDK for Office to add a document part (file) to a word processing document programmatically. - - -## Packages and document parts - -An Open XML document is stored as a package, whose format is defined by [ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The package can have multiple parts with relationships between them. The relationship between parts controls the category of the document. A document can be defined as a word-processing document if its package-relationship item contains a relationship to a main document part. If its package-relationship item contains a relationship to a presentation part it can be defined as a presentation document. If its package-relationship item contains a relationship to a workbook part, it is defined as a spreadsheet document. In this how-to topic, you'll use a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] ## Get a WordprocessingDocument object diff --git a/docs/general/how-to-copy-the-contents-of-an-open-xml-package-part-to-a-document-part-in-a-dif.md b/docs/general/how-to-copy-the-contents-of-an-open-xml-package-part-to-a-document-part-in-a-dif.md index 61ee8e7f..3429e8d8 100644 --- a/docs/general/how-to-copy-the-contents-of-an-open-xml-package-part-to-a-document-part-in-a-dif.md +++ b/docs/general/how-to-copy-the-contents-of-an-open-xml-package-part-to-a-document-part-in-a-dif.md @@ -25,18 +25,7 @@ programmatically. -------------------------------------------------------------------------------- -## Packages and Document Parts -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] -------------------------------------------------------------------------------- diff --git a/docs/general/how-to-create-a-package.md b/docs/general/how-to-create-a-package.md index a4f62cdc..5c28f447 100644 --- a/docs/general/how-to-create-a-package.md +++ b/docs/general/how-to-create-a-package.md @@ -21,21 +21,7 @@ This topic shows how to use the classes in the Open XML SDK for Office to programmatically create a word processing document package from content in the form of **WordprocessingML** XML markup. - - -## Packages and Document Parts - -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] ## Getting a WordprocessingDocument Object diff --git a/docs/general/how-to-get-the-contents-of-a-document-part-from-a-package.md b/docs/general/how-to-get-the-contents-of-a-document-part-from-a-package.md index e022e650..c092e0be 100644 --- a/docs/general/how-to-get-the-contents-of-a-document-part-from-a-package.md +++ b/docs/general/how-to-get-the-contents-of-a-document-part-from-a-package.md @@ -23,18 +23,7 @@ document programmatically. -------------------------------------------------------------------------------- -## Packages and Document Parts -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] --------------------------------------------------------------------------------- diff --git a/docs/general/how-to-remove-a-document-part-from-a-package.md b/docs/general/how-to-remove-a-document-part-from-a-package.md index e2a4c432..77742ba0 100644 --- a/docs/general/how-to-remove-a-document-part-from-a-package.md +++ b/docs/general/how-to-remove-a-document-part-from-a-package.md @@ -23,18 +23,7 @@ programmatically. -------------------------------------------------------------------------------- -## Packages and Document Parts -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] --------------------------------------------------------------------------------- diff --git a/docs/general/how-to-replace-the-theme-part-in-a-word-processing-document.md b/docs/general/how-to-replace-the-theme-part-in-a-word-processing-document.md index 8ed5b408..8e86f9c7 100644 --- a/docs/general/how-to-replace-the-theme-part-in-a-word-processing-document.md +++ b/docs/general/how-to-replace-the-theme-part-in-a-word-processing-document.md @@ -20,21 +20,7 @@ This topic shows how to use the classes in the Open XML SDK for Office to programmatically replace a document part in a word processing document. - - -## Packages and Document Parts - -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] ## Getting a WordprocessingDocument Object diff --git a/docs/general/how-to-search-and-replace-text-in-a-document-part.md b/docs/general/how-to-search-and-replace-text-in-a-document-part.md index cfdfbe19..1cdc9569 100644 --- a/docs/general/how-to-search-and-replace-text-in-a-document-part.md +++ b/docs/general/how-to-search-and-replace-text-in-a-document-part.md @@ -23,18 +23,7 @@ processing document. -------------------------------------------------------------------------------- -## Packages and Document Parts -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] --------------------------------------------------------------------------------- diff --git a/docs/includes/word/packages-and-document-parts.md b/docs/includes/word/packages-and-document-parts.md new file mode 100644 index 00000000..a2a0356b --- /dev/null +++ b/docs/includes/word/packages-and-document-parts.md @@ -0,0 +1,13 @@ +## Packages and Document Parts + +An Open XML document is stored as a package, whose format is defined by +[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The +package can have multiple parts with relationships between them. The +relationship between parts controls the category of the document. A +document can be defined as a word-processing document if its +package-relationship item contains a relationship to a main document +part. If its package-relationship item contains a relationship to a +presentation part it can be defined as a presentation document. If its +package-relationship item contains a relationship to a workbook part, it +is defined as a spreadsheet document. In this how-to topic, you will use +a word-processing document package. \ No newline at end of file diff --git a/docs/word/how-to-set-the-font-for-a-text-run.md b/docs/word/how-to-set-the-font-for-a-text-run.md index 2b14d19a..87065d56 100644 --- a/docs/word/how-to-set-the-font-for-a-text-run.md +++ b/docs/word/how-to-set-the-font-for-a-text-run.md @@ -23,18 +23,7 @@ document programmatically. -------------------------------------------------------------------------------- -## Packages and Document Parts -An Open XML document is stored as a package, whose format is defined by -[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The -package can have multiple parts with relationships between them. The -relationship between parts controls the category of the document. A -document can be defined as a word-processing document if its -package-relationship item contains a relationship to a main document -part. If its package-relationship item contains a relationship to a -presentation part it can be defined as a presentation document. If its -package-relationship item contains a relationship to a workbook part, it -is defined as a spreadsheet document. In this how-to topic, you will use -a word-processing document package. +[!include[Structure](../includes/word/packages-and-document-parts.md)] -------------------------------------------------------------------------------- From 06dd059488263367168307789fab86b7745ae04f Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 5 Dec 2023 14:27:58 -0800 Subject: [PATCH 02/21] closes #279 --- ...ry-of-all-named-ranges-in-a-spreadsheet.md | 127 ++---------------- .../cs/Program.cs | 29 ++-- .../vb/Program.vb | 23 +++- 3 files changed, 45 insertions(+), 134 deletions(-) diff --git a/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md b/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md index c16e418a..33182af6 100644 --- a/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md @@ -23,112 +23,25 @@ and ranges of all defined names in an Microsoft Excel 2010 or Microsoft Excel 2013 workbook. It contains an example **GetDefinedNames** method to illustrate this task. - - ## GetDefinedNames Method -The **GetDefinedNames** procedure accepts a +The **GetDefinedNames** method accepts a single parameter that indicates the name of the document from which to -retrieve the defined names. The procedure returns an +retrieve the defined names. The method returns an [Dictionary](https://msdn.microsoft.com/library/xfhwa508.aspx) instance that contains information about the defined names within the specified workbook, which may be empty if there are no defined names. -### [C#](#tab/cs-0) -```csharp - public static Dictionary - GetDefinedNames(String fileName) -``` - -### [Visual Basic](#tab/vb-0) -```vb - Public Function GetDefinedNames( - ByVal fileName As String) As Dictionary(Of String, String) -``` -*** - - -The method examines the workbook that you specify, looking for the part -that contains defined names. If it exists, the code iterates through all -the contents of the part, adding the name and value for each defined -name to the returned dictionary. - -## Calling the Sample Method - -To call the sample method, pass a string that contains the name of the -file from which to retrieve the defined names. The following code -example passes a string that contains the name of the file from which to -retrieve the defined names and iterates through the returned dictionary, -and displays the key and value from each item. - -### [C#](#tab/cs-1) -```csharp - var result = - GetDefinedNames(@"C:\Users\Public\Documents\definednames.xlsx"); - foreach (var dn in result) - Console.WriteLine("{0} {1}", dn.Key, dn.Value); -``` - -### [Visual Basic](#tab/vb-1) -```vb - Dim result = - GetDefinedNames("C:\Users\Public\Documents\definednames.xlsx") - For Each dn In result - Console.WriteLine("{0}: {1}", dn.Key, dn.Value) -``` -*** - - ## How the Code Works -The code starts by creating a variable named **returnValue** that the method will return before it exits. - -### [C#](#tab/cs-2) -```csharp - // Given a workbook name, return a dictionary of defined names. - // The pairs include the range name and a string representing the range. - var returnValue = new Dictionary(); - // Code removed here… - return returnValue; -``` - -### [Visual Basic](#tab/vb-2) -```vb - ' Given a workbook name, return a dictionary of defined names. - ' The pairs include the range name and a string representing the range. - Dim returnValue As New Dictionary(Of String, String) - ' Code removed here… - Return returnValue -``` -*** - - -The code continues by opening the spreadsheet document, using the **Open** method and indicating that the -document should be open for read-only access (the final false parameter). Given the open workbook, the code uses the **WorkbookPart** property to navigate to the main workbook part. The code stores this reference in a variable named **wbPart**. +The code opens the spreadsheet document, using the **Open** method, indicating that the +document should be open for read-only access with the final false parameter. Given the open workbook, the code uses the **WorkbookPart** property to navigate to the main workbook part. The code stores this reference in a variable named **wbPart**. ### [C#](#tab/cs-3) -```csharp - // Open the spreadsheet document for read-only access. - using (SpreadsheetDocument document = - SpreadsheetDocument.Open(fileName, false)) - { - // Retrieve a reference to the workbook part. - var wbPart = document.WorkbookPart; - // Code removed here. - } -``` +[!code-csharp[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-3) -```vb - ' Open the spreadsheet document for read-only access. - Using document As SpreadsheetDocument = - SpreadsheetDocument.Open(fileName, False) - - ' Retrieve a reference to the workbook part. - Dim wbPart As WorkbookPart = document.WorkbookPart - ' Code removed here… - End Using -``` +[!code-vb[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb#snippet1)] *** @@ -139,30 +52,10 @@ Given the workbook part, the next step is simple. The code uses the defined names that are contained within the workbook. If the property returns a non-null value, the code then iterates through the collection, retrieving information about each named part and adding the key name) and value (range description) to the dictionary for each defined name. ### [C#](#tab/cs-4) -```csharp - // Retrieve a reference to the defined names collection. - DefinedNames definedNames = wbPart.Workbook.DefinedNames; - - // If there are defined names, add them to the dictionary. - if (definedNames != null) - { - foreach (DefinedName dn in definedNames) - returnValue.Add(dn.Name.Value, dn.Text); - } -``` +[!code-csharp[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-4) -```vb - ' Retrieve a reference to the defined names collection. - Dim definedNames As DefinedNames = wbPart.Workbook.DefinedNames - - ' If there are defined names, add them to the dictionary. - If definedNames IsNot Nothing Then - For Each dn As DefinedName In definedNames - returnValue.Add(dn.Name.Value, dn.Text) - Next - End If -``` +[!code-vb[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb#snippet2)] *** @@ -171,10 +64,10 @@ defined names that are contained within the workbook. If the property returns a The following is the complete **GetDefinedNames** code sample in C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb#snippet0)] ## See also diff --git a/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs b/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs index 3ae2c819..d3677413 100644 --- a/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs +++ b/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/cs/Program.cs @@ -1,24 +1,25 @@ +// using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System; using System.Collections.Generic; -GetDefinedNames(args[0]); - -static Dictionary - GetDefinedNames(String fileName) +static DictionaryGetDefinedNames(String fileName) { // Given a workbook name, return a dictionary of defined names. // The pairs include the range name and a string representing the range. var returnValue = new Dictionary(); + // // Open the spreadsheet document for read-only access. - using (SpreadsheetDocument document = - SpreadsheetDocument.Open(fileName, false)) + using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false)) { // Retrieve a reference to the workbook part. var wbPart = document.WorkbookPart; + // + + // // Retrieve a reference to the defined names collection. DefinedNames? definedNames = wbPart?.Workbook?.DefinedNames; @@ -33,12 +34,18 @@ static Dictionary } } } - } - foreach (var pair in returnValue) - { - Console.WriteLine("{0} {1}", pair.Key, pair.Value); + // } return returnValue; -} \ No newline at end of file +} + +// + +var definedNames = GetDefinedNames(args[0]); + +foreach (var pair in definedNames) +{ + Console.WriteLine("Name: {0} Value: {1}", pair.Key, pair.Value); +} diff --git a/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb b/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb index 49c57887..d634aaa2 100644 --- a/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb +++ b/samples/spreadsheet/retrieve_a_dictionary_of_all_named_ranges/vb/Program.vb @@ -1,26 +1,33 @@ +' Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet Module Program Sub Main(args As String()) - End Sub + Dim definedNames = GetDefinedNames(args(0)) + For Each definedName In definedNames + Console.WriteLine("Name: {0} Value: {1}", definedName.Key, definedName.Value) + Next + End Sub - Public Function GetDefinedNames( - ByVal fileName As String) As Dictionary(Of String, String) + Public Function GetDefinedNames(ByVal fileName As String) As Dictionary(Of String, String) ' Given a workbook name, return a dictionary of defined names. ' The pairs include the range name and a string representing the range. Dim returnValue As New Dictionary(Of String, String) + ' ' Open the spreadsheet document for read-only access. - Using document As SpreadsheetDocument = - SpreadsheetDocument.Open(fileName, False) + Using document As SpreadsheetDocument = SpreadsheetDocument.Open(fileName, False) ' Retrieve a reference to the workbook part. Dim wbPart As WorkbookPart = document.WorkbookPart + ' + + ' ' Retrieve a reference to the defined names collection. Dim definedNames As DefinedNames = wbPart.Workbook.DefinedNames @@ -30,7 +37,11 @@ Module Program returnValue.Add(dn.Name.Value, dn.Text) Next End If + + ' End Using Return returnValue End Function -End Module \ No newline at end of file +End Module + +' From 7edb83a44ba43a682a57ecedbb133b99f35d016e Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 5 Dec 2023 14:44:42 -0800 Subject: [PATCH 03/21] closes #278 --- ...w-to-parse-and-read-a-large-spreadsheet.md | 138 +----------------- .../cs/Program.cs | 22 ++- .../vb/Program.vb | 26 +++- 3 files changed, 50 insertions(+), 136 deletions(-) diff --git a/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md b/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md index 283b28eb..cdb766e8 100644 --- a/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md +++ b/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md @@ -22,68 +22,6 @@ about the basic structure of a **SpreadsheetML** document, see [Structure of a S [!include[Add-ins note](../includes/addinsnote.md)] -You must use the following **using** directives -or **Imports** statements to compile the code -in this topic. - -### [C#](#tab/cs-0) -```csharp - using System; - using System.Linq; - using DocumentFormat.OpenXml; - using DocumentFormat.OpenXml.Packaging; - using DocumentFormat.OpenXml.Spreadsheet; -``` - -### [Visual Basic](#tab/vb-0) -```vb - Imports System - Imports System.Linq - Imports DocumentFormat.OpenXml - Imports DocumentFormat.OpenXml.Packaging - Imports DocumentFormat.OpenXml.Spreadsheet -``` -*** - - --------------------------------------------------------------------------------- -## Getting a SpreadsheetDocument Object -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an -Excel document package. To open and work with an Excel document, you -create an instance of the **SpreadsheetDocument** class from the document. -After you create this instance, you can use it to obtain access to the -main workbook part that contains the worksheets. The content in the -document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance, you call one of the overloads of the [Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) method. The following code sample -shows how to use the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) overload. The first -parameter takes a string that represents the full path to the document -to open. The second parameter takes a value of **true** or **false** and -represents whether or not you want the file to be opened for editing. In -this example, the parameter is **false** -because the document is opened as read-only. - -### [C#](#tab/cs-1) -```csharp - // Open the document as read-only. - using (SpreadsheetDocument spreadsheetDocument = - SpreadsheetDocument.Open(fileName, false)) - { - // Code removed here. - } -``` - -### [Visual Basic](#tab/vb-1) -```vb - ' Open the document as read-only. - Using spreadsheetDocument As SpreadsheetDocument = _ - SpreadsheetDocument.Open(filename, False) - ' Code removed here. - End Using -``` -*** - - -------------------------------------------------------------------------------- ## Approaches to Parsing Open XML Files The Open XML SDK provides two approaches to parsing Open XML files. You @@ -101,34 +39,10 @@ The following code segment is used to read a very large Excel file using the DOM approach. ### [C#](#tab/cs-2) -```csharp - WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart; - WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); - SheetData sheetData = worksheetPart.Worksheet.Elements().First(); - string text; - foreach (Row r in sheetData.Elements()) - { - foreach (Cell c in r.Elements()) - { - text = c.CellValue.Text; - Console.Write(text + " "); - } - } -``` +[!code-csharp[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-2) -```vb - Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart - Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.First() - Dim sheetData As SheetData = worksheetPart.Worksheet.Elements(Of SheetData)().First() - Dim text As String - For Each r As Row In sheetData.Elements(Of Row)() - For Each c As Cell In r.Elements(Of Cell)() - text = c.CellValue.Text - Console.Write(text & " ") - Next - Next -``` +[!code-vb[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb#snippet1)] *** @@ -137,36 +51,10 @@ sample (reading a very large Excel file), but uses the SAX approach. This is the recommended approach for reading very large files. ### [C#](#tab/cs-3) -```csharp - WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart; - WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); - - OpenXmlReader reader = OpenXmlReader.Create(worksheetPart); - string text; - while (reader.Read()) - { - if (reader.ElementType == typeof(CellValue)) - { - text = reader.GetText(); - Console.Write(text + " "); - } - } -``` +[!code-csharp[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-3) -```vb - Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart - Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.First() - - Dim reader As OpenXmlReader = OpenXmlReader.Create(worksheetPart) - Dim text As String - While reader.Read() - If reader.ElementType = GetType(CellValue) Then - text = reader.GetText() - Console.Write(text & " ") - End If - End While -``` +[!code-vb[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb#snippet2)] *** @@ -184,30 +72,20 @@ method separately by commenting the call to the one you would like to exclude. ### [C#](#tab/cs-4) -```csharp - String fileName = @"C:\Users\Public\Documents\BigFile.xlsx"; - // Comment one of the following lines to test the method separately. - ReadExcelFileDOM(fileName); // DOM - ReadExcelFileSAX(fileName); // SAX -``` +[!code-csharp[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-4) -```vb - Dim fileName As String = "C:\Users\Public\Documents\BigFile.xlsx" - ' Comment one of the following lines to test each method separately. - ReadExcelFileDOM(fileName) ' DOM - ReadExcelFileSAX(fileName) ' SAX -``` +[!code-vb[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb#snippet3)] *** The following is the complete code sample in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb#snippet0)] -------------------------------------------------------------------------------- ## See also diff --git a/samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs b/samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs index 7ccb802a..5fe6e88a 100644 --- a/samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs +++ b/samples/spreadsheet/parse_and_read_a_large_spreadsheet/cs/Program.cs @@ -1,12 +1,10 @@ +// using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System; using System.Linq; -ReadExcelFileDOM(args[0]); -ReadExcelFileSAX(args[0]); - // The DOM approach. // Note that the code below works only for cells that contain numeric values. // @@ -14,6 +12,8 @@ static void ReadExcelFileDOM(string fileName) { using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false)) { + // + WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart(); WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); SheetData sheetData = worksheetPart.Worksheet.Elements().First(); @@ -27,6 +27,8 @@ static void ReadExcelFileDOM(string fileName) Console.Write(text + " "); } } + + // Console.WriteLine(); Console.ReadKey(); @@ -38,6 +40,8 @@ static void ReadExcelFileSAX(string fileName) { using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false)) { + // + WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart(); WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); @@ -51,7 +55,17 @@ static void ReadExcelFileSAX(string fileName) Console.Write(text + " "); } } + + // + Console.WriteLine(); Console.ReadKey(); } -} \ No newline at end of file +} +// + +// +// Comment one of the following lines to test the method separately. +ReadExcelFileDOM(args[0]); // DOM +ReadExcelFileSAX(args[0]); // SAX +// \ No newline at end of file diff --git a/samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb b/samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb index c6f8a951..b9ed20e0 100644 --- a/samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb +++ b/samples/spreadsheet/parse_and_read_a_large_spreadsheet/vb/Program.vb @@ -1,11 +1,19 @@ +' Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet Module Program Sub Main(args As String()) - End Sub + ' + + ' Comment one of the following lines to test each method separately. + ReadExcelFileDOM(args(0)) ' DOM + ReadExcelFileSAX(args(0)) ' SAX + + ' + End Sub ' The DOM approach. @@ -14,6 +22,9 @@ Module Program Private Sub ReadExcelFileDOM(ByVal fileName As String) Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(fileName, False) + + ' + Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.First() Dim sheetData As SheetData = worksheetPart.Worksheet.Elements(Of SheetData)().First() @@ -24,6 +35,9 @@ Module Program Console.Write(text & " ") Next Next + + ' + Console.WriteLine() Console.ReadKey() End Using @@ -31,6 +45,9 @@ Module Program ' The SAX approach. Private Sub ReadExcelFileSAX(ByVal fileName As String) + + ' + Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(fileName, False) Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.First() @@ -43,8 +60,13 @@ Module Program Console.Write(text & " ") End If End While + + ' + Console.WriteLine() Console.ReadKey() End Using End Sub -End Module \ No newline at end of file +End Module + +' \ No newline at end of file From b729aa5fedfebdf42c705c8a3a8a00a90c92fb2a Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 5 Dec 2023 15:23:09 -0800 Subject: [PATCH 04/21] update ms.date values for previously updated files --- docs/presentation/how-to-apply-a-theme-to-a-presentation.md | 2 +- docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md | 2 +- ...etrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md | 2 +- ...eve-a-list-of-the-hidden-rows-or-columns-in-a-spreadsheet.md | 2 +- ...retrieve-a-list-of-the-hidden-worksheets-in-a-spreadsheet.md | 2 +- ...how-to-retrieve-a-list-of-the-worksheets-in-a-spreadsheet.md | 2 +- .../how-to-retrieve-the-values-of-cells-in-a-spreadsheet.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/presentation/how-to-apply-a-theme-to-a-presentation.md b/docs/presentation/how-to-apply-a-theme-to-a-presentation.md index 78aad9de..b5b6e2a2 100644 --- a/docs/presentation/how-to-apply-a-theme-to-a-presentation.md +++ b/docs/presentation/how-to-apply-a-theme-to-a-presentation.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/05/2023 ms.localizationpriority: medium --- diff --git a/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md b/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md index cdb766e8..3c9a503f 100644 --- a/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md +++ b/docs/spreadsheet/how-to-parse-and-read-a-large-spreadsheet.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/05/2023 ms.localizationpriority: high --- # Parse and read a large spreadsheet document diff --git a/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md b/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md index 33182af6..0c3e347b 100644 --- a/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-retrieve-a-dictionary-of-all-named-ranges-in-a-spreadsheet.md @@ -12,7 +12,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 06/28/2021 +ms.date: 12/05/2023 ms.localizationpriority: medium --- # Retrieve a dictionary of all named ranges in a spreadsheet document diff --git a/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-rows-or-columns-in-a-spreadsheet.md b/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-rows-or-columns-in-a-spreadsheet.md index a8b0d587..4572bd72 100644 --- a/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-rows-or-columns-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-rows-or-columns-in-a-spreadsheet.md @@ -12,7 +12,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 06/28/2021 +ms.date: 12/05/2023 ms.localizationpriority: high --- # Retrieve a list of the hidden rows or columns in a spreadsheet document diff --git a/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-worksheets-in-a-spreadsheet.md b/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-worksheets-in-a-spreadsheet.md index baa59eae..87f77f01 100644 --- a/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-worksheets-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-retrieve-a-list-of-the-hidden-worksheets-in-a-spreadsheet.md @@ -10,7 +10,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 06/28/2021 +ms.date: 11/29/2023 ms.localizationpriority: medium --- diff --git a/docs/spreadsheet/how-to-retrieve-a-list-of-the-worksheets-in-a-spreadsheet.md b/docs/spreadsheet/how-to-retrieve-a-list-of-the-worksheets-in-a-spreadsheet.md index 67330c29..ccc65726 100644 --- a/docs/spreadsheet/how-to-retrieve-a-list-of-the-worksheets-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-retrieve-a-list-of-the-worksheets-in-a-spreadsheet.md @@ -12,7 +12,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 06/28/2021 +ms.date: 11/27/2023 ms.localizationpriority: high --- # Retrieve a list of the worksheets in a spreadsheet document diff --git a/docs/spreadsheet/how-to-retrieve-the-values-of-cells-in-a-spreadsheet.md b/docs/spreadsheet/how-to-retrieve-the-values-of-cells-in-a-spreadsheet.md index 6816f8d9..a3ce0be8 100644 --- a/docs/spreadsheet/how-to-retrieve-the-values-of-cells-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-retrieve-the-values-of-cells-in-a-spreadsheet.md @@ -10,7 +10,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 06/28/2021 +ms.date: 11/20/2023 ms.localizationpriority: high --- From 5e1d51d83af2d9de3168d44df21eff7dfb224757 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Wed, 6 Dec 2023 09:08:19 -0800 Subject: [PATCH 05/21] closes #277 --- ...elete-text-from-a-cell-in-a-spreadsheet.md | 7 +- ...en-a-spreadsheet-document-from-a-stream.md | 93 ++----------------- .../open_from_a_stream/cs/Program.cs | 17 +++- .../open_from_a_stream/vb/Program.vb | 15 ++- 4 files changed, 37 insertions(+), 95 deletions(-) diff --git a/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md b/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md index f8ec9c93..8d5932ce 100644 --- a/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md @@ -19,12 +19,7 @@ This topic shows how to use the classes in the Open XML SDK for Office to delete text from a cell in a spreadsheet document programmatically. - - - -## Get a SpreadsheetDocument object - -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an Excel document package. To open and work with an Excel document, create an instance of the **SpreadsheetDocument** class from the document. After you create the instance from the document, obtain access to the main workbook part that contains the worksheets. The text in the document is represented in the package as XML using **SpreadsheetML** markup. +[!include[Structure](../includes/spreadsheet/spreadsheet-document-object.md)] To create the class instance from the document, call one of the [Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) methods. Several are provided, each with a different signature. The sample code in this topic uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a signature that requires two parameters. The first parameter takes a full path string that represents the document that you want to open. The second parameter is either **true** or **false** and represents whether you want the file to be opened for editing. Any changes that you make to the document will not be saved if this parameter is **false**. diff --git a/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md b/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md index 6b9f5b5e..60f12b35 100644 --- a/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md +++ b/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/05/2023 ms.localizationpriority: high --- # Open a spreadsheet document from a stream @@ -36,59 +36,7 @@ Open XML SDK. -------------------------------------------------------------------------------- -## Getting a SpreadsheetDocument Object - -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an -Excel document package. To open and work with an Excel document, you -create an instance of the **SpreadsheetDocument** class from the document. -After you create the instance from the document, you can then obtain -access to the main workbook part that contains the worksheets. The text -in the document is represented in the package as XML using SpreadsheetML -markup. - -To create the class instance from the document, you call one of the -[Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) methods. Several are provided, each -with a different signature. The sample code in this topic uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a -signature that requires two parameters. The first parameter takes a full -path string that represents the document that you want to open. The -second parameter is either **true** or **false** and represents whether you want the file to -be opened for editing. Any changes that you make to the document will -not be saved if this parameter is **false**. - -The code that calls the **Open** method is -shown in the following example. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) -``` -*** - - -After you have opened the spreadsheet document package, you can add a -row to a sheet in the workbook. Each workbook has a workbook part and at -least one [Worksheet](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.worksheet.aspx). To access the [Workbook](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.aspx) assign a reference to the existing -document body, represented by the [WorkbookPart](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.workbookpart.aspx), as shown in the following -code example. - -### [C#](#tab/cs-1) -```csharp - WorkbookPart wbPart = document.WorkbookPart; -``` - -### [Visual Basic](#tab/vb-1) -```vb - Dim wbPart As WorkbookPart = document.WorkbookPart -``` -*** - +## The a SpreadsheetDocument Object The basic document structure of a SpreadsheetML document consists of the [Sheets](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheets.aspx) and [Sheet](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheet.aspx) elements, which reference the @@ -154,20 +102,10 @@ create a new [WorksheetPart](https://msdn.microsoft.com/library/office/documentf adds the new **WorksheetPart**. ### [C#](#tab/cs-2) -```csharp - // Add a new worksheet. - WorksheetPart newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(); - newWorksheetPart.Worksheet = new Worksheet(new SheetData()); - newWorksheetPart.Worksheet.Save(); -``` +[!code-csharp[](../../samples/spreadsheet/open_from_a_stream/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-2) -```vb - ' Add a new worksheet. - Dim newWorksheetPart As WorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(Of WorksheetPart)() - newWorksheetPart.Worksheet = New Worksheet(New SheetData()) - newWorksheetPart.Worksheet.Save() -``` +[!code-vb[](../../samples/spreadsheet/open_from_a_stream/vb/Program.vb#snippet1)] *** @@ -175,26 +113,13 @@ adds the new **WorksheetPart**. ## Sample Code In this example, the **OpenAndAddToSpreadsheetStream** method can be used to open a spreadsheet document from an already open stream and append -some text to it. In your program, you can use the following example to -call the **OpenAndAddToSpreadsheetStream** -method that uses a file named Sheet11.xslx. +some text to it. The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs-3) -```csharp - string strDoc = @"C:\Users\Public\Documents\Sheet11.xlsx"; - ; - Stream stream = File.Open(strDoc, FileMode.Open); - OpenAndAddToSpreadsheetStream(stream); - stream.Close(); -``` +[!code-csharp[](../../samples/spreadsheet/open_from_a_stream/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-3) -```vb - Dim strDoc As String = "C:\Users\Public\Documents\Sheet11.xlsx" - Dim stream As Stream = File.Open(strDoc, FileMode.Open) - OpenAndAddToSpreadsheetStream(stream) - stream.Close() -``` +[!code-vb[](../../samples/spreadsheet/open_from_a_stream/vb/Program.vb#snippet2)] *** @@ -204,10 +129,10 @@ close the stream passed to it. The calling code must do that. The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/open_from_a_stream/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/open_from_a_stream/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/open_from_a_stream/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/open_from_a_stream/vb/Program.vb#snippet0)] -------------------------------------------------------------------------------- ## See also diff --git a/samples/spreadsheet/open_from_a_stream/cs/Program.cs b/samples/spreadsheet/open_from_a_stream/cs/Program.cs index 72d655f3..4abdb0fb 100644 --- a/samples/spreadsheet/open_from_a_stream/cs/Program.cs +++ b/samples/spreadsheet/open_from_a_stream/cs/Program.cs @@ -1,11 +1,9 @@ +// using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.IO; using System.Linq; -FileStream fileStream = new(args[0], FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); -OpenAndAddToSpreadsheetStream(fileStream); - static void OpenAndAddToSpreadsheetStream(Stream stream) { // Open a SpreadsheetDocument based on a stream. @@ -16,10 +14,14 @@ static void OpenAndAddToSpreadsheetStream(Stream stream) // Get or create the WorkbookPart WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart(); + // + // Add a new worksheet. WorksheetPart newWorksheetPart = workbookPart.AddNewPart(); newWorksheetPart.Worksheet = new Worksheet(new SheetData()); newWorksheetPart.Worksheet.Save(); + + // Workbook workbook = workbookPart.Workbook ?? new Workbook(); @@ -50,4 +52,11 @@ static void OpenAndAddToSpreadsheetStream(Stream stream) // Dispose the document handle. spreadsheetDocument.Dispose(); } -} \ No newline at end of file +} + +// + +// +var fileStream = File.Open(args[0], FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); +OpenAndAddToSpreadsheetStream(fileStream); +// \ No newline at end of file diff --git a/samples/spreadsheet/open_from_a_stream/vb/Program.vb b/samples/spreadsheet/open_from_a_stream/vb/Program.vb index a280f5e6..b850d939 100644 --- a/samples/spreadsheet/open_from_a_stream/vb/Program.vb +++ b/samples/spreadsheet/open_from_a_stream/vb/Program.vb @@ -1,9 +1,16 @@ +' Imports System.IO Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet Module Program Sub Main(args As String()) + + ' + Dim fileStream As FileStream = New FileStream(args(0), FileMode.OpenOrCreate, FileAccess.ReadWrite) + OpenAndAddToSpreadsheetStream(fileStream) + ' + End Sub @@ -12,11 +19,15 @@ Module Program ' Open a SpreadsheetDocument based on a stream. Dim mySpreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(stream, True) + ' + ' Add a new worksheet. Dim newWorksheetPart As WorksheetPart = mySpreadsheetDocument.WorkbookPart.AddNewPart(Of WorksheetPart)() newWorksheetPart.Worksheet = New Worksheet(New SheetData()) newWorksheetPart.Worksheet.Save() + ' + Dim sheets As Sheets = mySpreadsheetDocument.WorkbookPart.Workbook.GetFirstChild(Of Sheets)() Dim relationshipId As String = mySpreadsheetDocument.WorkbookPart.GetIdOfPart(newWorksheetPart) @@ -42,4 +53,6 @@ Module Program 'Caller must close the stream. End Sub -End Module \ No newline at end of file +End Module + +' \ No newline at end of file From 8b1690c60f9f42d3528b921e8c7361002ce7400d Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Wed, 6 Dec 2023 13:03:38 -0800 Subject: [PATCH 06/21] remove incorrectly added include --- .../how-to-delete-text-from-a-cell-in-a-spreadsheet.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md b/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md index 8d5932ce..1eb293ca 100644 --- a/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md @@ -19,7 +19,9 @@ This topic shows how to use the classes in the Open XML SDK for Office to delete text from a cell in a spreadsheet document programmatically. -[!include[Structure](../includes/spreadsheet/spreadsheet-document-object.md)] +## Get a SpreadsheetDocument object + +In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an Excel document package. To open and work with an Excel document, create an instance of the **SpreadsheetDocument** class from the document. After you create the instance from the document, obtain access to the main workbook part that contains the worksheets. The text in the document is represented in the package as XML using **SpreadsheetML** markup. To create the class instance from the document, call one of the [Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) methods. Several are provided, each with a different signature. The sample code in this topic uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a signature that requires two parameters. The first parameter takes a full path string that represents the document that you want to open. The second parameter is either **true** or **false** and represents whether you want the file to be opened for editing. Any changes that you make to the document will not be saved if this parameter is **false**. From 1b11a55227f0185b3777f2320648c03434f1e86b Mon Sep 17 00:00:00 2001 From: Taylor Southwick Date: Fri, 8 Dec 2023 13:47:52 -0800 Subject: [PATCH 07/21] Update docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md --- .../how-to-open-a-spreadsheet-document-from-a-stream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md b/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md index 60f12b35..c06478e6 100644 --- a/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md +++ b/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md @@ -36,7 +36,7 @@ Open XML SDK. -------------------------------------------------------------------------------- -## The a SpreadsheetDocument Object +## The SpreadsheetDocument Object The basic document structure of a SpreadsheetML document consists of the [Sheets](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheets.aspx) and [Sheet](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheet.aspx) elements, which reference the From 94ad7385a244a4b6edb154d43d977b34afb7655d Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 12 Dec 2023 11:42:09 -0800 Subject: [PATCH 08/21] closes #276 --- ...readsheet-document-for-read-only-access.md | 80 +++---------------- .../insert_a_new_worksheet/cs/Program.cs | 6 +- .../open_for_read_only_access/cs/Program.cs | 49 +++++++++++- .../open_for_read_only_access/vb/Program.vb | 44 +++++++++- 4 files changed, 97 insertions(+), 82 deletions(-) diff --git a/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md b/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md index 323e0539..fca64e09 100644 --- a/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md +++ b/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/12/2023 ms.localizationpriority: high --- # Open a spreadsheet document for read-only access @@ -71,16 +71,10 @@ The following code example calls the **Open** Method. ### [C#](#tab/cs-0) -```csharp - // Open a SpreadsheetDocument for read-only access based on a filepath. - using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filepath, false)) -``` +[!code-csharp[](../../samples/spreadsheet/open_for_read_only_access/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-0) -```vb - ' Open a SpreadsheetDocument for read-only access based on a filepath. - Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(filepath, False) -``` +[!code-vb[](../../samples/spreadsheet/open_for_read_only_access/vb/Program.vb#snippet1)] *** @@ -94,19 +88,10 @@ document. The following code example opens a document based on a stream. ### [C#](#tab/cs-1) -```csharp - Stream stream = File.Open(strDoc, FileMode.Open); - // Open a SpreadsheetDocument for read-only access based on a stream. - using (SpreadsheetDocument spreadsheetDocument = - SpreadsheetDocument.Open(stream, false)) -``` +[!code-csharp[](../../samples/spreadsheet/open_for_read_only_access/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-1) -```vb - Dim stream As Stream = File.Open(strDoc, FileMode.Open) - ' Open a SpreadsheetDocument for read-only access based on a stream. - Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(stream, False) -``` +[!code-vb[](../../samples/spreadsheet/open_for_read_only_access/vb/Program.vb#snippet2)] *** @@ -124,43 +109,10 @@ example in the sample code. The following code example performs this operation. ### [C#](#tab/cs-2) -```csharp - // Open System.IO.Packaging.Package. - Package spreadsheetPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read); - - // Open a SpreadsheetDocument based on a package. - using (SpreadsheetDocument spreadsheetDocument = - SpreadsheetDocument.Open(spreadsheetPackage)) -``` +[!code-csharp[](../../samples/spreadsheet/open_for_read_only_access/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-2) -```vb - ' Open System.IO.Packaging.Package. - Dim spreadsheetPackage As Package = Package.Open(filepath, FileMode.Open, FileAccess.Read) - - ' Open a SpreadsheetDocument based on a package. - Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(spreadsheetPackage) -``` -*** - - -After you open the spreadsheet document package, you can access the main -workbook part. To access the main workbook part, you assign a reference -to the existing workbook part, as shown in the following code example. - -### [C#](#tab/cs-3) -```csharp - // Assign a reference to the existing workbook part. - WorkbookPart wbPart = document.WorkbookPart; -``` - -### [Visual Basic](#tab/vb-3) -```vb - ' Assign a reference to the existing workbook part. - Dim wbPart As WorkbookPart = document.WorkbookPart -``` -*** - +[!code-vb[](../../samples/spreadsheet/open_for_read_only_access/vb/Program.vb#snippet3)] --------------------------------------------------------------------------------- ## Basic Document Structure @@ -220,28 +172,14 @@ v|DocumentFormat.OpenXml.Spreadsheet.CellValue|The value of a cell. -------------------------------------------------------------------------------- ## Sample Code -The following code sample is used to open a Spreadsheet Document for -Read-only Access. You can call the **OpenSpreadsheetDocumentReadonly** method by using -the following code, which opens the file "Sheet10.xlsx," as an example. - -### [C#](#tab/cs-4) -```csharp - OpenSpreadsheetDocumentReadonly(@"C:\Users\Public\Documents\Sheet10.xlsx"); -``` - -### [Visual Basic](#tab/vb-4) -```vb - OpenSpreadsheetDocumentReadonly("C:\Users\Public\Documents\Sheet10.xlsx") -``` -*** The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/open_for_read_only_access/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/open_for_read_only_access/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/open_for_read_only_access/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/open_for_read_only_access/vb/Program.vb#snippet0)] -------------------------------------------------------------------------------- ## See also diff --git a/samples/spreadsheet/insert_a_new_worksheet/cs/Program.cs b/samples/spreadsheet/insert_a_new_worksheet/cs/Program.cs index e44a56d4..1d94ada5 100644 --- a/samples/spreadsheet/insert_a_new_worksheet/cs/Program.cs +++ b/samples/spreadsheet/insert_a_new_worksheet/cs/Program.cs @@ -2,8 +2,6 @@ using DocumentFormat.OpenXml.Spreadsheet; using System.Linq; -InsertWorksheet(args[0]); - // Given a document name, inserts a new worksheet. static void InsertWorksheet(string docName) { @@ -32,4 +30,6 @@ static void InsertWorksheet(string docName) Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName }; sheets.Append(sheet); } -} \ No newline at end of file +} + +InsertWorksheet(args[0]); diff --git a/samples/spreadsheet/open_for_read_only_access/cs/Program.cs b/samples/spreadsheet/open_for_read_only_access/cs/Program.cs index aef17368..c9cd2a8c 100644 --- a/samples/spreadsheet/open_for_read_only_access/cs/Program.cs +++ b/samples/spreadsheet/open_for_read_only_access/cs/Program.cs @@ -1,9 +1,14 @@ +// using DocumentFormat.OpenXml.Packaging; +using System.IO; +using System.IO.Packaging; -static void OpenSpreadsheetDocumentReadonly(string filepath) +static void OpenSpreadsheetDocumentReadonly(string filePath) { - // Open a SpreadsheetDocument based on a filepath. - using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filepath, false)) + // + // Open a SpreadsheetDocument based on a file path. + using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, false)) + // { if (spreadsheetDocument.WorkbookPart is not null) { @@ -14,4 +19,40 @@ static void OpenSpreadsheetDocumentReadonly(string filepath) // The rest of the code will not be called. } } -} \ No newline at end of file + + // + // Open a SpreadsheetDocument based on a stream. + Stream stream = File.Open(filePath, FileMode.Open); + + using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(stream, false)) + // + { + if (spreadsheetDocument.WorkbookPart is not null) + { + // Attempt to add a new WorksheetPart. + // The call to AddNewPart generates an exception because the file is read-only. + WorksheetPart newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(); + + // The rest of the code will not be called. + } + } + + // + // Open System.IO.Packaging.Package. + Package spreadsheetPackage = Package.Open(filePath, FileMode.Open, FileAccess.Read); + + // Open a SpreadsheetDocument based on a package. + using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(spreadsheetPackage)) + // + { + if (spreadsheetDocument.WorkbookPart is not null) + { + // Attempt to add a new WorksheetPart. + // The call to AddNewPart generates an exception because the file is read-only. + WorksheetPart newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(); + + // The rest of the code will not be called. + } + } +} +// \ No newline at end of file diff --git a/samples/spreadsheet/open_for_read_only_access/vb/Program.vb b/samples/spreadsheet/open_for_read_only_access/vb/Program.vb index 55e48516..7432fab2 100644 --- a/samples/spreadsheet/open_for_read_only_access/vb/Program.vb +++ b/samples/spreadsheet/open_for_read_only_access/vb/Program.vb @@ -1,3 +1,6 @@ +' +Imports System.IO +Imports System.IO.Packaging Imports DocumentFormat.OpenXml.Packaging Module Program @@ -6,9 +9,41 @@ Module Program - Public Sub OpenSpreadsheetDocumentReadonly(ByVal filepath As String) - ' Open a SpreadsheetDocument based on a filepath. - Using spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Open(filepath, False) + Public Sub OpenSpreadsheetDocumentReadOnly(ByVal filePath As String) + ' + ' Open a SpreadsheetDocument based on a file path. + Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(filePath, False) + ' + + ' Attempt to add a new WorksheetPart. + ' The call to AddNewPart generates an exception because the file is read-only. + Dim newWorksheetPart As WorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(Of WorksheetPart)() + + ' The rest of the code will not be called. + End Using + + ' + ' Open a SpreadsheetDocument based on a stream. + Dim stream = File.Open(filePath, FileMode.Open) + + Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(filePath, False) + ' + + ' Attempt to add a new WorksheetPart. + ' The call to AddNewPart generates an exception because the file is read-only. + Dim newWorksheetPart As WorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(Of WorksheetPart)() + + ' The rest of the code will not be called. + End Using + + ' + ' Open System.IO.Packaging.Package. + Dim spreadsheetPackage As Package = Package.Open(filePath, FileMode.Open, FileAccess.Read) + + ' Open a SpreadsheetDocument based on a package. + Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(spreadsheetPackage) + ' + ' Attempt to add a new WorksheetPart. ' The call to AddNewPart generates an exception because the file is read-only. Dim newWorksheetPart As WorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(Of WorksheetPart)() @@ -16,4 +51,5 @@ Module Program ' The rest of the code will not be called. End Using End Sub -End Module \ No newline at end of file +End Module +' \ No newline at end of file From 7f62a91fd0af5698cdad043edf094813b995e148 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 12 Dec 2023 12:13:31 -0800 Subject: [PATCH 09/21] closes #275 --- ...rge-two-adjacent-cells-in-a-spreadsheet.md | 145 +----------------- .../merge_two_adjacent_cells/cs/Program.cs | 7 +- .../merge_two_adjacent_cells/vb/Program.vb | 7 +- 3 files changed, 14 insertions(+), 145 deletions(-) diff --git a/docs/spreadsheet/how-to-merge-two-adjacent-cells-in-a-spreadsheet.md b/docs/spreadsheet/how-to-merge-two-adjacent-cells-in-a-spreadsheet.md index 3e2725c0..64d8c38c 100644 --- a/docs/spreadsheet/how-to-merge-two-adjacent-cells-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-merge-two-adjacent-cells-in-a-spreadsheet.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/12/2023 ms.localizationpriority: high --- # Merge two adjacent cells in a spreadsheet document @@ -20,114 +20,9 @@ This topic shows how to use the classes in the Open XML SDK for Office to merge two adjacent cells in a spreadsheet document programmatically. - - -------------------------------------------------------------------------------- -## Getting a SpreadsheetDocument Object - -In the Open XML SDK, the **[SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx)** class represents an -Excel document package. To open and work with an Excel document, you -create an instance of the **SpreadsheetDocument** class from the document. -After you create the instance from the document, you can then obtain -access to the main workbook part that contains the worksheets. The text -in the document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document that you call one of the -**[Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx)** overload methods. Several are -provided, each with a different signature. The sample code in this topic -uses the **[Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx)** method with a -signature that requires two parameters. The first parameter takes a full -path string that represents the document that you want to open. The -second parameter is either **true** or **false** and represents whether you want the file to -be opened for editing. Any changes that you make to the document will -not be saved if this parameter is **false**. - -The code that calls the **Open** method is -shown in the following **using** statement. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) - { - // Insert other code here. - } -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - ' Insert other code here. - End Using -``` -*** - -The **using** statement provides a recommended -alternative to the typical .Open, .Save, .Close sequence. It ensures -that the **Dispose** method (internal method -used by the Open XML SDK to clean up resources) is automatically called -when the closing brace is reached. The block that follows the **using** statement establishes a scope for the -object that is created or named in the **using** statement, in this case **document**. - - --------------------------------------------------------------------------------- -## Basic Structure of a SpreadsheetML Document - -The basic document structure of a **SpreadsheetML** document consists of the **[Sheets](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheets.aspx)** and **[Sheet](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheet.aspx)** elements, which reference the -worksheets in the **Workbook**. -A separate XML file is created for each **Worksheet**. -For example, the **SpreadsheetML** for a -workbook that has two worksheets name MySheet1 and MySheet2 is located -in the Workbook.xml file and is shown in the following code example. - -```xml - - - - - - - -``` - -The worksheet XML files contain one or more block level elements such as -**[SheetData](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheetdata.aspx)**. **sheetData** represents the cell table and contains -one or more **[Row](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.row.aspx)** elements. A **row** contains one or more **[Cell](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.cell.aspx)** elements. Each cell contains a **[CellValue](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.cellvalue.aspx)** element that represents the value -of the cell. For example, the SpreadsheetML for the first worksheet in a -workbook, that only has the value 100 in cell A1, is located in the -Sheet1.xml file and is shown in the following code example. - -```xml - - - - - - 100 - - - - -``` - -Using the Open XML SDK, you can create document structure and -content that uses strongly-typed classes that correspond to **SpreadsheetML** elements. You can find these -classes in the **DocumentFormat.OpenXML.Spreadsheet** namespace. The -following table lists the class names of the classes that correspond to -the **workbook**, **sheets**, **sheet**, **worksheet**, and **sheetData** elements. - -| SpreadsheetML Element | Open XML SDK Class | Description | -|---|---|---| -| workbook | DocumentFormat.OpenXML.Spreadsheet.Workbook | The root element for the main document part. | -| sheets | DocumentFormat. OpenXML.Spreadsheet.Sheets | The container for the block level structures such as sheet, fileVersion, and others specified in the [ISO/IEC 29500](https://www.iso.org/standard/71691.html) specification. | -| sheet | DocumentFormat.OpenXML.Spreadsheet.Sheet | A sheet that points to a sheet definition file. | -| worksheet | DocumentFormat.OpenXML.Spreadsheet.Worksheet | A sheet definition file that contains the sheet data. | -| sheetData | DocumentFormat.OpenXML.Spreadsheet.SheetData | The cell table, grouped together by rows. | -| row | DocumentFormat.OpenXml.Spreadsheet.Row | A row in the cell table. | -| c | DocumentFormat.OpenXml.Spreadsheet.Cell | A cell in a row. | -| v | DocumentFormat.OpenXml.Spreadsheet.CellValue | The value of a cell. | +[!include[Structure](../includes/spreadsheet/structure.md)] -------------------------------------------------------------------------------- @@ -137,47 +32,17 @@ The following code merges two adjacent cells in a **[SpreadsheetDocument](https: merging two cells, only the content from one of the cells is preserved. In left-to-right languages, the content in the upper-left cell is preserved. In right-to-left languages, the content in the upper-right -cell is preserved. You can call the **MergeTwoCells** method in your program by using the -following code example, which merges the two cells B2 and C2 in a sheet -named "Jane," in a file named "Sheet9.xlsx." - -### [C#](#tab/cs-1) -```csharp - string docName = @"C:\Users\Public\Documents\Sheet9.xlsx"; - string sheetName = "Jane"; - string cell1Name = "B2"; - string cell2Name = "C2"; - MergeTwoCells(docName, sheetName, cell1Name, cell2Name); -``` - -### [Visual Basic](#tab/vb-1) -```vb - Dim docName As String = "C:\Users\Public\Documents\Sheet9.xlsx" - Dim sheetName As String = "Jane" - Dim cell1Name As String = "B2" - Dim cell2Name As String = "C2" - MergeTwoCells(docName, sheetName, cell1Name, cell2Name) -``` -*** - +cell is preserved. The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/merge_two_adjacent_cells/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/merge_two_adjacent_cells/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/merge_two_adjacent_cells/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/merge_two_adjacent_cells/vb/Program.vb#snippet0)] -------------------------------------------------------------------------------- ## See also - - - [Open XML SDK class library reference](/office/open-xml/open-xml-sdk) - -[Language-Integrated Query (LINQ)](https://msdn.microsoft.com/library/bb397926.aspx) - -[Lambda Expressions](https://msdn.microsoft.com/library/bb531253.aspx) - -[Lambda Expressions (C\# Programming Guide)](https://msdn.microsoft.com/library/bb397687.aspx) diff --git a/samples/spreadsheet/merge_two_adjacent_cells/cs/Program.cs b/samples/spreadsheet/merge_two_adjacent_cells/cs/Program.cs index ace15a7a..44472c25 100644 --- a/samples/spreadsheet/merge_two_adjacent_cells/cs/Program.cs +++ b/samples/spreadsheet/merge_two_adjacent_cells/cs/Program.cs @@ -1,3 +1,4 @@ +// using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; @@ -6,7 +7,6 @@ using System.Linq; using System.Text.RegularExpressions; -MergeTwoCells(args[0], args[1], args[2], args[3]); // Given a document name, a worksheet name, and the names of two adjacent cells, merges the two cells. // When two cells are merged, only the content from one cell is preserved: @@ -147,4 +147,7 @@ static uint GetRowIndex(string cellName) Match match = regex.Match(cellName); return uint.Parse(match.Value); -} \ No newline at end of file +} +// + +MergeTwoCells(args[0], args[1], args[2], args[3]); \ No newline at end of file diff --git a/samples/spreadsheet/merge_two_adjacent_cells/vb/Program.vb b/samples/spreadsheet/merge_two_adjacent_cells/vb/Program.vb index ad293de9..d8b3f6aa 100644 --- a/samples/spreadsheet/merge_two_adjacent_cells/vb/Program.vb +++ b/samples/spreadsheet/merge_two_adjacent_cells/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports System.Text.RegularExpressions Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Packaging @@ -5,10 +6,9 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module Program Sub Main(args As String()) + MergeTwoCells(args(0), args(1), args(2), args(3)) End Sub - - ' Given a document name, a worksheet name, and the names of two adjacent cells, merges the two cells. ' When two cells are merged, only the content from one cell is preserved: ' the upper-left cell for left-to-right languages or the upper-right cell for right-to-left languages. @@ -125,4 +125,5 @@ Module Program Dim match As Match = regex.Match(cellName) Return UInteger.Parse(match.Value) End Function -End Module \ No newline at end of file +End Module +' \ No newline at end of file From 4483308d6636fc6159313f7a2c5e128cd15ef5af Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 12 Dec 2023 12:45:49 -0800 Subject: [PATCH 10/21] closes #274 --- ...nsert-text-into-a-cell-in-a-spreadsheet.md | 364 +----------------- .../insert_textto_a_cell/cs/Program.cs | 17 +- .../insert_textto_a_cell/vb/Program.vb | 14 +- 3 files changed, 37 insertions(+), 358 deletions(-) diff --git a/docs/spreadsheet/how-to-insert-text-into-a-cell-in-a-spreadsheet.md b/docs/spreadsheet/how-to-insert-text-into-a-cell-in-a-spreadsheet.md index bc18c31a..c86e7e9e 100644 --- a/docs/spreadsheet/how-to-insert-text-into-a-cell-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-insert-text-into-a-cell-in-a-spreadsheet.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/12/2023 ms.localizationpriority: high --- # Insert text into a cell in a spreadsheet document @@ -20,55 +20,7 @@ This topic shows how to use the classes in the Open XML SDK for Office to insert text into a cell in a new worksheet in a spreadsheet document programmatically. - - -------------------------------------------------------------------------------- -## Getting a SpreadsheetDocument Object -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an -Excel document package. To open and work with an Excel document, you -create an instance of the **SpreadsheetDocument** class from the document. -After you create the instance from the document, you can then obtain -access to the main workbook part that contains the worksheets. The text -in the document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document that you call one of the -[Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) overload methods. Several are -provided, each with a different signature. The sample code in this topic -uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a -signature that requires two parameters. The first parameter takes a full -path string that represents the document that you want to open. The -second parameter is either **true** or **false** and represents whether you want the file to -be opened for editing. Any changes that you make to the document will -not be saved if this parameter is **false**. - -The code that calls the **Open** method is -shown in the following **using** statement. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) - { - // Insert other code here. - } -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Using spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - ' Insert other code here. - End Using -``` -*** - - -The **using** statement provides a recommended -alternative to the typical .Open, .Save, .Close sequence. It ensures -that the **Dispose** method (internal method -used by the Open XML SDK to clean up resources) is automatically called -when the closing brace is reached. The block that follows the **using** statement establishes a scope for the -object that is created or named in the **using** statement, in this case *spreadSheet*. [!include[Structure](../includes/spreadsheet/structure.md)] @@ -79,82 +31,10 @@ inserts a new [Cell](https://msdn.microsoft.com/library/office/documentformat.op inserts the specified text into that cell. ### [C#](#tab/cs-1) -```csharp - // Given a document name and text, - // inserts a new worksheet and writes the text to cell "A1" of the new worksheet. - public static void InsertText(string docName, string text) - { - // Open the document for editing. - using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) - { - // Get the SharedStringTablePart. If it does not exist, create a new one. - SharedStringTablePart shareStringPart; - if (spreadSheet.WorkbookPart.GetPartsOfType().Count() > 0) - { - shareStringPart = spreadSheet.WorkbookPart.GetPartsOfType().First(); - } - else - { - shareStringPart = spreadSheet.WorkbookPart.AddNewPart(); - } - - // Insert the text into the SharedStringTablePart. - int index = InsertSharedStringItem(text, shareStringPart); - - // Insert a new worksheet. - WorksheetPart worksheetPart = InsertWorksheet(spreadSheet.WorkbookPart); - - // Insert cell A1 into the new worksheet. - Cell cell = InsertCellInWorksheet("A", 1, worksheetPart); - - // Set the value of cell A1. - cell.CellValue = new CellValue(index.ToString()); - cell.DataType = new EnumValue(CellValues.SharedString); - - // Save the new worksheet. - worksheetPart.Worksheet.Save(); - } - } -``` +[!code-csharp[](../../samples/spreadsheet/insert_textto_a_cell/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-1) -```vb - ' Given a document name and text, - ' inserts a new worksheet and writes the text to cell "A1" of the new worksheet. - Public Function InsertText(ByVal docName As String, ByVal text As String) - ' Open the document for editing. - Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - - Imports (spreadSheet) - ' Get the SharedStringTablePart. If it does not exist, create a new one. - Dim shareStringPart As SharedStringTablePart - - If (spreadSheet.WorkbookPart.GetPartsOfType(Of SharedStringTablePart).Count() > 0) Then - shareStringPart = spreadSheet.WorkbookPart.GetPartsOfType(Of SharedStringTablePart).First() - Else - shareStringPart = spreadSheet.WorkbookPart.AddNewPart(Of SharedStringTablePart)() - End If - - ' Insert the text into the SharedStringTablePart. - Dim index As Integer = InsertSharedStringItem(text, shareStringPart) - - ' Insert a new worksheet. - Dim worksheetPart As WorksheetPart = InsertWorksheet(spreadSheet.WorkbookPart) - - ' Insert cell A1 into the new worksheet. - Dim cell As Cell = InsertCellInWorksheet("A", 1, worksheetPart) - - ' Set the value of cell A1. - cell.CellValue = New CellValue(index.ToString) - cell.DataType = New EnumValue(Of CellValues)(CellValues.SharedString) - - ' Save the new worksheet. - worksheetPart.Worksheet.Save() - - Return 0 - End Imports - End Function -``` +[!code-vb[](../../samples/spreadsheet/insert_textto_a_cell/vb/Program.vb#snippet1)] *** @@ -170,65 +50,10 @@ The following code verifies if the specified text exists in the **SharedStringTa it does not exist. ### [C#](#tab/cs-2) -```csharp - // Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text - // and inserts it into the SharedStringTablePart. If the item already exists, returns its index. - private static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart) - { - // If the part does not contain a SharedStringTable, create one. - if (shareStringPart.SharedStringTable == null) - { - shareStringPart.SharedStringTable = new SharedStringTable(); - } - - int i = 0; - - // Iterate through all the items in the SharedStringTable. If the text already exists, return its index. - foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements()) - { - if (item.InnerText == text) - { - return i; - } - - i++; - } - - // The text does not exist in the part. Create the SharedStringItem and return its index. - shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text))); - shareStringPart.SharedStringTable.Save(); - - return i; - } -``` +[!code-csharp[](../../samples/spreadsheet/insert_textto_a_cell/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-2) -```vb - ' Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text - ' and inserts it into the SharedStringTablePart. If the item already exists, returns its index. - Private Function InsertSharedStringItem(ByVal text As String, ByVal shareStringPart As SharedStringTablePart) As Integer - ' If the part does not contain a SharedStringTable, create one. - If (shareStringPart.SharedStringTable Is Nothing) Then - shareStringPart.SharedStringTable = New SharedStringTable - End If - - Dim i As Integer = 0 - - ' Iterate through all the items in the SharedStringTable. If the text already exists, return its index. - For Each item As SharedStringItem In shareStringPart.SharedStringTable.Elements(Of SharedStringItem)() - If (item.InnerText = text) Then - Return i - End If - i = (i + 1) - Next - - ' The text does not exist in the part. Create the SharedStringItem and return its index. - shareStringPart.SharedStringTable.AppendChild(New SharedStringItem(New DocumentFormat.OpenXml.Spreadsheet.Text(text))) - shareStringPart.SharedStringTable.Save() - - Return i - End Function -``` +[!code-vb[](../../samples/spreadsheet/insert_textto_a_cell/vb/Program.vb#snippet2)] *** @@ -245,66 +70,10 @@ object by adding a new **WorksheetPart** object to the [WorkbookPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.workbookpart.aspx) object. ### [C#](#tab/cs-3) -```csharp - // Given a WorkbookPart, inserts a new worksheet. - private static WorksheetPart InsertWorksheet(WorkbookPart workbookPart) - { - // Add a new worksheet part to the workbook. - WorksheetPart newWorksheetPart = workbookPart.AddNewPart(); - newWorksheetPart.Worksheet = new Worksheet(new SheetData()); - newWorksheetPart.Worksheet.Save(); - - Sheets sheets = workbookPart.Workbook.GetFirstChild(); - string relationshipId = workbookPart.GetIdOfPart(newWorksheetPart); - - // Get a unique ID for the new sheet. - uint sheetId = 1; - if (sheets.Elements().Count() > 0) - { - sheetId = sheets.Elements().Select(s => s.SheetId.Value).Max() + 1; - } - - string sheetName = "Sheet" + sheetId; - - // Append the new worksheet and associate it with the workbook. - Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName }; - sheets.Append(sheet); - workbookPart.Workbook.Save(); - - return newWorksheetPart; - } -``` +[!code-csharp[](../../samples/spreadsheet/insert_textto_a_cell/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-3) -```vb - ' Given a WorkbookPart, inserts a new worksheet. - Private Function InsertWorksheet(ByVal workbookPart As WorkbookPart) As WorksheetPart - ' Add a new worksheet part to the workbook. - Dim newWorksheetPart As WorksheetPart = workbookPart.AddNewPart(Of WorksheetPart)() - newWorksheetPart.Worksheet = New Worksheet(New SheetData) - newWorksheetPart.Worksheet.Save() - Dim sheets As Sheets = workbookPart.Workbook.GetFirstChild(Of Sheets)() - Dim relationshipId As String = workbookPart.GetIdOfPart(newWorksheetPart) - - ' Get a unique ID for the new sheet. - Dim sheetId As UInteger = 1 - If (sheets.Elements(Of Sheet).Count() > 0) Then - sheetId = sheets.Elements(Of Sheet).Select(Function(s) s.SheetId.Value).Max() + 1 - End If - - Dim sheetName As String = ("Sheet" + sheetId.ToString()) - - ' Add the new worksheet and associate it with the workbook. - Dim sheet As Sheet = New Sheet - sheet.Id = relationshipId - sheet.SheetId = sheetId - sheet.Name = sheetName - sheets.Append(sheet) - workbookPart.Workbook.Save() - - Return newWorksheetPart - End Function -``` +[!code-vb[](../../samples/spreadsheet/insert_textto_a_cell/vb/Program.vb#snippet3)] *** @@ -319,137 +88,26 @@ In the following code, insert a new **Cell** object into a **Worksheet** object. ### [C#](#tab/cs-4) -```csharp - // Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. - // If the cell already exists, returns it. - private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart) - { - Worksheet worksheet = worksheetPart.Worksheet; - SheetData sheetData = worksheet.GetFirstChild(); - string cellReference = columnName + rowIndex; - - // If the worksheet does not contain a row with the specified row index, insert one. - Row row; - if (sheetData.Elements().Where(r => r.RowIndex == rowIndex).Count() != 0) - { - row = sheetData.Elements().Where(r => r.RowIndex == rowIndex).First(); - } - else - { - row = new Row() { RowIndex = rowIndex }; - sheetData.Append(row); - } - - // If there is not a cell with the specified column name, insert one. - if (row.Elements().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0) - { - return row.Elements().Where(c => c.CellReference.Value == cellReference).First(); - } - else - { - // Cells must be in sequential order according to CellReference. Determine where to insert the new cell. - Cell refCell = null; - foreach (Cell cell in row.Elements()) - { - if (cell.CellReference.Value.Length == cellReference.Length) - { - if (string.Compare(cell.CellReference.Value, cellReference, true) > 0) - { - refCell = cell; - break; - } - } - } - - Cell newCell = new Cell() { CellReference = cellReference }; - row.InsertBefore(newCell, refCell); - - worksheet.Save(); - return newCell; - } - } -``` +[!code-csharp[](../../samples/spreadsheet/insert_textto_a_cell/cs/Program.cs#snippet4)] ### [Visual Basic](#tab/vb-4) -```vb - ' Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. - ' If the cell already exists, return it. - Private Function InsertCellInWorksheet(ByVal columnName As String, ByVal rowIndex As UInteger, ByVal worksheetPart As WorksheetPart) As Cell - Dim worksheet As Worksheet = worksheetPart.Worksheet - Dim sheetData As SheetData = worksheet.GetFirstChild(Of SheetData)() - Dim cellReference As String = (columnName + rowIndex.ToString()) - - ' If the worksheet does not contain a row with the specified row index, insert one. - Dim row As Row - If (sheetData.Elements(Of Row).Where(Function(r) r.RowIndex.Value = rowIndex).Count() <> 0) Then - row = sheetData.Elements(Of Row).Where(Function(r) r.RowIndex.Value = rowIndex).First() - Else - row = New Row() - row.RowIndex = rowIndex - sheetData.Append(row) - End If - - ' If there is not a cell with the specified column name, insert one. - If (row.Elements(Of Cell).Where(Function(c) c.CellReference.Value = columnName + rowIndex.ToString()).Count() > 0) Then - Return row.Elements(Of Cell).Where(Function(c) c.CellReference.Value = cellReference).First() - Else - ' Cells must be in sequential order according to CellReference. Determine where to insert the new cell. - Dim refCell As Cell = Nothing - For Each cell As Cell In row.Elements(Of Cell)() - If (String.Compare(cell.CellReference.Value, cellReference, True) > 0) Then - refCell = cell - Exit For - End If - Next - - Dim newCell As Cell = New Cell - newCell.CellReference = cellReference - - row.InsertBefore(newCell, refCell) - worksheet.Save() - - Return newCell - End If - End Function -``` +[!code-vb[](../../samples/spreadsheet/insert_textto_a_cell/vb/Program.vb#snippet4)] *** -------------------------------------------------------------------------------- ## Sample Code -The following code sample is used to insert a new worksheet and write -the text to the cell "A1" of the new worksheet for a specific -spreadsheet document named "Sheet8.xlsx." To call the **InsertText** method you can use the following code -as an example. - -### [C#](#tab/cs-5) -```csharp - InsertText(@"C:\Users\Public\Documents\Sheet8.xlsx", "Inserted Text"); -``` - -### [Visual Basic](#tab/vb-5) -```vb - InsertText("C:\Users\Public\Documents\Sheet8.xlsx", "Inserted Text") -``` -*** - The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/insert_textto_a_cell/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/insert_textto_a_cell/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/insert_textto_a_cell/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/insert_textto_a_cell/vb/Program.vb#snippet0)] -------------------------------------------------------------------------------- ## See also [Open XML SDK class library reference](/office/open-xml/open-xml-sdk) - -[Language-Integrated Query (LINQ)](https://msdn.microsoft.com/library/bb397926.aspx) - -[Lambda Expressions](https://msdn.microsoft.com/library/bb531253.aspx) - -[Lambda Expressions (C\# Programming Guide)](https://msdn.microsoft.com/library/bb397687.aspx) diff --git a/samples/spreadsheet/insert_textto_a_cell/cs/Program.cs b/samples/spreadsheet/insert_textto_a_cell/cs/Program.cs index d847e946..d745ff90 100644 --- a/samples/spreadsheet/insert_textto_a_cell/cs/Program.cs +++ b/samples/spreadsheet/insert_textto_a_cell/cs/Program.cs @@ -1,14 +1,12 @@ - +// using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.Linq; -InsertText(args[0], args[1]); - +// // Given a document name and text, // inserts a new work sheet and writes the text to cell "A1" of the new worksheet. - static void InsertText(string docName, string text) { // Open the document for editing. @@ -44,7 +42,9 @@ static void InsertText(string docName, string text) worksheetPart.Worksheet.Save(); } } +// +// // Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text // and inserts it into the SharedStringTablePart. If the item already exists, returns its index. static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart) @@ -74,7 +74,9 @@ static int InsertSharedStringItem(string text, SharedStringTablePart shareString return i; } +// +// // Given a WorkbookPart, inserts a new worksheet. static WorksheetPart InsertWorksheet(WorkbookPart workbookPart) { @@ -110,7 +112,10 @@ static WorksheetPart InsertWorksheet(WorkbookPart workbookPart) return newWorksheetPart; } +// + +// // Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. // If the cell already exists, returns it. static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart) @@ -158,3 +163,7 @@ static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPar return newCell; } } +// +// + +InsertText(args[0], args[1]); \ No newline at end of file diff --git a/samples/spreadsheet/insert_textto_a_cell/vb/Program.vb b/samples/spreadsheet/insert_textto_a_cell/vb/Program.vb index 6ec4d2cc..819035d3 100644 --- a/samples/spreadsheet/insert_textto_a_cell/vb/Program.vb +++ b/samples/spreadsheet/insert_textto_a_cell/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet @@ -6,8 +7,10 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module MyModule Sub Main(args As String()) + InsertText(args(0), args(1)) End Sub + ' ' Given a document name and text, ' inserts a new worksheet and writes the text to cell "A1" of the new worksheet. Public Function InsertText(ByVal docName As String, ByVal text As String) @@ -43,7 +46,9 @@ Module MyModule Return 0 End Using End Function + ' + ' ' Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text ' and inserts it into the SharedStringTablePart. If the item already exists, returns its index. Private Function InsertSharedStringItem(ByVal text As String, ByVal shareStringPart As SharedStringTablePart) As Integer @@ -68,7 +73,9 @@ Module MyModule Return i End Function + ' + ' ' Given a WorkbookPart, inserts a new worksheet. Private Function InsertWorksheet(ByVal workbookPart As WorkbookPart) As WorksheetPart ' Add a new worksheet part to the workbook. @@ -96,7 +103,9 @@ Module MyModule Return newWorksheetPart End Function + ' + ' ' Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. ' If the cell already exists, return it. Private Function InsertCellInWorksheet(ByVal columnName As String, ByVal rowIndex As UInteger, ByVal worksheetPart As WorksheetPart) As Cell @@ -136,4 +145,7 @@ Module MyModule Return newCell End If End Function -End Module \ No newline at end of file + ' + +End Module +' From b75ba4f3c1e8025c07ed6581aeec2259eafc4ed8 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 12 Dec 2023 15:54:45 -0800 Subject: [PATCH 11/21] closes #273 --- ...sert-a-new-worksheet-into-a-spreadsheet.md | 134 +----------------- 1 file changed, 3 insertions(+), 131 deletions(-) diff --git a/docs/spreadsheet/how-to-insert-a-new-worksheet-into-a-spreadsheet.md b/docs/spreadsheet/how-to-insert-a-new-worksheet-into-a-spreadsheet.md index c04087a6..3bb56571 100644 --- a/docs/spreadsheet/how-to-insert-a-new-worksheet-into-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-insert-a-new-worksheet-into-a-spreadsheet.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/12/2023 ms.localizationpriority: high --- # Insert a new worksheet into a spreadsheet document @@ -23,133 +23,11 @@ programmatically. -------------------------------------------------------------------------------- -## Getting a SpreadsheetDocument Object -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an -Excel document package. To open and work with an Excel document, you -create an instance of the **SpreadsheetDocument** class from the document. -After you create the instance from the document, you can then obtain -access to the main workbook part that contains the worksheets. The text -in the document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document that you call one of the -[Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) methods. Several are provided, each -with a different signature. The sample code in this topic uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a -signature that requires two parameters. The first parameter takes a full -path string that represents the document that you want to open. The -second parameter is either **true** or **false** and represents whether you want the file to -be opened for editing. Any changes that you make to the document will -not be saved if this parameter is **false**. - -The code that calls the **Open** method is -shown in the following **using** statement. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(docName, true)) - { - // Insert other code here. - } -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Dim spreadSheet As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - Using (spreadSheet) - ' Insert other code here. - End Using -``` -*** - - -The **using** statement provides a recommended -alternative to the typical .Open, .Save, .Close sequence. It ensures -that the **Dispose** method (internal method -used by the Open XML SDK to clean up resources) is automatically called -when the closing brace is reached. The block that follows the **using** statement establishes a scope for the -object that is created or named in the **using** statement, in this case **spreadSheet**. - - --------------------------------------------------------------------------------- -## Basic Structure of a SpreadsheetML Document -The basic document structure of a **SpreadsheetML** document consists of the [Sheets](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheets.aspx) and [Sheet](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheet.aspx) elements, which reference the -worksheets in the [Workbook](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.aspx). A separate XML file is created -for each [Worksheet](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.worksheet.aspx). For example, the **SpreadsheetML** for a workbook that has two -worksheets name MySheet1 and MySheet2 is located in the Workbook.xml -file and is shown in the following code example. - -```xml - - - - - - - -``` - -The worksheet XML files contain one or more block level elements such as -[SheetData](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheetdata.aspx). **sheetData** represents the cell table and contains -one or more [Row](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.row.aspx) elements. A **row** contains one or more [Cell](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.cell.aspx) elements. Each cell contains a [CellValue](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.cellvalue.aspx) element that represents the value -of the cell. For example, the **SpreadsheetML** -for the first worksheet in a workbook, that only has the value 100 in -cell A1, is located in the Sheet1.xml file and is shown in the following -code example. - -```xml - - - - - - 100 - - - - -``` - -Using the Open XML SDK, you can create document structure and -content that uses strongly-typed classes that correspond to **SpreadsheetML** elements. You can find these -classes in the **DocumentFormat.OpenXML.Spreadsheet** namespace. The -following table lists the class names of the classes that correspond to -the **workbook**, **sheets**, **sheet**, **worksheet**, and **sheetData** elements. - -| SpreadsheetML Element | Open XML SDK Class | Description | -|---|---|---| -| workbook | DocumentFormat.OpenXml.Spreadsheet.Workbook | The root element for the main document part. | -| sheets | DocumentFormat.OpenXml.Spreadsheet.Sheets | The container for the block level structures such as sheet, fileVersion, and others specified in the [ISO/IEC 29500](https://www.iso.org/standard/71691.html) specification. | -| sheet | DocumentFormat.OpenXml.Spreadsheet.Sheet | A sheet that points to a sheet definition file. | -| worksheet | DocumentFormat.OpenXml.Spreadsheet.Worksheet | A sheet definition file that contains the sheet data. | -| sheetData | DocumentFormat.OpenXml.Spreadsheet.SheetData | The cell table, grouped together by rows. | -| row | DocumentFormat.OpenXml.Spreadsheet.Row | A row in the cell table. | -| c | DocumentFormat.OpenXml.Spreadsheet.Cell | A cell in a row. | -| v | DocumentFormat.OpenXml.Spreadsheet.CellValue | The value of a cell. | +[!include[Structure](../includes/spreadsheet/structure.md)] -------------------------------------------------------------------------------- ## Sample Code -In the following code, insert a blank [Worksheet](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.worksheetpart.worksheet.aspx) object by adding a blank [WorksheetPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.worksheetpart.aspx) object, generating a unique -ID for the **WorksheetPart** object, and -registering the **WorksheetPart** object in the -[WorkbookPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.workbookpart.aspx) object contained in a [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) document package. To -call the method InsertWorksheet, you can use the following code, which -inserts a worksheet in a file names "Sheet7.xslx," as an example. - -### [C#](#tab/cs-1) -```csharp - string docName = @"C:\Users\Public\Documents\Sheet7.xlsx"; - InsertWorksheet(docName); -``` - -### [Visual Basic](#tab/vb-1) -```vb - Dim docName As String = "C:\Users\Public\Documents\Sheet7.xlsx" - InsertWorksheet(docName) -``` -*** - Following is the complete sample code in both C\# and Visual Basic. @@ -163,10 +41,4 @@ Following is the complete sample code in both C\# and Visual Basic. ## See also -- [Open XML SDK class library reference](/office/open-xml/open-xml-sdk) - -[Language-Integrated Query (LINQ)](https://msdn.microsoft.com/library/bb397926.aspx) - -[Lambda Expressions](https://msdn.microsoft.com/library/bb531253.aspx) - -[Lambda Expressions (C\# Programming Guide)](https://msdn.microsoft.com/library/bb397687.aspx) +[Open XML SDK class library reference](/office/open-xml/open-xml-sdk) From 73ada711d158949b441a5b64b0f182680d495873 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 12 Dec 2023 16:24:12 -0800 Subject: [PATCH 12/21] closes #272 --- ...ow-to-insert-a-chart-into-a-spreadsheet.md | 364 +----------------- .../insert_a_chartto/cs/Program.cs | 17 +- .../insert_a_chartto/vb/Program.vb | 22 +- 3 files changed, 41 insertions(+), 362 deletions(-) diff --git a/docs/spreadsheet/how-to-insert-a-chart-into-a-spreadsheet.md b/docs/spreadsheet/how-to-insert-a-chart-into-a-spreadsheet.md index 7dc9b486..18197bbd 100644 --- a/docs/spreadsheet/how-to-insert-a-chart-into-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-insert-a-chart-into-a-spreadsheet.md @@ -9,7 +9,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 12/12/2023 ms.localizationpriority: high --- @@ -17,51 +17,6 @@ ms.localizationpriority: high This topic shows how to use the classes in the Open XML SDK for Office to insert a chart into a spreadsheet document programmatically. - - -## Get a SpreadsheetDocument object - -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an -Excel document package. To open and work with an Excel document, you -create an instance of the **SpreadsheetDocument** class from the document. -After you create the instance from the document, you can then obtain -access to the main workbook part that contains the worksheets. The -content in the document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document, you call one of the -[Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) methods. Several are provided, each -with a different signature. The sample code in this topic uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a -signature that requires two parameters. The first parameter takes a full -path string that represents the document that you want to open. The -second parameter is either **true** or **false** and represents whether you want the file to -be opened for editing. Any changes to the document will not be saved if -this parameter is **false**. - -The code that calls the **Open** method is shown in the following **using** statement. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) - { - // Insert other code here. - } -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - ' Insert other code here. - End Using -``` -*** - - -The **using** statement provides a recommended alternative to the typical .Open, .Save, .Close sequence. It ensures that the **Dispose** method (internal method used by the Open XML SDK to clean up resources) is automatically called when the closing brace is reached. The block that follows the **using** statement establishes a scope for the object that is created or named in the **using** statement, in this case *document*. - -[!include[Structure](../includes/spreadsheet/structure.md)] - ## Row element In this how-to, you are going to deal with the row, cell, and cell value @@ -191,58 +146,10 @@ In the following example cell B4 contains the number 360. After opening the spreadsheet file for read/write access, the code verifies if the specified worksheet exists. It then adds a new [DrawingsPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.drawingspart.aspx) object using the [AddNewPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.openxmlpartcontainer.addnewpart.aspx) method, appends it to the worksheet, and saves the worksheet part. The code then adds a new [ChartPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.chartpart.aspx) object, appends a new [ChartSpace](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.chartpart.chartspace.aspx) object to the **ChartPart** object, and then appends a new [EditingLanguage](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.chartspace.editinglanguage.aspx) object to the **ChartSpace*** object that specifies the language for the chart is English-US. ### [C#](#tab/cs-1) -```csharp - IEnumerable sheets = document.WorkbookPart.Workbook.Descendants().Where - (s => s.Name == worksheetName); - if (sheets.Count() == 0) - { - // The specified worksheet does not exist. - return; - } - WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id); - - // Add a new drawing to the worksheet. - DrawingsPart drawingsPart = worksheetPart.AddNewPart(); - worksheetPart.Worksheet.Append(new DocumentFormat.OpenXml.Spreadsheet.Drawing() - { Id = worksheetPart.GetIdOfPart(drawingsPart) }); - worksheetPart.Worksheet.Save(); - - // Add a new chart and set the chart language to English-US. - ChartPart chartPart = drawingsPart.AddNewPart(); - chartPart.ChartSpace = new ChartSpace(); - chartPart.ChartSpace.Append(new EditingLanguage() { Val = new StringValue("en-US") }); - DocumentFormat.OpenXml.Drawing.Charts.Chart chart = chartPart.ChartSpace.AppendChild - - (new DocumentFormat.OpenXml.Drawing.Charts.Chart()); -``` +[!code-csharp[](../../samples/spreadsheet/insert_a_chartto/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-1) -```vb - Dim sheets As IEnumerable(Of Sheet) = _ - document.WorkbookPart.Workbook.Descendants(Of Sheet)() _ - .Where(Function(s) s.Name = worksheetName) - If sheets.Count() = 0 Then - ' The specified worksheet does not exist. - Return - End If - Dim worksheetPart As WorksheetPart = _ - CType(document.WorkbookPart.GetPartById(sheets.First().Id), WorksheetPart) - - ' Add a new drawing to the worksheet. - Dim drawingsPart As DrawingsPart = worksheetPart.AddNewPart(Of DrawingsPart)() - worksheetPart.Worksheet.Append(New DocumentFormat.OpenXml.Spreadsheet.Drawing() With {.Id = _ - worksheetPart.GetIdOfPart(drawingsPart)}) - worksheetPart.Worksheet.Save() - - ' Add a new chart and set the chart language to English-US. - Dim chartPart As ChartPart = drawingsPart.AddNewPart(Of ChartPart)() - chartPart.ChartSpace = New ChartSpace() - chartPart.ChartSpace.Append(New EditingLanguage() With {.Val = _ - New StringValue("en-US")}) - Dim chart As DocumentFormat.OpenXml.Drawing.Charts.Chart = _ - chartPart.ChartSpace.AppendChild(Of DocumentFormat.OpenXml.Drawing.Charts _ - .Chart)(New DocumentFormat.OpenXml.Drawing.Charts.Chart()) -``` +[!code-vb[](../../samples/spreadsheet/insert_a_chartto/vb/Program.vb#snippet1)] *** @@ -252,293 +159,46 @@ The code then iterates through each key in the **Dictionary** class. For each ke [BarChartSeries](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.barchartseries.aspx) object to the **BarChart** object and sets the [SeriesText](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.seriestext.aspx) object of the **BarChartSeries** object to equal the key. For each key, it appends a [NumberLiteral](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.numberliteral.aspx) object to the **Values** collection of the **BarChartSeries** object and sets the **NumberLiteral** object to equal the **Dictionary** class value corresponding to the key. ### [C#](#tab/cs-2) -```csharp - // Create a new clustered column chart. - PlotArea plotArea = chart.AppendChild(new PlotArea()); - Layout layout = plotArea.AppendChild(new Layout()); - BarChart barChart = plotArea.AppendChild(new BarChart(new BarDirection() - { Val = new EnumValue(BarDirectionValues.Column) }, - new BarGrouping() { Val = new EnumValue (BarGroupingValues.Clustered) })); - - uint i = 0; - - // Iterate through each key in the Dictionary collection and add the key to the chart Series - // and add the corresponding value to the chart Values. - foreach (string key in data.Keys) - { - BarChartSeries barChartSeries = barChart.AppendChild - (new BarChartSeries(new Index() { Val = new UInt32Value(i) }, - new Order() { Val = new UInt32Value(i) }, - new SeriesText(new NumericValue() { Text = key }))); - - StringLiteral strLit = barChartSeries.AppendChild - (new CategoryAxisData()).AppendChild(new StringLiteral()); - strLit.Append(new PointCount() { Val = new UInt32Value(1U) }); - strLit.AppendChild(new StringPoint() { Index = new UInt32Value(0U) }) - .Append(new NumericValue(title)); - - NumberLiteral numLit = barChartSeries.AppendChild(new DocumentFormat.OpenXml.Drawing.Charts.Values()).AppendChild - (new NumberLiteral()); - numLit.Append(new FormatCode("General")); - numLit.Append(new PointCount() { Val = new UInt32Value(1U) }); - numLit.AppendChild(new NumericPoint() { Index = new UInt32Value(0u)}) - .Append(new NumericValue(data[key].ToString())); - - i++; - } -``` +[!code-csharp[](../../samples/spreadsheet/insert_a_chartto/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-2) -```vb - ' Create a new clustered column chart. - Dim plotArea As PlotArea = chart.AppendChild(Of PlotArea)(New PlotArea()) - Dim layout As Layout = plotArea.AppendChild(Of Layout)(New Layout()) - Dim barChart As BarChart = plotArea.AppendChild(Of BarChart)(New BarChart _ - (New BarDirection() With {.Val = New EnumValue(Of BarDirectionValues) _ - (BarDirectionValues.Column)}, New BarGrouping() With {.Val = New EnumValue _ - (Of BarGroupingValues)(BarGroupingValues.Clustered)})) - - Dim i As UInteger = 0 - - ' Iterate through each key in the Dictionary collection and add the key to the chart Series - ' and add the corresponding value to the chart Values. - For Each key As String In data.Keys - Dim barChartSeries As BarChartSeries = barChart.AppendChild(Of BarChartSeries) _ - (New BarChartSeries(New Index() With {.Val = New UInt32Value(i)}, New Order() _ - With {.Val = New UInt32Value(i)}, New SeriesText(New NumericValue() With {.Text = key}))) - - Dim strLit As StringLiteral = barChartSeries.AppendChild(Of CategoryAxisData) _ - (New CategoryAxisData()).AppendChild(Of StringLiteral)(New StringLiteral()) - strLit.Append(New PointCount() With {.Val = New UInt32Value(1UI)}) - strLit.AppendChild(Of StringPoint)(New StringPoint() With {.Index = _ - New UInt32Value(0UI)}).Append(New NumericValue(title)) - - Dim numLit As NumberLiteral = barChartSeries.AppendChild _ - (Of DocumentFormat.OpenXml.Drawing.Charts.Values)(New DocumentFormat _ - .OpenXml.Drawing.Charts.Values()).AppendChild(Of NumberLiteral)(New NumberLiteral()) - numLit.Append(New FormatCode("General")) - numLit.Append(New PointCount() With {.Val = New UInt32Value(1UI)}) - numLit.AppendChild(Of NumericPoint)(New NumericPoint() With {.Index = _ - New UInt32Value(0UI)}).Append(New NumericValue(data(key).ToString())) - - i += 1 - Next key -``` +[!code-vb[](../../samples/spreadsheet/insert_a_chartto/vb/Program.vb#snippet2)] *** The code adds the [CategoryAxis](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.categoryaxis.aspx) object and [ValueAxis](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.valueaxis.aspx) object to the chart and sets the value of the following properties: [Scaling](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.scaling.aspx), [AxisPosition](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.axisposition.aspx), [TickLabelPosition](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.ticklabelposition.aspx), [CrossingAxis](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.crossingaxis.aspx), [Crosses](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.crosses.aspx), [AutoLabeled](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.autolabeled.aspx), [LabelAlignment](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.labelalignment.aspx), and [LabelOffset](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.labeloffset.aspx). It also adds the [Legend](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.charts.chart.legend.aspx) object to the chart and saves the chart part. ### [C#](#tab/cs-3) -```csharp - barChart.Append(new AxisId() { Val = new UInt32Value(48650112u) }); - barChart.Append(new AxisId() { Val = new UInt32Value(48672768u) }); - - // Add the Category Axis. - CategoryAxis catAx = plotArea.AppendChild(new CategoryAxis(new AxisId() - { Val = new UInt32Value(48650112u) }, new Scaling(new Orientation() - { - Val = new EnumValue( - DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax) - }), - new AxisPosition() { Val = new EnumValue(AxisPositionValues.Bottom) }, - new TickLabelPosition() { Val = new EnumValue(TickLabelPositionValues.NextTo) }, - new CrossingAxis() { Val = new UInt32Value(48672768U) }, - new Crosses() { Val = new EnumValue(CrossesValues.AutoZero) }, - new AutoLabeled() { Val = new BooleanValue(true) }, - new LabelAlignment() { Val = new EnumValue(LabelAlignmentValues.Center) }, - new LabelOffset() { Val = new UInt16Value((ushort)100) })); - - // Add the Value Axis. - ValueAxis valAx = plotArea.AppendChild(new ValueAxis(new AxisId() { Val = new UInt32Value(48672768u) }, - new Scaling(new Orientation() - { - Val = new EnumValue( - DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax) - }), - new AxisPosition() { Val = new EnumValue(AxisPositionValues.Left) }, - new MajorGridlines(), - new DocumentFormat.OpenXml.Drawing.Charts.NumberingFormat() { FormatCode = new StringValue("General"), - SourceLinked = new BooleanValue(true) }, new TickLabelPosition() { Val = - new EnumValue(TickLabelPositionValues.NextTo) }, - new CrossingAxis() { Val = new UInt32Value(48650112U) }, new Crosses() { - Val = new EnumValue(CrossesValues.AutoZero) }, new CrossBetween() - { Val = new EnumValue(CrossBetweenValues.Between) })); - // Add the chart Legend. - Legend legend = chart.AppendChild(new Legend(new LegendPosition() - { Val = new EnumValue(LegendPositionValues.Right) }, - new Layout())); - - chart.Append(new PlotVisibleOnly() { Val = new BooleanValue(true) }); - - // Save the chart part. - chartPart.ChartSpace.Save(); -``` +[!code-csharp[](../../samples/spreadsheet/insert_a_chartto/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-3) -```vb - barChart.Append(New AxisId() With {.Val = New UInt32Value(48650112UI)}) - barChart.Append(New AxisId() With {.Val = New UInt32Value(48672768UI)}) - - ' Add the Category Axis. - Dim catAx As CategoryAxis = plotArea.AppendChild(Of CategoryAxis) _ - (New CategoryAxis(New AxisId() With {.Val = New UInt32Value(48650112UI)}, _ - New Scaling(New Orientation() With {.Val = New EnumValue(Of _ - DocumentFormat.OpenXml.Drawing.Charts.OrientationValues) _ - (DocumentFormat.Open Xml.Drawing.Charts.OrientationValues.MinMax)}), New AxisPosition() With _ - {.Val = New EnumValue(Of AxisPositionValues)(AxisPositionValues.Bottom)}, _ - New TickLabelPosition() With {.Val = New EnumValue(Of TickLabelPositionValues) _ - (TickLabelPositionValues.NextTo)}, New CrossingAxis() With {.Val = New UInt32Value(48672768UI)}, _ - New Crosses() With {.Val = New EnumValue(Of CrossesValues)(CrossesValues.AutoZero)} _ - , New AutoLabeled() With {.Val = New BooleanValue(True)}, New LabelAlignment()_ - With {.Val = New EnumValue(Of LabelAlignmentValues)(LabelAlignmentValues.Center)} _ - , New LabelOffset() With {.Val = New UInt16Value(CUShort(100))})) - - ' Add the Value Axis. - Dim valAx As ValueAxis = plotArea.AppendChild(Of ValueAxis)(New ValueAxis _ - (New AxisId() With {.Val = New UInt32Value(48672768UI)}, New Scaling(New _ - Orientation() With {.Val = New EnumValue(Of DocumentFormat.OpenXml.Drawing _ - .Charts.OrientationValues)(DocumentFormat.OpenXml.Drawing.Charts.OrientationValues.MinMax)}), _ - New AxisPosition() With {.Val = New EnumValue(Of AxisPositionValues)(AxisPositionValues.Left)}, _ - New MajorGridlines(), New DocumentFormat.OpenXml.Drawing.Charts.NumberingFormat() With {.FormatCode = _ - New StringValue("General"), .SourceLinked = New BooleanValue(True)}, New TickLabelPosition() With _ - {.Val = New EnumValue(Of TickLabelPositionValues)(TickLabelPositionValues.NextTo)}, New CrossingAxis() _ - With {.Val = New UInt32Value(48650112UI)}, New Crosses() With {.Val = New EnumValue(Of CrossesValues) _ - (CrossesValues.AutoZero)}, New CrossBetween() With {.Val = New EnumValue(Of CrossBetweenValues) _ - (CrossBetweenValues.Between)})) - - ' Add the chart Legend. - Dim legend As Legend = chart.AppendChild(Of Legend)(New Legend(New LegendPosition() _ - With {.Val = New EnumValue(Of LegendPositionValues)(LegendPositionValues.Right)}, New Layout())) - - chart.Append(New PlotVisibleOnly() With {.Val = New BooleanValue(True)}) - - ' Save the chart part. - chartPart.ChartSpace.Save() -``` +[!code-vb[](../../samples/spreadsheet/insert_a_chartto/vb/Program.vb#snippet3)] *** The code positions the chart on the worksheet by creating a [WorksheetDrawing](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.drawingspart.worksheetdrawing.aspx) object and appending a **TwoCellAnchor** object. The **TwoCellAnchor** object specifies how to move or resize the chart if you move the rows and columns between the [FromMarker](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.spreadsheet.frommarker.aspx) and [ToMarker](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.spreadsheet.tomarker.aspx) anchors. The code then creates a [GraphicFrame](https://msdn.microsoft.com/library/office/documentformat.openxml.drawing.spreadsheet.graphicframe.aspx) object to contain the chart and names the chart "Chart 1," and saves the worksheet drawing. ### [C#](#tab/cs-4) -```csharp - // Position the chart on the worksheet using a TwoCellAnchor object. - drawingsPart.WorksheetDrawing = new WorksheetDrawing(); - TwoCellAnchor twoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild(new TwoCellAnchor()); - twoCellAnchor.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(new ColumnId("9"), - new ColumnOffset("581025"), - new RowId("17"), - new RowOffset("114300"))); - twoCellAnchor.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(new ColumnId("17"), - new ColumnOffset("276225"), - new RowId("32"), - new RowOffset("0"))); - - // Append a GraphicFrame to the TwoCellAnchor object. - DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame graphicFrame = - twoCellAnchor.AppendChild( - new DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame()); - graphicFrame.Macro = ""; - - graphicFrame.Append(new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameProperties( - new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualDrawingProperties() { Id = new UInt32Value(2u), - Name = "Chart 1" }, new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameDrawingProperties())); - - graphicFrame.Append(new Transform(new Offset() { X = 0L, Y = 0L }, - new Extents() { Cx = 0L, Cy = 0L })); - - graphicFrame.Append(new Graphic(new GraphicData(new ChartReference() { Id = drawingsPart.GetIdOfPart(chartPart)}) - { Uri = "https://schemas.openxmlformats.org/drawingml/2006/chart" })); - - twoCellAnchor.Append(new ClientData()); - - // Save the WorksheetDrawing object. - drawingsPart.WorksheetDrawing.Save(); -``` +[!code-csharp[](../../samples/spreadsheet/insert_a_chartto/cs/Program.cs#snippet4)] ### [Visual Basic](#tab/vb-4) -```vb - ' Position the chart on the worksheet using a TwoCellAnchor object. - drawingsPart.WorksheetDrawing = New WorksheetDrawing() - Dim twoCellAnchor As TwoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild(Of _ - TwoCellAnchor)(New TwoCellAnchor()) - twoCellAnchor.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet.FromMarker(New _ - ColumnId("9"), New ColumnOffset("581025"), New RowId("17"), New RowOffset("114300"))) - twoCellAnchor.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet.ToMarker(New _ - ColumnId("17"), New ColumnOffset("276225"), New RowId("32"), New RowOffset("0"))) - - ' Append a GraphicFrame to the TwoCellAnchor object. - Dim graphicFrame As DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame = _ - twoCellAnchor.AppendChild(Of DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame) _ - (New DocumentFormat.OpenXml.Drawing.Spreadsheet.GraphicFrame()) - graphicFrame.Macro = "" - - graphicFrame.Append(New DocumentFormat.OpenXml.Drawing.Spreadsheet _ - .NonVisualGraphicFrameProperties(New DocumentFormat.OpenXml.Drawing.Spreadsheet. _ - NonVisualDrawingProperties() With {.Id = New UInt32Value(2UI), .Name = "Chart 1"}, _ - New DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualGraphicFrameDrawingProperties())) - - graphicFrame.Append(New Transform(New Offset() With {.X = 0L, .Y = 0L}, _ - New Extents() With {.Cx = 0L, .Cy = 0L})) - - graphicFrame.Append(New Graphic(New GraphicData(New ChartReference() With _ - {.Id = drawingsPart.GetIdOfPart(chartPart)}) With {.Uri = _ - "https://schemas.openxmlformats.org/drawingml/2006/chart"})) - - twoCellAnchor.Append(New ClientData()) - - ' Save the WorksheetDrawing object. - drawingsPart.WorksheetDrawing.Save() -``` +[!code-vb[](../../samples/spreadsheet/insert_a_chartto/vb/Program.vb#snippet4)] *** ## Sample Code -In the following code, you add a clustered column chart to a [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) document package using -the data from a [Dictionary\](https://msdn2.microsoft.com/library/xfhwa508) -class. For instance, you can call the method **InsertChartInSpreadsheet** by using this code segment. - -### [C#](#tab/cs-5) -```csharp - string docName = @"C:\Users\Public\Documents\Sheet6.xlsx"; - string worksheetName = "Joe"; - string title = "New Chart"; - Dictionary data = new Dictionary(); - data.Add("abc", 1); - InsertChartInSpreadsheet(docName, worksheetName, title, data); -``` - -### [Visual Basic](#tab/vb-5) -```vb - Dim docName As String = "C:\Users\Public\Documents\Sheet6.xlsx" - Dim worksheetName As String = "Joe" - Dim title As String = "New Chart" - Dim data As New Dictionary(Of String, Integer)() - data.Add("abc", 1) - InsertChartInSpreadsheet(docName, worksheetName, title, data) -``` -*** - - -After you have run the program, take a look the file named "Sheet6.xlsx" to see the inserted chart. - > [!NOTE] > This code can be run only once. You cannot create more than one instance of the chart. The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/insert_a_chartto/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/insert_a_chartto/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/insert_a_chartto/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/insert_a_chartto/vb/Program.vb#snippet0)] ## See also -- [Open XML SDK class library reference](/office/open-xml/open-xml-sdk) -[Language-Integrated Query (LINQ)](https://msdn.microsoft.com/library/bb397926.aspx) -[Lambda Expressions](https://msdn.microsoft.com/library/bb531253.aspx) -[Lambda Expressions (C\# Programming Guide)](https://msdn.microsoft.com/library/bb397687.aspx) +[Open XML SDK class library reference](/office/open-xml/open-xml-sdk) diff --git a/samples/spreadsheet/insert_a_chartto/cs/Program.cs b/samples/spreadsheet/insert_a_chartto/cs/Program.cs index 07ad189a..ecd759df 100644 --- a/samples/spreadsheet/insert_a_chartto/cs/Program.cs +++ b/samples/spreadsheet/insert_a_chartto/cs/Program.cs @@ -1,4 +1,4 @@ - +// using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Drawing.Charts; @@ -8,16 +8,15 @@ using System.Collections.Generic; using System.Linq; -InsertChartInSpreadsheet(args[0], args[1], args[2], new Dictionary() { { "First", 1 }, { "Second", 2 }, { "Third", 3 } }); // Given a document name, a worksheet name, a chart title, and a Dictionary collection of text keys // and corresponding integer data, creates a column chart with the text as the series and the integers as the values. -static void InsertChartInSpreadsheet(string docName, string worksheetName, string title, -Dictionary data) +static void InsertChartInSpreadsheet(string docName, string worksheetName, string title, Dictionary data) { // Open the document for editing. using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) { + // IEnumerable? sheets = document.WorkbookPart?.Workbook.Descendants().Where(s => s.Name == worksheetName); if (sheets is null || sheets.Count() == 0) @@ -48,7 +47,9 @@ static void InsertChartInSpreadsheet(string docName, string worksheetName, strin chartPart.ChartSpace.Append(new EditingLanguage() { Val = new StringValue("en-US") }); DocumentFormat.OpenXml.Drawing.Charts.Chart chart = chartPart.ChartSpace.AppendChild( new DocumentFormat.OpenXml.Drawing.Charts.Chart()); + // + // // Create a new clustered column chart. PlotArea plotArea = chart.AppendChild(new PlotArea()); Layout layout = plotArea.AppendChild(new Layout()); @@ -82,7 +83,9 @@ static void InsertChartInSpreadsheet(string docName, string worksheetName, strin i++; } + // + // barChart.Append(new AxisId() { Val = new UInt32Value(48650112u) }); barChart.Append(new AxisId() { Val = new UInt32Value(48672768u) }); @@ -129,7 +132,9 @@ static void InsertChartInSpreadsheet(string docName, string worksheetName, strin // Save the chart part. chartPart.ChartSpace.Save(); + // + // // Position the chart on the worksheet using a TwoCellAnchor object. drawingsPart.WorksheetDrawing = new WorksheetDrawing(); TwoCellAnchor twoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild(new TwoCellAnchor()); @@ -163,6 +168,10 @@ static void InsertChartInSpreadsheet(string docName, string worksheetName, strin // Save the WorksheetDrawing object. drawingsPart.WorksheetDrawing.Save(); + // } } +// + +InsertChartInSpreadsheet(args[0], args[1], args[2], new Dictionary() { { "First", 1 }, { "Second", 2 }, { "Third", 3 } }); diff --git a/samples/spreadsheet/insert_a_chartto/vb/Program.vb b/samples/spreadsheet/insert_a_chartto/vb/Program.vb index d4c9eac8..ea2e48aa 100644 --- a/samples/spreadsheet/insert_a_chartto/vb/Program.vb +++ b/samples/spreadsheet/insert_a_chartto/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Drawing Imports DocumentFormat.OpenXml.Drawing.Charts @@ -9,18 +10,19 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module MyModule Sub Main(args As String()) + InsertChartInSpreadsheet(args(0), args(1), args(2), New Dictionary(Of String, Integer) From {{"First", 1}, {"Second", 2}, {"Third", 3}}) End Sub ' Given a document name, a worksheet name, a chart title, and a Dictionary collection of text keys ' and corresponding integer data, creates a column chart with the text as the series ' and the integers as the values. - Private Sub InsertChartInSpreadsheet(ByVal docName As String, ByVal worksheetName As String, - ByVal title As String, ByVal data As Dictionary(Of String, Integer)) + Private Sub InsertChartInSpreadsheet(ByVal docName As String, ByVal worksheetName As String, ByVal title As String, ByVal data As Dictionary(Of String, Integer)) ' Open the document for editing. Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - Dim sheets As IEnumerable(Of Sheet) = - document.WorkbookPart.Workbook.Descendants(Of Sheet)() _ - .Where(Function(s) s.Name = worksheetName) + + ' + Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.Descendants(Of Sheet)() _.Where(Function(s) s.Name = worksheetName) + If sheets.Count() = 0 Then ' The specified worksheet does not exist. Return @@ -42,7 +44,9 @@ Module MyModule Dim chart As DocumentFormat.OpenXml.Drawing.Charts.Chart = chartPart.ChartSpace.AppendChild(Of DocumentFormat.OpenXml.Drawing.Charts _ .Chart)(New DocumentFormat.OpenXml.Drawing.Charts.Chart()) + ' + ' ' Create a new clustered column chart. Dim plotArea As PlotArea = chart.AppendChild(Of PlotArea)(New PlotArea()) Dim layout As Layout = plotArea.AppendChild(Of Layout)(New Layout()) @@ -76,7 +80,9 @@ Module MyModule i += 1 Next key + ' + ' barChart.Append(New AxisId() With {.Val = New UInt32Value(48650112UI)}) barChart.Append(New AxisId() With {.Val = New UInt32Value(48672768UI)}) @@ -105,7 +111,9 @@ Module MyModule ' Save the chart part. chartPart.ChartSpace.Save() + ' + ' ' Position the chart on the worksheet using a TwoCellAnchor object. drawingsPart.WorksheetDrawing = New WorksheetDrawing() Dim twoCellAnchor As TwoCellAnchor = drawingsPart.WorksheetDrawing.AppendChild(Of @@ -134,10 +142,12 @@ Module MyModule "https://schemas.openxmlformats.org/drawingml/2006/chart"})) twoCellAnchor.Append(New ClientData()) + ' ' Save the WorksheetDrawing object. drawingsPart.WorksheetDrawing.Save() End Using End Sub -End Module \ No newline at end of file +End Module +' From 5a358a39ed618d79c4a34c7d3b3f4039c4773976 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Tue, 2 Jan 2024 13:32:41 -0800 Subject: [PATCH 13/21] fix vb syntax error --- samples/spreadsheet/insert_a_chartto/vb/Program.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/spreadsheet/insert_a_chartto/vb/Program.vb b/samples/spreadsheet/insert_a_chartto/vb/Program.vb index ea2e48aa..3befa45a 100644 --- a/samples/spreadsheet/insert_a_chartto/vb/Program.vb +++ b/samples/spreadsheet/insert_a_chartto/vb/Program.vb @@ -21,7 +21,7 @@ Module MyModule Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) ' - Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.Descendants(Of Sheet)() _.Where(Function(s) s.Name = worksheetName) + Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.Descendants(Of Sheet)().Where(Function(s) s.Name = worksheetName) If sheets.Count() = 0 Then ' The specified worksheet does not exist. From d753ffbff57929bf578a4ff3e93401b2b1359b81 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Wed, 3 Jan 2024 15:04:04 -0800 Subject: [PATCH 14/21] closes #271 --- ...et-worksheet-information-from-a-package.md | 74 ++----------------- .../cs/Program.cs | 22 ++++-- .../vb/Program.vb | 23 ++++-- 3 files changed, 37 insertions(+), 82 deletions(-) diff --git a/docs/spreadsheet/how-to-get-worksheet-information-from-a-package.md b/docs/spreadsheet/how-to-get-worksheet-information-from-a-package.md index 53bef64f..6bf1f4fb 100644 --- a/docs/spreadsheet/how-to-get-worksheet-information-from-a-package.md +++ b/docs/spreadsheet/how-to-get-worksheet-information-from-a-package.md @@ -9,7 +9,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 03/22/2022 +ms.date: 01/03/2024 ms.localizationpriority: high --- @@ -17,32 +17,6 @@ ms.localizationpriority: high This topic shows how to use the classes in the Open XML SDK for Office to programmatically retrieve information from a worksheet in a Spreadsheet document. - - -## Create SpreadsheetDocument object - -In the Open XML SDK, the **[SpreadsheetDocument](/dotnet/api/documentformat.openxml.packaging.spreadsheetdocument)** class represents an Excel document package. To create an Excel document, you create an instance of the **SpreadsheetDocument** class and populate it with parts. At a minimum, the document must have a workbook part that serves as a container for the document, and at least one worksheet part. The text is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document you call one of the **[Open](/dotnet/api/documentformat.openxml.packaging.spreadsheetdocument.open)** methods. In this example, you must open the file for read access only. Therefore, you can use the **[Open(String, Boolean)](/dotnet/api/documentformat.openxml.packaging.spreadsheetdocument.open#DocumentFormat_OpenXml_Packaging_SpreadsheetDocument_Open_System_String_System_Boolean_)** method, and set the Boolean parameter to **false**. - -The following code example calls the **Open** method to open the file specified by the **filepath** for read-only access. - -### [C#](#tab/cs-0) -```csharp - // Open file as read-only. - using (SpreadsheetDocument mySpreadsheet = SpreadsheetDocument.Open(fileName, false)) -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open file as read-only. - Using mySpreadsheet As SpreadsheetDocument = SpreadsheetDocument.Open(fileName, False) -``` -*** - - -The **using** statement provides a recommended alternative to the typical .Open, .Save, .Close sequence. It ensures that the **Dispose** method (internal method used by the Open XML SDK to clean up resources) is automatically called when the closing brace is reached. The block that follows the **using** statement establishes a scope for the object that is created or named in the **using** statement, in this case **mySpreadsheet**. - [!include[Structure](../includes/spreadsheet/structure.md)] ## How the Sample Code Works @@ -50,38 +24,18 @@ The **using** statement provides a recommended alternative to the typical .Open, After you have opened the file for read-only access, you instantiate the **Sheets** class. ### [C#](#tab/cs-1) -```csharp - S sheets = mySpreadsheet.WorkbookPart.Workbook.Sheets; -``` - +[!code-csharp[](../../samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-1) -```vb - Dim sheets As S = mySpreadsheet.WorkbookPart.Workbook.Sheets -``` +[!code-vb[](../../samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb#snippet1)] *** You then you iterate through the **Sheets** collection and display **[OpenXmlElement](/dotnet/api/documentformat.openxml.openxmlelement)** and the **[OpenXmlAttribute](/dotnet/api/documentformat.openxml.openxmlattribute)** in each element. ### [C#](#tab/cs-2) -```csharp - foreach (E sheet in sheets) - { - foreach (A attr in sheet.GetAttributes()) - { - Console.WriteLine("{0}: {1}", attr.LocalName, attr.Value); - } - } -``` - +[!code-csharp[](../../samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-2) -```vb - For Each sheet In sheets - For Each attr In sheet.GetAttributes() - Console.WriteLine("{0}: {1}", attr.LocalName, attr.Value) - Next - Next -``` +[!code-vb[](../../samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb#snippet2)] *** @@ -89,27 +43,13 @@ By displaying the attribute information you get the name and ID for each workshe ## Sample code -In the following code example, you retrieve and display the attributes of the all sheets in the specified workbook contained in a **SpreadsheetDocument** document. The following code example shows how to call the **GetSheetInfo** method. - -### [C#](#tab/cs-3) -```csharp - GetSheetInfo(@"C:\Users\Public\Documents\Sheet5.xlsx"); -``` - -### [Visual Basic](#tab/vb-3) -```vb - GetSheetInfo("C:\Users\Public\Documents\Sheet5.xlsx") -``` -*** - - The following is the complete code sample in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb#snippet0)] ## See also diff --git a/samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs b/samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs index 897698af..de7cd3e1 100644 --- a/samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs +++ b/samples/spreadsheet/get_worksheetformation_from_a_package/cs/Program.cs @@ -1,29 +1,35 @@ - +// using DocumentFormat.OpenXml.Packaging; using System; -using A = DocumentFormat.OpenXml.OpenXmlAttribute; -using E = DocumentFormat.OpenXml.OpenXmlElement; -using S = DocumentFormat.OpenXml.Spreadsheet.Sheets; +using OpenXmlAttribute = DocumentFormat.OpenXml.OpenXmlAttribute; +using OpenXmlElement = DocumentFormat.OpenXml.OpenXmlElement; +using Sheets = DocumentFormat.OpenXml.Spreadsheet.Sheets; -GetSheetInfo(args[0]); static void GetSheetInfo(string fileName) { // Open file as read-only. using (SpreadsheetDocument mySpreadsheet = SpreadsheetDocument.Open(fileName, false)) { - S? sheets = mySpreadsheet.WorkbookPart?.Workbook?.Sheets; + // + Sheets? sheets = mySpreadsheet.WorkbookPart?.Workbook?.Sheets; + // if (sheets is not null) { // For each sheet, display the sheet information. - foreach (E sheet in sheets) + // + foreach (OpenXmlElement sheet in sheets) { - foreach (A attr in sheet.GetAttributes()) + foreach (OpenXmlAttribute attr in sheet.GetAttributes()) { Console.WriteLine("{0}: {1}", attr.LocalName, attr.Value); } } + // } } } +// + +GetSheetInfo(args[0]); diff --git a/samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb b/samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb index d607c016..7805a85c 100644 --- a/samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb +++ b/samples/spreadsheet/get_worksheetformation_from_a_package/vb/Program.vb @@ -1,25 +1,34 @@ +' Imports DocumentFormat.OpenXml.Packaging -Imports A = DocumentFormat.OpenXml.OpenXmlAttribute -Imports E = DocumentFormat.OpenXml.OpenXmlElement -Imports S = DocumentFormat.OpenXml.Spreadsheet.Sheets +Imports OpenXmlAttribute = DocumentFormat.OpenXml.OpenXmlAttribute +Imports OpenXmlElement = DocumentFormat.OpenXml.OpenXmlElement +Imports Sheets = DocumentFormat.OpenXml.Spreadsheet.Sheets Module MyModule Sub Main(args As String()) + Dim fileName As String = args(0) + GetSheetInfo(fileName) End Sub Public Sub GetSheetInfo(ByVal fileName As String) ' Open file as read-only. Using mySpreadsheet As SpreadsheetDocument = SpreadsheetDocument.Open(fileName, False) - Dim sheets As S = mySpreadsheet.WorkbookPart.Workbook.Sheets + + ' + Dim sheets As Sheets = mySpreadsheet.WorkbookPart.Workbook.Sheets + ' ' For each sheet, display the sheet information. - For Each sheet As E In sheets - For Each attr As A In sheet.GetAttributes() + ' + For Each sheet As OpenXmlElement In sheets + For Each attr As OpenXmlAttribute In sheet.GetAttributes() Console.WriteLine("{0}: {1}", attr.LocalName, attr.Value) Next Next + ' End Using End Sub -End Module \ No newline at end of file +End Module +' \ No newline at end of file From 82d35a2f2d1577f8d05028a243062c58789a36cb Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Wed, 3 Jan 2024 15:43:17 -0800 Subject: [PATCH 15/21] closes #270 --- ...o-get-a-column-heading-in-a-spreadsheet.md | 172 ++---------------- .../get_a_column_heading/cs/Program.cs | 18 +- .../get_a_column_heading/vb/Program.vb | 19 +- 3 files changed, 49 insertions(+), 160 deletions(-) diff --git a/docs/spreadsheet/how-to-get-a-column-heading-in-a-spreadsheet.md b/docs/spreadsheet/how-to-get-a-column-heading-in-a-spreadsheet.md index bf559c7d..64faf55c 100644 --- a/docs/spreadsheet/how-to-get-a-column-heading-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-get-a-column-heading-in-a-spreadsheet.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 01/03/2024 ms.localizationpriority: high --- # Get a column heading in a spreadsheet document @@ -20,46 +20,6 @@ This topic shows how to use the classes in the Open XML SDK for Office to retrieve a column heading in a spreadsheet document programmatically. - - -## Create a SpreadsheetDocument Object - -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an -Excel document package. To create an Excel document, you create an -instance of the **SpreadsheetDocument** class -and populate it with parts. At a minimum, the document must have a -workbook part that serves as a container for the document, and at least -one worksheet part. The text is represented in the package as XML using -**SpreadsheetML** markup. - -To create the class instance from the document you call one of the [Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) overload methods. In this example, -you need to open the file for read access only. Therefore, you can use -the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method, and set the -Boolean parameter to **false**. - -The following code example calls the Open method to **Open** the file specified by the **filepath** for read-only access. - -### [C#](#tab/cs-0) -```csharp - // Open file as read-only. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, false)) -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document as read-only. - Dim document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, False) -``` -*** - - -The **using** statement provides a recommended -alternative to the typical .Open, .Save, .Close sequence. It ensures -that the **Dispose** method (internal method -used by the Open XML SDK to clean up resources) is automatically called -when the closing brace is reached. The block that follows the **using** statement establishes a scope for the -object that is created or named in the **using** statement, in this case **mySpreadsheet**. - [!include[Structure](../includes/spreadsheet/structure.md)] ## How the Sample Code Works @@ -74,21 +34,9 @@ creating a regular expression to match the column name portion of the cell name. For more information about regular expressions, see [Regular Expression Language Elements](https://msdn.microsoft.com/library/az24scfc.aspx). ### [C#](#tab/cs-1) -```csharp - // Create a regular expression to match the column name portion of the cell name. - Regex regex = new Regex("[A-Za-z]+"); - Match match = regex.Match(cellName); - - return match.Value; -``` - +[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-1) -```vb - ' Create a regular expression to match the column name portion of the cell name. - Dim regex As Regex = New Regex("[A-Za-z]+") - Dim match As Match = regex.Match(cellName) - Return match.Value -``` +[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb#snippet1)] *** @@ -97,21 +45,9 @@ as a parameter. It parses the cell name to get the row index by creating a regular expression to match the row index portion of the cell name. ### [C#](#tab/cs-2) -```csharp - // Create a regular expression to match the row index portion the cell name. - Regex regex = new Regex(@"\d+"); - Match match = regex.Match(cellName); - - return uint.Parse(match.Value); -``` - +[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-2) -```vb - ' Create a regular expression to match the row index portion the cell name. - Dim regex As Regex = New Regex("\d+") - Dim match As Match = regex.Match(cellName) - Return UInteger.Parse(match.Value) -``` +[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb#snippet2)] *** @@ -125,44 +61,21 @@ the **GetColumnName** method. The code also gets the cells in the column and orders them by row using the **GetRowIndex** method. ### [C#](#tab/cs-3) -```csharp - // Get the column name for the specified cell. - string columnName = GetColumnName(cellName); - - // Get the cells in the specified column and order them by row. - IEnumerable cells = worksheetPart.Worksheet.Descendants(). - Where(c => string.Compare(GetColumnName(c.CellReference.Value), - columnName, true) == 0) -``` - +[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-3) -```vb - ' Get the column name for the specified cell. - Dim columnName As String = GetColumnName(cellName) - - ' Get the cells in the specified column and order them by row. - Dim cells As IEnumerable(Of Cell) = worksheetPart.Worksheet.Descendants(Of Cell)().Where(Function(c) _ - String.Compare(GetColumnName(c.CellReference.Value), columnName, True) = 0).OrderBy(Function(r) GetRowIndex(r.CellReference)) -``` +[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb#snippet3)] *** If the specified column exists, it gets the first cell in the column using the [IEnumerable(T).First](https://msdn.microsoft.com/library/bb291976.aspx) -method. The first cell contains the heading. +method. The first cell contains the heading. Otherwise the specified column does not exist and the method returns `null` / `Nothing` ### [C#](#tab/cs-4) -```csharp - // Get the first cell in the column. - Cell headCell = cells.First(); -``` - +[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs#snippet4)] ### [Visual Basic](#tab/vb-4) -```vb - ' Get the first cell in the column. - Dim headCell As Cell = cells.First() -``` +[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb#snippet4)] *** @@ -174,79 +87,24 @@ method. If the content of the cell is not in the [SharedStringTable](https://msd content of the cell. ### [C#](#tab/cs-5) -```csharp - // If the content of the first cell is stored as a shared string, get the text of the first cell - // from the SharedStringTablePart and return it. Otherwise, return the string value of the cell. - if (headCell.DataType != null && headCell.DataType.Value == - CellValues.SharedString) - { - SharedStringTablePart shareStringPart = document.WorkbookPart. - GetPartsOfType().First(); - SharedStringItem[] items = shareStringPart. - SharedStringTable.Elements().ToArray(); - return items[int.Parse(headCell.CellValue.Text)].InnerText; - } - else - { - return headCell.CellValue.Text; - } -``` - +[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs#snippet5)] ### [Visual Basic](#tab/vb-5) -```vb - ' If the content of the first cell is stored as a shared string, get the text of the first cell - ' from the SharedStringTablePart and return it. Otherwise, return the string value of the cell. - If ((Not (headCell.DataType) Is Nothing) AndAlso (headCell.DataType.Value = CellValues.SharedString)) Then - Dim shareStringPart As SharedStringTablePart = document.WorkbookPart.GetPartsOfType(Of SharedStringTablePart)().First() - Dim items() As SharedStringItem = shareStringPart.SharedStringTable.Elements(Of SharedStringItem)().ToArray() - Return items(Integer.Parse(headCell.CellValue.Text)).InnerText - Else - Return headCell.CellValue.Text - End If -``` +[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb#snippet5)] *** ## Sample Code -The following code example shows how to retrieve the column heading -using the name of the column. You can call the **GetColumnHeading** method by using a call like the -following example that uses the file "Sheet4.xlsx." - -### [C#](#tab/cs-6) -```csharp - string docName = @"C:\Users\Public\Documents\Sheet4.xlsx"; - string worksheetName = "Sheet1"; - string cellName = "B2"; - string s1 = GetColumnHeading(docName, worksheetName, cellName); -``` - -### [Visual Basic](#tab/vb-6) -```vb - Dim docName As String = "C:\Users\Public\Documents\Sheet4.xlsx" - Dim worksheetName As String = "Sheet1" - Dim cellName As String = "B2" - Dim s1 As String = GetColumnHeading(docName, worksheetName, cellName) -``` -*** - - Following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/get_a_column_heading/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/get_a_column_heading/vb/Program.vb#snippet0)] ## See also -[Open XML SDK class library reference](/office/open-xml/open-xml-sdk) - -[Language-Integrated Query (LINQ)](https://msdn.microsoft.com/library/bb397926.aspx) - -[Lambda Expressions](https://msdn.microsoft.com/library/bb531253.aspx) - -[Lambda Expressions (C\# Programming Guide)](https://msdn.microsoft.com/library/bb397687.aspx) +[Open XML SDK class library reference](/office/open-xml/open-xml-sdk) diff --git a/samples/spreadsheet/get_a_column_heading/cs/Program.cs b/samples/spreadsheet/get_a_column_heading/cs/Program.cs index b8875268..96ac093c 100644 --- a/samples/spreadsheet/get_a_column_heading/cs/Program.cs +++ b/samples/spreadsheet/get_a_column_heading/cs/Program.cs @@ -1,11 +1,11 @@ - +// using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; +using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -GetColumnHeading(args[0], args[1], args[2]); // Given a document name, a worksheet name, and a cell name, gets the column of the cell and returns // the content of the first cell in that column. @@ -32,13 +32,16 @@ WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart!.GetPartById(id); + // // Get the column name for the specified cell. string columnName = GetColumnName(cellName); // Get the cells in the specified column and order them by row. IEnumerable cells = worksheetPart.Worksheet.Descendants().Where(c => string.Compare(GetColumnName(c.CellReference?.Value), columnName, true) == 0) .OrderBy(r => GetRowIndex(r.CellReference) ?? 0); + // + // if (cells.Count() == 0) { // The specified column does not exist. @@ -47,7 +50,9 @@ // Get the first cell in the column. Cell headCell = cells.First(); + // + // // If the content of the first cell is stored as a shared string, get the text of the first cell // from the SharedStringTablePart and return it. Otherwise, return the string value of the cell. if (headCell.DataType is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index)) @@ -61,6 +66,7 @@ { return headCell.CellValue?.Text; } + // } } // Given a cell name, parses the specified cell to get the column name. @@ -70,11 +76,14 @@ static string GetColumnName(string? cellName) { return string.Empty; } + + // // Create a regular expression to match the column name portion of the cell name. Regex regex = new Regex("[A-Za-z]+"); Match match = regex.Match(cellName); return match.Value; + // } // Given a cell name, parses the specified cell to get the row index. @@ -85,9 +94,14 @@ static string GetColumnName(string? cellName) return null; } + // // Create a regular expression to match the row index portion the cell name. Regex regex = new Regex(@"\d+"); Match match = regex.Match(cellName); return uint.Parse(match.Value); + // } +// + +Console.WriteLine("Column heading: {0}", GetColumnHeading(args[0], args[1], args[2])); diff --git a/samples/spreadsheet/get_a_column_heading/vb/Program.vb b/samples/spreadsheet/get_a_column_heading/vb/Program.vb index d3ab8c36..1782b4b8 100644 --- a/samples/spreadsheet/get_a_column_heading/vb/Program.vb +++ b/samples/spreadsheet/get_a_column_heading/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports System.Text.RegularExpressions Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet @@ -6,6 +7,7 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module MyModule Sub Main(args As String()) + Console.WriteLine("The heading: {0}", GetColumnHeading(args(0), args(1), args(2))) End Sub ' Given a document name, a worksheet name, and a cell name, gets the column of the cell and returns @@ -23,13 +25,16 @@ Module MyModule Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(sheets.First.Id), WorksheetPart) + ' ' Get the column name for the specified cell. Dim columnName As String = GetColumnName(cellName) ' Get the cells in the specified column and order them by row. Dim cells As IEnumerable(Of Cell) = worksheetPart.Worksheet.Descendants(Of Cell)().Where(Function(c) _ String.Compare(GetColumnName(c.CellReference.Value), columnName, True) = 0).OrderBy(Function(r) GetRowIndex(r.CellReference)) + ' + ' If (cells.Count() = 0) Then ' The specified column does not exist. Return Nothing @@ -37,7 +42,9 @@ Module MyModule ' Get the first cell in the column. Dim headCell As Cell = cells.First() + ' + ' ' If the content of the first cell is stored as a shared string, get the text of the first cell ' from the SharedStringTablePart and return it. Otherwise, return the string value of the cell. If (((headCell.DataType) IsNot Nothing) AndAlso (headCell.DataType.Value = CellValues.SharedString)) Then @@ -47,23 +54,33 @@ Module MyModule Else Return headCell.CellValue.Text End If + ' End Using End Function ' Given a cell name, parses the specified cell to get the column name. Private Function GetColumnName(ByVal cellName As String) As String + + ' ' Create a regular expression to match the column name portion of the cell name. Dim regex As Regex = New Regex("[A-Za-z]+") Dim match As Match = regex.Match(cellName) + Return match.Value + ' End Function ' Given a cell name, parses the specified cell to get the row index. Private Function GetRowIndex(ByVal cellName As String) As UInteger + + ' ' Create a regular expression to match the row index portion the cell name. Dim regex As Regex = New Regex("\d+") Dim match As Match = regex.Match(cellName) + Return UInteger.Parse(match.Value) + ' End Function -End Module \ No newline at end of file +End Module +' From ff73ded83657621882e7dd5bbd6e413739d53d45 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Thu, 4 Jan 2024 09:38:34 -0800 Subject: [PATCH 16/21] closes #269 --- ...elete-text-from-a-cell-in-a-spreadsheet.md | 292 +----------------- .../delete_text_from_a_cell/cs/Program.cs | 13 +- .../delete_text_from_a_cell/vb/Program.vb | 11 +- 3 files changed, 29 insertions(+), 287 deletions(-) diff --git a/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md b/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md index 1eb293ca..0b7fdb04 100644 --- a/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md +++ b/docs/spreadsheet/how-to-delete-text-from-a-cell-in-a-spreadsheet.md @@ -10,7 +10,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 03/22/2022 +ms.date: 01/04/2024 ms.localizationpriority: high --- # Delete text from a cell in a spreadsheet document @@ -19,40 +19,6 @@ This topic shows how to use the classes in the Open XML SDK for Office to delete text from a cell in a spreadsheet document programmatically. -## Get a SpreadsheetDocument object - -In the Open XML SDK, the [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) class represents an Excel document package. To open and work with an Excel document, create an instance of the **SpreadsheetDocument** class from the document. After you create the instance from the document, obtain access to the main workbook part that contains the worksheets. The text in the document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document, call one of the [Open()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.open.aspx) methods. Several are provided, each with a different signature. The sample code in this topic uses the [Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx) method with a signature that requires two parameters. The first parameter takes a full path string that represents the document that you want to open. The second parameter is either **true** or **false** and represents whether you want the file to be opened for editing. Any changes that you make to the document will not be saved if this parameter is **false**. - -The following **using** statement code example calls the **Open** method. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) - { - // Other code goes here. - } -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - ' Other code goes here. - End Using -``` -*** - - -The **using** statement provides a recommended -alternative to the typical .Open, .Save, .Close sequence. It verifies -that the **Dispose** method (internal method -used by the Open XML SDK to clean up resources) is automatically called -when the closing brace is reached. The block that follows the **using** statement establishes a scope for the -object that is created or named in the **using** statement, in this case *document*. - [!include[Structure](../includes/spreadsheet/structure.md)] ## How the sample code works @@ -60,111 +26,18 @@ object that is created or named in the **using** statement, in this case *docume In the following code example, you delete text from a cell in a [SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx) document package. Then, you verify if other cells within the spreadsheet document still reference the text removed from the row, and if they do not, you remove the text from the [SharedStringTablePart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.sharedstringtablepart.aspx) object by using the [Remove](https://msdn.microsoft.com/library/office/documentformat.openxml.openxmlelement.remove.aspx) method. Then you clean up the **SharedStringTablePart** object by calling the **RemoveSharedStringItem** method. ### [C#](#tab/cs-1) -```csharp - // Given a document, a worksheet name, a column name, and a one-based row index, - // deletes the text from the cell at the specified column and row on the specified worksheet. - public static void DeleteTextFromCell(string docName, string sheetName, string colName, uint rowIndex) - { - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) - { - IEnumerable sheets = document.WorkbookPart.Workbook.GetFirstChild().Elements().Where(s => s.Name == sheetName); - if (sheets.Count() == 0) - { - // The specified worksheet does not exist. - return; - } - string relationshipId = sheets.First().Id.Value; - WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId); - - // Get the cell at the specified column and row. - Cell cell = GetSpreadsheetCell(worksheetPart.Worksheet, colName, rowIndex); - if (cell == null) - { - // The specified cell does not exist. - return; - } - cell.Remove(); - worksheetPart.Worksheet.Save(); - } - } -``` - +[!code-csharp[](../../samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-1) -```vb - ' Given a document, a worksheet name, a column name, and a one-based row index, - ' deletes the text from the cell at the specified column and row on the specified worksheet. - Public Shared Sub DeleteTextFromCell(ByVal docName As String, ByVal sheetName As String, ByVal colName As String, ByVal rowIndex As UInteger) - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.GetFirstChild(Of Sheets)().Elements(Of Sheet)().Where(Function(s) s.Name = sheetName) - If sheets.Count() = 0 Then - ' The specified worksheet does not exist. - Return - End If - Dim relationshipId As String = sheets.First().Id.Value - Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(relationshipId), WorksheetPart) - - ' Get the cell at the specified column and row. - Dim cell As Cell = GetSpreadsheetCell(worksheetPart.Worksheet, colName, rowIndex) - If cell Is Nothing Then - ' The specified cell does not exist. - Return - End If - - cell.Remove() - worksheetPart.Worksheet.Save() - - End Using - End Sub -``` +[!code-vb[](../../samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb#snippet1)] *** In the following code example, you verify that the cell specified by the column name and row index exists. If so, the code returns the cell; otherwise, it returns **null**. ### [C#](#tab/cs-2) -```csharp - // Given a worksheet, a column name, and a row index, gets the cell at the specified column and row. - private static Cell GetSpreadsheetCell(Worksheet worksheet, string columnName, uint rowIndex) - { - IEnumerable rows = worksheet.GetFirstChild().Elements().Where(r => r.RowIndex == rowIndex); - if (rows.Count() == 0) - { - // A cell does not exist at the specified row. - return null; - } - - IEnumerable cells = rows.First().Elements().Where(c => string.Compare(c.CellReference.Value, columnName + rowIndex, true) == 0); - if (cells.Count() == 0) - { - // A cell does not exist at the specified column, in the specified row. - return null; - } - - return cells.First(); - } -``` - +[!code-csharp[](../../samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-2) -```vb - ' Given a worksheet, a column name, and a row index, gets the cell at the specified column and row. - Private Shared Function GetSpreadsheetCell(ByVal worksheet As Worksheet, ByVal columnName As String, ByVal rowIndex As UInteger) As Cell - Dim rows As IEnumerable(Of Row) = worksheet.GetFirstChild(Of SheetData)().Elements(Of Row)().Where(Function(r) r.RowIndex = rowIndex) - If rows.Count() = 0 Then - ' A cell does not exist at the specified row. - Return Nothing - End If - - Dim cells As IEnumerable(Of Cell) = rows.First().Elements(Of Cell)().Where(Function(c) String.Compare(c.CellReference.Value, columnName & rowIndex, True) = 0) - If cells.Count() = 0 Then - ' A cell does not exist at the specified column, in the specified row. - Return Nothing - End If - - Return cells.First() - End Function -``` +[!code-vb[](../../samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb#snippet2)] *** @@ -185,169 +58,22 @@ through each **Worksheet** object and **Cell** object and refresh the shared str references. Finally, you save the worksheet and the [SharedStringTable](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sharedstringtable.aspx) object. ### [C#](#tab/cs-3) -```csharp - // Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer - // reference the specified SharedStringItem and removes the item. - private static void RemoveSharedStringItem(int shareStringId, SpreadsheetDocument document) - { - bool remove = true; - - foreach (var part in document.WorkbookPart.GetPartsOfType()) - { - Worksheet worksheet = part.Worksheet; - foreach (var cell in worksheet.GetFirstChild().Descendants()) - { - // Verify if other cells in the document reference the item. - if (cell.DataType != null && - cell.DataType.Value == CellValues.SharedString && - cell.CellValue.Text == shareStringId.ToString()) - { - // Other cells in the document still reference the item. Do not remove the item. - remove = false; - break; - } - } - - if (!remove) - { - break; - } - } - - // Other cells in the document do not reference the item. Remove the item. - if (remove) - { - SharedStringTablePart shareStringTablePart = document.WorkbookPart.SharedStringTablePart; - if (shareStringTablePart == null) - { - return; - } - - SharedStringItem item = shareStringTablePart.SharedStringTable.Elements().ElementAt(shareStringId); - if (item != null) - { - item.Remove(); - - // Refresh all the shared string references. - foreach (var part in document.WorkbookPart.GetPartsOfType()) - { - Worksheet worksheet = part.Worksheet; - foreach (var cell in worksheet.GetFirstChild().Descendants()) - { - if (cell.DataType != null && - cell.DataType.Value == CellValues.SharedString) - { - int itemIndex = int.Parse(cell.CellValue.Text); - if (itemIndex > shareStringId) - { - cell.CellValue.Text = (itemIndex - 1).ToString(); - } - } - } - worksheet.Save(); - } - - document.WorkbookPart.SharedStringTablePart.SharedStringTable.Save(); - } - } - } -``` - +[!code-csharp[](../../samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-3) -```vb - ' Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer - ' reference the specified SharedStringItem and removes the item. - Private Shared Sub RemoveSharedStringItem(ByVal shareStringId As Integer, ByVal document As SpreadsheetDocument) - Dim remove As Boolean = True - - For Each part In document.WorkbookPart.GetPartsOfType(Of WorksheetPart)() - Dim worksheet As Worksheet = part.Worksheet - For Each cell In worksheet.GetFirstChild(Of SheetData)().Descendants(Of Cell)() - ' Verify if other cells in the document reference the item. - If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString AndAlso cell.CellValue.Text = shareStringId.ToString() Then - ' Other cells in the document still reference the item. Do not remove the item. - remove = False - Exit For - End If - Next cell - - If Not remove Then - Exit For - End If - Next part - - ' Other cells in the document do not reference the item. Remove the item. - If remove Then - Dim shareStringTablePart As SharedStringTablePart = document.WorkbookPart.SharedStringTablePart - If shareStringTablePart Is Nothing Then - Return - End If - - Dim item As SharedStringItem = shareStringTablePart.SharedStringTable.Elements(Of SharedStringItem)().ElementAt(shareStringId) - If item IsNot Nothing Then - item.Remove() - - ' Refresh all the shared string references. - For Each part In document.WorkbookPart.GetPartsOfType(Of WorksheetPart)() - Dim worksheet As Worksheet = part.Worksheet - For Each cell In worksheet.GetFirstChild(Of SheetData)().Descendants(Of Cell)() - If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString Then - Dim itemIndex As Integer = Integer.Parse(cell.CellValue.Text) - If itemIndex > shareStringId Then - cell.CellValue.Text = (itemIndex - 1).ToString() - End If - End If - Next cell - worksheet.Save() - Next part - - document.WorkbookPart.SharedStringTablePart.SharedStringTable.Save() - End If - End If - End Sub -``` +[!code-vb[](../../samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb#snippet3)] *** ## Sample code -The following code sample is used to delete text from a specific cell in -a spreadsheet document. You can run the program by calling the method -**DeleteTextFromCell** from the file -"Sheet3.xlsx" as shown in the following example, where you specify row -2, column B, and the name of the worksheet. - -### [C#](#tab/cs-4) -```csharp - string docName = @"C:\Users\Public\Documents\Sheet3.xlsx"; - string sheetName = "Jane"; - string colName = "B"; - uint rowIndex = 2; - DeleteTextFromCell( docName, sheetName, colName, rowIndex); -``` - -### [Visual Basic](#tab/vb-4) -```vb - Dim docName As String = "C:\Users\Public\Documents\Sheet3.xlsx" - Dim sheetName As String = "Jane" - Dim colName As String = "B" - Dim rowIndex As UInteger = 2 - DeleteTextFromCell(docName, sheetName, colName, rowIndex) -``` -*** - - The following is the complete code sample in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb#snippet0)] ## See also [Open XML SDK class library reference](/office/open-xml/open-xml-sdk) -[Language-Integrated Query (LINQ)](https://msdn.microsoft.com/library/bb397926.aspx) -[Lambda Expressions](https://msdn.microsoft.com/library/bb531253.aspx) -[Lambda Expressions (C\# Programming Guide)](https://msdn.microsoft.com/library/bb397687.aspx) diff --git a/samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs b/samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs index 0fb1e4de..f1c211b2 100644 --- a/samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs +++ b/samples/spreadsheet/delete_text_from_a_cell/cs/Program.cs @@ -1,11 +1,10 @@ - +// using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System.Collections.Generic; using System.Linq; -DeleteTextFromCell(args[0], args[1], args[2], uint.Parse(args[3])); - +// // Given a document, a worksheet name, a column name, and a one-based row index, // deletes the text from the cell at the specified column and row on the specified worksheet. static void DeleteTextFromCell(string docName, string sheetName, string colName, uint rowIndex) @@ -41,7 +40,9 @@ static void DeleteTextFromCell(string docName, string sheetName, string colName, worksheetPart.Worksheet.Save(); } } +// +// // Given a worksheet, a column name, and a row index, gets the cell at the specified column and row. static Cell? GetSpreadsheetCell(Worksheet worksheet, string columnName, uint rowIndex) { @@ -62,7 +63,9 @@ static void DeleteTextFromCell(string docName, string sheetName, string colName, return cells.FirstOrDefault(); } +// +// // Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer // reference the specified SharedStringItem and removes the item. static void RemoveSharedStringItem(int shareStringId, SpreadsheetDocument document) @@ -144,3 +147,7 @@ static void RemoveSharedStringItem(int shareStringId, SpreadsheetDocument docume } } } +// +// + +DeleteTextFromCell(args[0], args[1], args[2], uint.Parse(args[3])); diff --git a/samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb b/samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb index b22a6d95..13127c57 100644 --- a/samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb +++ b/samples/spreadsheet/delete_text_from_a_cell/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet @@ -5,8 +6,10 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module MyModule Sub Main(args As String()) + DeleteTextFromCell(args(0), args(1), args(2), UInteger.Parse(args(3))) End Sub + ' ' Given a document, a worksheet name, a column name, and a one-based row index, ' deletes the text from the cell at the specified column and row on the specified sheet. Public Sub DeleteTextFromCell(ByVal docName As String, ByVal sheetName As String, ByVal colName As String, ByVal rowIndex As UInteger) @@ -35,7 +38,9 @@ Module MyModule End Using End Sub + ' + ' ' Given a worksheet, a column name, and a row index, gets the cell at the specified column and row. Private Function GetSpreadsheetCell(ByVal worksheet As Worksheet, ByVal columnName As String, ByVal rowIndex As UInteger) As Cell Dim rows As IEnumerable(Of Row) = worksheet.GetFirstChild(Of SheetData)().Elements(Of Row)().Where(Function(r) r.RowIndex = rowIndex.ToString()) @@ -52,7 +57,9 @@ Module MyModule Return cells.First End Function + ' + ' ' Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer ' reference the specified SharedStringItem and removes the item. Private Sub RemoveSharedStringItem(ByVal shareStringId As Integer, ByVal document As SpreadsheetDocument) @@ -103,4 +110,6 @@ Module MyModule End If End If End Sub -End Module \ No newline at end of file + ' +End Module +' From cc25cc51ba704f59c6bad6a0f682764147c123a7 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Thu, 4 Jan 2024 10:29:03 -0800 Subject: [PATCH 17/21] closes #268 --- ...sheet-document-by-providing-a-file-name.md | 79 ++++++------------- .../cs/Program.cs | 12 ++- .../vb/Program.vb | 14 +++- 3 files changed, 44 insertions(+), 61 deletions(-) diff --git a/docs/spreadsheet/how-to-create-a-spreadsheet-document-by-providing-a-file-name.md b/docs/spreadsheet/how-to-create-a-spreadsheet-document-by-providing-a-file-name.md index e3a4ce41..4c2ded5a 100644 --- a/docs/spreadsheet/how-to-create-a-spreadsheet-document-by-providing-a-file-name.md +++ b/docs/spreadsheet/how-to-create-a-spreadsheet-document-by-providing-a-file-name.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 01/04/2024 ms.localizationpriority: high --- # Create a spreadsheet document by providing a file name @@ -22,7 +22,7 @@ Office to programmatically create a spreadsheet document. -------------------------------------------------------------------------------- -## Getting a SpreadsheetDocument Object +## Creating a SpreadsheetDocument Object In the Open XML SDK, the **[SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx)** class represents an Excel document package. To create an Excel document, create an instance of the **SpreadsheetDocument** class and @@ -51,84 +51,49 @@ The following code example calls the **Create** method. ### [C#](#tab/cs-0) -```csharp - SpreadsheetDocument spreadsheetDocument = - SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook); -``` - +[!code-csharp[](../../samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-0) -```vb - Dim spreadsheetDocument As SpreadsheetDocument = _ - SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook) -``` +[!code-vb[](../../samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb#snippet1)] *** When you have created the Excel document package, you can add parts to -it. To add the workbook part you call the [AddWorkbookPart()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.addworkbookpart.aspx) method of the **SpreadsheetDocument** class. A workbook part must +it. To add the workbook part you call the [AddWorkbookPart()](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.addworkbookpart.aspx) method of the **SpreadsheetDocument** class. + +### [C#](#tab/cs-100) +[!code-csharp[](../../samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs#snippet2)] +### [Visual Basic](#tab/vb-100) +[!code-vb[](../../samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb#snippet2)] +*** + +A workbook part must have at least one worksheet. To add a worksheet, create a new **Sheet**. When you create a new **Sheet**, associate the **Sheet** with the [Workbook](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.aspx) by passing the **Id**, **SheetId** and **Name** parameters. Use the [GetIdOfPart(OpenXmlPart)](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.openxmlpartcontainer.getidofpart.aspx) method to get the -**Id** of the **Sheet**. Then add the new sheet to the **Sheet** collection by calling the [Append([])](https://msdn.microsoft.com/library/office/cc801361.aspx) method of the [Sheets](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheets.aspx) class. The following code example +**Id** of the **Sheet**. Then add the new sheet to the **Sheet** collection by calling the [Append([])](https://msdn.microsoft.com/library/office/cc801361.aspx) method of the [Sheets](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sheets.aspx) class. + +To create the basic document structure using the Open XML SDK, instantiate the **Workbook** class, assign it +to the [WorkbookPart](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.workbookpart.aspx) property of the main document +part, and then add instances of the [WorksheetPart](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.worksheet.worksheetpart.aspx), **Worksheet**, and **Sheet**. The following code example creates a new worksheet, associates the worksheet, and appends the worksheet to the workbook. ### [C#](#tab/cs-1) -```csharp - Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart. - GetIdOfPart(worksheetPart), SheetId = 1, Name = "mySheet" }; - sheets.Append(sheet); -``` - +[!code-csharp[](../../samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-1) -```vb - Dim sheet As New Sheet() With {.Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), .SheetId = 1, .Name = "mySheet"} - sheets.Append(sheet) -``` +[!code-vb[](../../samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb#snippet3)] *** -[!include[Structure](../includes/spreadsheet/structure.md)] - -## Generating the SpreadsheetML Markup -To create the basic document structure using the Open XML SDK, -instantiate the **Workbook** class, assign it -to the [WorkbookPart](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.workbookpart.aspx) property of the main document -part, and then add instances of the [WorksheetPart](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.worksheet.worksheetpart.aspx), **Worksheet**, and **Sheet** -classes. This is shown in the sample code and generates the required -**SpreadsheetML** markup. - - -------------------------------------------------------------------------------- ## Sample Code -The **CreateSpreadsheetWorkbook** method shown -here can be used to create a basic Excel document, a workbook with one -sheet named "mySheet". To call it in your program, you can use the -following code example that creates a file named "Sheet2.xlsx" in the -public documents folder. - -### [C#](#tab/cs-2) -```csharp - CreateSpreadsheetWorkbook(@"c:\Users\Public\Documents\Sheet2.xlsx") -``` - -### [Visual Basic](#tab/vb-2) -```vb - CreateSpreadsheetWorkbook("c:\Users\Public\Documents\Sheet2.xlsx") -``` -*** - - -Notice that the file name extension, .xlsx, matches the type of file -specified by the **SpreadsheetDocumentType.Workbook** parameter in the -call to the **Create** method. Following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb#snippet0)] -------------------------------------------------------------------------------- ## See also diff --git a/samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs b/samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs index 549c5bf5..d569d83b 100644 --- a/samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs +++ b/samples/spreadsheet/create_by_providing_a_file_name/cs/Program.cs @@ -1,20 +1,24 @@ +// using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; -CreateSpreadsheetWorkbook(args[0]); - static void CreateSpreadsheetWorkbook(string filepath) { + // // Create a spreadsheet document by supplying the filepath. // By default, AutoSave = true, Editable = true, and Type = xlsx. 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.Worksheet = new Worksheet(new SheetData()); @@ -25,9 +29,13 @@ static void CreateSpreadsheetWorkbook(string filepath) // 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); + // workbookPart.Workbook.Save(); // Dispose the document. spreadsheetDocument.Dispose(); } +// + +CreateSpreadsheetWorkbook(args[0]); diff --git a/samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb b/samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb index c4185262..993986e8 100644 --- a/samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb +++ b/samples/spreadsheet/create_by_providing_a_file_name/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Spreadsheet @@ -6,18 +7,24 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module MyModule Sub Main(args As String()) + CreateSpreadsheetWorkbook(args(0)) End Sub Public Sub CreateSpreadsheetWorkbook(ByVal filepath As String) + + ' ' Create a spreadsheet document by supplying the filepath. ' By default, AutoSave = true, Editable = true, and Type = xlsx. - Dim spreadsheetDocument As SpreadsheetDocument = - SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook) + Dim 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()) @@ -32,10 +39,13 @@ Module MyModule sheet.Name = "mySheet" sheets.Append(sheet) + ' workbookpart.Workbook.Save() ' Dispose the document. spreadsheetDocument.Dispose() End Sub + ' + End Module \ No newline at end of file From bdd3a74e1362c62fbba01d0be79bc6d05d28e5e8 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Thu, 4 Jan 2024 12:24:55 -0800 Subject: [PATCH 18/21] closes #267 --- ...ange-of-cells-in-a-spreadsheet-document.md | 424 +----------------- .../cs/Program.cs | 23 +- .../vb/Program.vb | 23 +- 3 files changed, 59 insertions(+), 411 deletions(-) diff --git a/docs/spreadsheet/how-to-calculate-the-sum-of-a-range-of-cells-in-a-spreadsheet-document.md b/docs/spreadsheet/how-to-calculate-the-sum-of-a-range-of-cells-in-a-spreadsheet-document.md index 03003bfa..692a8118 100644 --- a/docs/spreadsheet/how-to-calculate-the-sum-of-a-range-of-cells-in-a-spreadsheet-document.md +++ b/docs/spreadsheet/how-to-calculate-the-sum-of-a-range-of-cells-in-a-spreadsheet-document.md @@ -9,7 +9,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 04/04/2022 +ms.date: 01/04/2024 ms.localizationpriority: high --- @@ -17,37 +17,6 @@ ms.localizationpriority: high This topic shows how to use the classes in the Open XML SDK for Office to calculate the sum of a contiguous range of cells in a spreadsheet document programmatically. - - -## Get a SpreadsheetDocument Object - -In the Open XML SDK, the **[SpreadsheetDocument](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.spreadsheetdocument.aspx)** class represents an Excel document package. To open and work with an Excel document, you create an instance of the **SpreadsheetDocument** class from the document. After you create the instance from the document, you can then obtain access to the main **[Workbook](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.workbook.aspx)** part that contains the worksheets. The text in the document is represented in the package as XML using **SpreadsheetML** markup. - -To create the class instance from the document that you call one of the **Open** methods. Several are provided, each with a different signature. The sample code in this topic uses the **[Open(String, Boolean)](https://msdn.microsoft.com/library/office/cc562356.aspx)** method with a signature that requires two parameters. The first parameter takes a full path string that represents the document that you want to open. The second parameter is either **true** or **false** and represents whether you want the file to be opened for editing. Any changes that you make to the document will not be saved if this parameter is **false**. - -The code that calls the **Open** method is shown in the following **using** statement. - -### [C#](#tab/cs-0) -```csharp - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) - { - // Other code goes here. - } -``` - -### [Visual Basic](#tab/vb-0) -```vb - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - ' Other code goes here. - End Using -``` -*** - - -The **using** statement provides a recommended alternative to the typical .Open, .Save, .Close sequence. It ensures that the **Dispose** method (internal method used by the Open XML SDK to clean up resources) is automatically called when the closing brace is reached. The block that follows the **using** statement establishes a scope for the object that is created or named in the **using** statement, in this case **document**. - [!include[Structure](../includes/spreadsheet/structure.md)] ## How the Sample Code Works @@ -59,430 +28,69 @@ The code then opens the file for editing as a **SpreadsheetDocument** document p For each **Row** object within the contiguous range, the code iterates through each **Cell** object and determines if the column of the cell is within the contiguous range by calling the **CompareColumn** method. If the cell is within the contiguous range, the code adds the value of the cell to the sum. Then it gets the **SharedStringTablePart** object if it exists. If it does not exist, it creates one using the **[AddNewPart](https://msdn.microsoft.com/library/office/documentformat.openxml.packaging.openxmlpartcontainer.addnewpart.aspx)** method. It inserts the result into the **SharedStringTablePart** object by calling the **InsertSharedStringItem** method. -The code inserts a new cell for the result into the worksheet by calling the **InsertCellInWorksheet** method and set the value of the cell. For more information, see [how to insert a cell in a spreadsheet](how-to-insert-text-into-a-cell-in-a-spreadsheet.md#how-the-sample-code-works), and then saves the worksheet. +The code inserts a new cell for the result into the worksheet by calling the **InsertCellInWorksheet** method and set the value of the cell. For more information, see [how to insert a cell in a spreadsheet](how-to-insert-text-into-a-cell-in-a-spreadsheet.md#how-the-sample-code-works), and then save the worksheet. ### [C#](#tab/cs-1) -```csharp - // Given a document name, a worksheet name, the name of the first cell in the contiguous range, - // the name of the last cell in the contiguous range, and the name of the results cell, - // calculates the sum of the cells in the contiguous range and inserts the result into the results cell. - // Note: All cells in the contiguous range must contain numbers. - private static void CalculateSumOfCellRange(string docName, string worksheetName, string firstCellName, string lastCellName, string resultCell) - { - // Open the document for editing. - using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true)) - { - IEnumerable sheets = document.WorkbookPart.Workbook.Descendants().Where(s => s.Name == worksheetName); - if (sheets.Count() == 0) - { - // The specified worksheet does not exist. - return; - } - - WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id); - Worksheet worksheet = worksheetPart.Worksheet; - - // Get the row number and column name for the first and last cells in the range. - uint firstRowNum = GetRowIndex(firstCellName); - uint lastRowNum = GetRowIndex(lastCellName); - string firstColumn = GetColumnName(firstCellName); - string lastColumn = GetColumnName(lastCellName); - - double sum = 0; - - // Iterate through the cells within the range and add their values to the sum. - foreach (Row row in worksheet.Descendants().Where(r => r.RowIndex.Value >= firstRowNum && r.RowIndex.Value <= lastRowNum)) - { - foreach (Cell cell in row) - { - string columnName = GetColumnName(cell.CellReference.Value); - if (CompareColumn(columnName, firstColumn) >= 0 && CompareColumn(columnName, lastColumn) <= 0) - { - sum += double.Parse(cell.CellValue.Text); - } - } - } - - // Get the SharedStringTablePart and add the result to it. - // If the SharedStringPart does not exist, create a new one. - SharedStringTablePart shareStringPart; - if (document.WorkbookPart.GetPartsOfType().Count() > 0) - { - shareStringPart = document.WorkbookPart.GetPartsOfType().First(); - } - else - { - shareStringPart = document.WorkbookPart.AddNewPart(); - } - - // Insert the result into the SharedStringTablePart. - int index = InsertSharedStringItem("Result:" + sum, shareStringPart); - - Cell result = InsertCellInWorksheet(GetColumnName(resultCell), GetRowIndex(resultCell), worksheetPart); - - // Set the value of the cell. - result.CellValue = new CellValue(index.ToString()); - result.DataType = new EnumValue(CellValues.SharedString); - - worksheetPart.Worksheet.Save(); - } - } -``` - +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet1)] ### [Visual Basic](#tab/vb-1) -```vb - ' Given a document name, a worksheet name, the name of the first cell in the contiguous range, - ' the name of the last cell in the contiguous range, and the name of the results cell, - ' calculates the sum of the cells in the contiguous range and inserts the result into the results cell. - ' Note: All cells in the contiguous range must contain numbers. - Private Shared Sub CalculateSumOfCellRange(ByVal docName As String, ByVal worksheetName As String, ByVal firstCellName As String, ByVal lastCellName As String, ByVal resultCell As String) - ' Open the document for editing. - Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True) - Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.Descendants(Of Sheet)().Where(Function(s) s.Name = worksheetName) - If sheets.Count() = 0 Then - ' The specified worksheet does not exist. - Return - End If - - Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(sheets.First().Id), WorksheetPart) - Dim worksheet As Worksheet = worksheetPart.Worksheet - - ' Get the row number and column name for the first and last cells in the range. - Dim firstRowNum As UInteger = GetRowIndex(firstCellName) - Dim lastRowNum As UInteger = GetRowIndex(lastCellName) - Dim firstColumn As String = GetColumnName(firstCellName) - Dim lastColumn As String = GetColumnName(lastCellName) - - Dim sum As Double = 0 - - ' Iterate through the cells within the range and add their values to the sum. - For Each row As Row In worksheet.Descendants(Of Row)().Where(Function(r) r.RowIndex.Value >= firstRowNum AndAlso r.RowIndex.Value <= lastRowNum) - For Each cell As Cell In row - Dim columnName As String = GetColumnName(cell.CellReference.Value) - If CompareColumn(columnName, firstColumn) >= 0 AndAlso CompareColumn(columnName, lastColumn) <= 0 Then - sum += Double.Parse(cell.CellValue.Text) - End If - Next cell - Next row - - ' Get the SharedStringTablePart and add the result to it. - ' If the SharedStringPart does not exist, create a new one. - Dim shareStringPart As SharedStringTablePart - If document.WorkbookPart.GetPartsOfType(Of SharedStringTablePart)().Count() > 0 Then - shareStringPart = document.WorkbookPart.GetPartsOfType(Of SharedStringTablePart)().First() - Else - shareStringPart = document.WorkbookPart.AddNewPart(Of SharedStringTablePart)() - End If - - ' Insert the result into the SharedStringTablePart. - Dim index As Integer = InsertSharedStringItem("Result:" & sum, shareStringPart) - - Dim result As Cell = InsertCellInWorksheet(GetColumnName(resultCell), GetRowIndex(resultCell), worksheetPart) - - ' Set the value of the cell. - result.CellValue = New CellValue(index.ToString()) - result.DataType = New EnumValue(Of CellValues)(CellValues.SharedString) - - worksheetPart.Worksheet.Save() - End Using - End Sub -``` +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet1)] *** To get the row index the code passes a parameter that represents the name of the cell, and creates a new regular expression to match the row index portion of the cell name. For more information about regular expressions, see [Regular Expression Language Elements](/dotnet/standard/base-types/regular-expression-language-quick-reference). It gets the row index by calling the **[Regex.Match](https://msdn2.microsoft.com/library/3zy662f6)** method, and then returns the row index. ### [C#](#tab/cs-2) -```csharp - // Given a cell name, parses the specified cell to get the row index. - private static uint GetRowIndex(string cellName) - { - // Create a regular expression to match the row index portion the cell name. - Regex regex = new Regex(@"\d+"); - Match match = regex.Match(cellName); - - return uint.Parse(match.Value); - } -``` - +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet2)] ### [Visual Basic](#tab/vb-2) -```vb - ' Given a cell name, parses the specified cell to get the row index. - Private Shared Function GetRowIndex(ByVal cellName As String) As UInteger - ' Create a regular expression to match the row index portion the cell name. - Dim regex As New Regex("\d+") - Dim match As Match = regex.Match(cellName) - - Return UInteger.Parse(match.Value) - End Function -``` +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet2)] *** The code then gets the column name by passing a parameter that represents the name of the cell, and creates a new regular expression to match the column name portion of the cell name. This regular expression matches any combination of uppercase or lowercase letters. It gets the column name by calling the **[Regex.Match](/dotnet/api/system.text.regularexpressions.regex.match)** method, and then returns the column name. ### [C#](#tab/cs-3) -```csharp - // Given a cell name, parses the specified cell to get the column name. - private static string GetColumnName(string cellName) - { - // Create a regular expression to match the column name portion of the cell name. - Regex regex = new Regex("[A-Za-z]+"); - Match match = regex.Match(cellName); - - return match.Value; - } -``` - +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet3)] ### [Visual Basic](#tab/vb-3) -```vb - ' Given a cell name, parses the specified cell to get the column name. - Private Shared Function GetColumnName(ByVal cellName As String) As String - ' Create a regular expression to match the column name portion of the cell name. - Dim regex As New Regex("[A-Za-z]+") - Dim match As Match = regex.Match(cellName) - - Return match.Value - End Function -``` +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet3)] *** To compare two columns the code passes in two parameters that represent the columns to compare. If the first column is longer than the second column, it returns 1. If the second column is longer than the first column, it returns -1. Otherwise, it compares the values of the columns using the **[Compare](/dotnet/api/system.string.compare)** and returns the result. ### [C#](#tab/cs-4) -```csharp - // Given two columns, compares the columns. - private static int CompareColumn(string column1, string column2) - { - if (column1.Length > column2.Length) - { - return 1; - } - else if (column1.Length < column2.Length) - { - return -1; - } - else - { - return string.Compare(column1, column2, true); - } - } -``` - +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet4)] ### [Visual Basic](#tab/vb-4) -```vb - ' Given two columns, compares the columns. - Private Shared Function CompareColumn(ByVal column1 As String, ByVal column2 As String) As Integer - If column1.Length > column2.Length Then - Return 1 - ElseIf column1.Length < column2.Length Then - Return -1 - Else - Return String.Compare(column1, column2, True) - End If - End Function -``` +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet4)] *** To insert a **SharedStringItem**, the code passes in a parameter that represents the text to insert into the cell and a parameter that represents the **SharedStringTablePart** object for the spreadsheet. If the **ShareStringTablePart** object does not contain a **[SharedStringTable](https://msdn.microsoft.com/library/office/documentformat.openxml.spreadsheet.sharedstringtable.aspx)** object then it creates one. If the text already exists in the **ShareStringTable** object, then it returns the index for the **[SharedStringItem](/dotnet/api/documentformat.openxml.spreadsheet.sharedstringitem)** object that represents the text. If the text does not exist, create a new **SharedStringItem** object that represents the text. It then returns the index for the **SharedStringItem** object that represents the text. ### [C#](#tab/cs-5) -```csharp - // Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text - // and inserts it into the SharedStringTablePart. If the item already exists, returns its index. - private static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart) - { - // If the part does not contain a SharedStringTable, create it. - if (shareStringPart.SharedStringTable == null) - { - shareStringPart.SharedStringTable = new SharedStringTable(); - } - - int i = 0; - foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements()) - { - if (item.InnerText == text) - { - // The text already exists in the part. Return its index. - return i; - } - - i++; - } - - // The text does not exist in the part. Create the SharedStringItem. - shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text))); - shareStringPart.SharedStringTable.Save(); - - return i; - } -``` - +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet5)] ### [Visual Basic](#tab/vb-5) -```vb - ' Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text - ' and inserts it into the SharedStringTablePart. If the item already exists, returns its index. - Private Shared Function InsertSharedStringItem(ByVal text As String, ByVal shareStringPart As SharedStringTablePart) As Integer - ' If the part does not contain a SharedStringTable, create it. - If shareStringPart.SharedStringTable Is Nothing Then - shareStringPart.SharedStringTable = New SharedStringTable() - End If - - Dim i As Integer = 0 - For Each item As SharedStringItem In shareStringPart.SharedStringTable.Elements(Of SharedStringItem)() - If item.InnerText = text Then - ' The text already exists in the part. Return its index. - Return i - End If - - i += 1 - Next item - - ' The text does not exist in the part. Create the SharedStringItem. - shareStringPart.SharedStringTable.AppendChild(New SharedStringItem(New DocumentFormat.OpenXml.Spreadsheet.Text(text))) - shareStringPart.SharedStringTable.Save() - - Return i - End Function -``` +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet5)] *** The final step is to insert a cell into the worksheet. The code does that by passing in parameters that represent the name of the column and the number of the row of the cell, and a parameter that represents the worksheet that contains the cell. If the specified row does not exist, it creates the row and append it to the worksheet. If the specified column exists, it finds the cell that matches the row in that column and returns the cell. If the specified column does not exist, it creates the column and inserts it into the worksheet. It then determines where to insert the new cell in the column by iterating through the row elements to find the cell that comes directly after the specified row, in sequential order. It saves this row in the **refCell** variable. It inserts the new cell before the cell referenced by **refCell** using the **[InsertBefore](/dotnet/api/documentformat.openxml.openxmlcompositeelement.insertbefore)** method. It then returns the new **Cell** object. ### [C#](#tab/cs-6) -```csharp - // Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. - // If the cell already exists, returns it. - private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart) - { - Worksheet worksheet = worksheetPart.Worksheet; - SheetData sheetData = worksheet.GetFirstChild(); - string cellReference = columnName + rowIndex; - - // If the worksheet does not contain a row with the specified row index, insert one. - Row row; - if (sheetData.Elements().Where(r => r.RowIndex == rowIndex).Count() != 0) - { - row = sheetData.Elements().Where(r => r.RowIndex == rowIndex).First(); - } - else - { - row = new Row() { RowIndex = rowIndex }; - sheetData.Append(row); - } - - // If there is not a cell with the specified column name, insert one. - if (row.Elements().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0) - { - return row.Elements().Where(c => c.CellReference.Value == cellReference).First(); - } - else - { - // Cells must be in sequential order according to CellReference. Determine where to insert the new cell. - Cell refCell = null; - foreach (Cell cell in row.Elements()) - { - if (string.Compare(cell.CellReference.Value, cellReference, true) > 0) - { - refCell = cell; - break; - } - } - - Cell newCell = new Cell() { CellReference = cellReference }; - row.InsertBefore(newCell, refCell); - - worksheet.Save(); - return newCell; - } - } -``` - +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet6)] ### [Visual Basic](#tab/vb-6) -```vb - ' Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. - ' If the cell already exists, returns it. - Private Shared Function InsertCellInWorksheet(ByVal columnName As String, ByVal rowIndex As UInteger, ByVal worksheetPart As WorksheetPart) As Cell - Dim worksheet As Worksheet = worksheetPart.Worksheet - Dim sheetData As SheetData = worksheet.GetFirstChild(Of SheetData)() - Dim cellReference As String = columnName & rowIndex - - ' If the worksheet does not contain a row with the specified row index, insert one. - Dim row As Row - If sheetData.Elements(Of Row)().Where(Function(r) r.RowIndex = rowIndex).Count() <> 0 Then - row = sheetData.Elements(Of Row)().Where(Function(r) r.RowIndex = rowIndex).First() - Else - row = New Row() With {.RowIndex = rowIndex} - sheetData.Append(row) - End If - - ' If there is not a cell with the specified column name, insert one. - If row.Elements(Of Cell)().Where(Function(c) c.CellReference.Value = columnName & rowIndex).Count() > 0 Then - Return row.Elements(Of Cell)().Where(Function(c) c.CellReference.Value = cellReference).First() - Else - ' Cells must be in sequential order according to CellReference. Determine where to insert the new cell. - Dim refCell As Cell = Nothing - For Each cell As Cell In row.Elements(Of Cell)() - If String.Compare(cell.CellReference.Value, cellReference, True) > 0 Then - refCell = cell - Exit For - End If - Next cell - - Dim newCell As New Cell() With {.CellReference = cellReference} - row.InsertBefore(newCell, refCell) - - worksheet.Save() - Return newCell - End If - End Function -``` +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet6)] *** ## Sample Code - -The following code sample calculates the sum of a contiguous range of cells in a spreadsheet document. The result is inserted into the **SharedStringTablePart** object and into the specified result cell. You can call the method CalculateSumOfCellRange by using the following example. - -### [C#](#tab/cs-7) -```csharp - string docName = @"C:\Users\Public\Documents\Sheet1.xlsx"; - string worksheetName = "John"; - string firstCellName = "A1"; - string lastCellName = "A3"; - string resultCell = "A4"; - CalculateSumOfCellRange(docName, worksheetName, firstCellName, lastCellName, resultCell); -``` - -### [Visual Basic](#tab/vb-7) -```vb - Dim docName As String = "C:\Users\Public\Documents\Sheet1.xlsx" - Dim worksheetName As String = "John" - Dim firstCellName As String = "A1" - Dim lastCellName As String = "A3" - Dim resultCell As String = "A4" - CalculateSumOfCellRange(docName, worksheetName, firstCellName, lastCellName, resultCell) -``` -*** - - -After running the program, you can inspect the file named "Sheet1.xlsx" to see the sum of the column in the worksheet named "John" in the specified cell. - The following is the complete sample code in both C\# and Visual Basic. ### [C#](#tab/cs) -[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs)] +[!code-csharp[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs#snippet0)] ### [Visual Basic](#tab/vb) -[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb)] +[!code-vb[](../../samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb#snippet0)] ## See also - [Open XML SDK class library reference](/office/open-xml/open-xml-sdk) -- [Language-Integrated Query (LINQ) (C#)](/dotnet/csharp/programming-guide/concepts/linq/) -- [Language-Integrated Query (LINQ) (Visual Basic)](/dotnet/visual-basic/programming-guide/concepts/linq/) -- [Lambda Expressions (C#)](/dotnet/csharp/language-reference/operators/lambda-expressions) -- [Lambda Expressions (Visual Basic)](/dotnet/visual-basic/programming-guide/language-features/procedures/lambda-expressions) diff --git a/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs b/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs index 0c707852..da63024e 100644 --- a/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs +++ b/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/cs/Program.cs @@ -1,3 +1,4 @@ +// using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; @@ -7,8 +8,7 @@ using System.Text.RegularExpressions; -CalculateSumOfCellRange(args[0], args[1], args[2], args[3], args[4]); - +// static void CalculateSumOfCellRange(string docName, string worksheetName, string firstCellName, string lastCellName, string resultCell) { // Open the document for editing. @@ -73,7 +73,9 @@ static void CalculateSumOfCellRange(string docName, string worksheetName, string worksheetPart.Worksheet.Save(); } } +// +// // Given a cell name, parses the specified cell to get the row index. static uint GetRowIndex(string cellName) { @@ -83,6 +85,9 @@ static uint GetRowIndex(string cellName) return uint.Parse(match.Value); } +// + +// // Given a cell name, parses the specified cell to get the column name. static string GetColumnName(string cellName) { @@ -92,6 +97,9 @@ static string GetColumnName(string cellName) return match.Value; } +// + +// // Given two columns, compares the columns. static int CompareColumn(string column1, string column2) { @@ -108,6 +116,9 @@ static int CompareColumn(string column1, string column2) return string.Compare(column1, column2, true); } } +// + +// // Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text // and inserts it into the SharedStringTablePart. If the item already exists, returns its index. static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart) @@ -136,6 +147,9 @@ static int InsertSharedStringItem(string text, SharedStringTablePart shareString return i; } +// + +// // Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. // If the cell already exists, returns it. static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart) @@ -182,3 +196,8 @@ static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPar return newCell; } } +// + +// + +CalculateSumOfCellRange(args[0], args[1], args[2], args[3], args[4]); diff --git a/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb b/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb index c6cf8188..5a34187a 100644 --- a/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb +++ b/samples/spreadsheet/calculate_the_sum_of_a_range_of_cells/vb/Program.vb @@ -1,3 +1,4 @@ +' Imports System.Text.RegularExpressions Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Packaging @@ -7,8 +8,10 @@ Imports DocumentFormat.OpenXml.Spreadsheet Module MyModule Sub Main(args As String()) + CalculateSumOfCellRange(args(0), args(1), args(2), args(3), args(4)) End Sub + ' ' Given a document name, a worksheet name, the name of the first cell in the contiguous range, ' the name of the last cell in the contiguous range, and the name of the results cell, ' calculates the sum of the cells in the contiguous range and inserts the result into the results cell. @@ -68,6 +71,9 @@ Module MyModule worksheetPart.Worksheet.Save() End Using End Sub + ' + + ' ' Given a cell name, parses the specified cell to get the row index. Private Function GetRowIndex(ByVal cellName As String) As UInteger ' Create a regular expression to match the row index portion the cell name. @@ -75,6 +81,9 @@ Module MyModule Dim match As Match = regex.Match(cellName) Return UInteger.Parse(match.Value) End Function + ' + + ' ' Given a cell name, parses the specified cell to get the column name. Private Function GetColumnName(ByVal cellName As String) As String ' Create a regular expression to match the column name portion of the cell name. @@ -82,6 +91,9 @@ Module MyModule Dim match As Match = regex.Match(cellName) Return match.Value End Function + ' + + ' ' Given two columns, compares the columns. Private Function CompareColumn(ByVal column1 As String, ByVal column2 As String) As Integer If (column1.Length > column2.Length) Then @@ -92,6 +104,9 @@ Module MyModule Return String.Compare(column1, column2, True) End If End Function + ' + + ' ' Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text ' and inserts it into the SharedStringTablePart. If the item already exists, returns its index. Private Function InsertSharedStringItem(ByVal text As String, ByVal shareStringPart As SharedStringTablePart) As Integer @@ -115,6 +130,9 @@ Module MyModule Return i End Function + ' + + ' ' Given a column name, a row index, and a WorksheetPart, inserts a cell into the worksheet. ' If the cell already exists, return it. Private Function InsertCellInWorksheet(ByVal columnName As String, ByVal rowIndex As UInteger, ByVal worksheetPart As WorksheetPart) As Cell @@ -154,4 +172,7 @@ Module MyModule Return newCell End If End Function -End Module \ No newline at end of file + ' + +End Module +' \ No newline at end of file From 56fad64dff251a65bed5c92b61f88a3f1c0ab3f9 Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Wed, 10 Jan 2024 11:45:21 -0800 Subject: [PATCH 19/21] closes #297 --- docs/includes/spreadsheet/structure.md | 2 +- docs/presentation/structure-of-a-presentationml-document.md | 2 +- ...how-to-open-a-spreadsheet-document-for-read-only-access.md | 2 +- .../how-to-open-a-spreadsheet-document-from-a-stream.md | 2 +- docs/spreadsheet/structure-of-a-spreadsheetml-document.md | 2 +- docs/spreadsheet/working-with-formulas.md | 2 +- docs/spreadsheet/working-with-tables.md | 4 ++-- docs/spreadsheet/working-with-the-shared-string-table.md | 2 +- samples/spreadsheet/add_custom_ui/vb/Program.vb | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/includes/spreadsheet/structure.md b/docs/includes/spreadsheet/structure.md index 3cdbdc31..3866d007 100644 --- a/docs/includes/spreadsheet/structure.md +++ b/docs/includes/spreadsheet/structure.md @@ -22,7 +22,7 @@ code example. ```xml - + diff --git a/docs/presentation/structure-of-a-presentationml-document.md b/docs/presentation/structure-of-a-presentationml-document.md index daadd7fc..676c0160 100644 --- a/docs/presentation/structure-of-a-presentationml-document.md +++ b/docs/presentation/structure-of-a-presentationml-document.md @@ -650,7 +650,7 @@ The following XML code is the PresentationML that represents the relationship pa ```xml - + diff --git a/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md b/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md index fca64e09..66645348 100644 --- a/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md +++ b/docs/spreadsheet/how-to-open-a-spreadsheet-document-for-read-only-access.md @@ -142,7 +142,7 @@ Sheet1.xml file and is as follows. ```xml - + diff --git a/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md b/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md index c06478e6..19b1c0e2 100644 --- a/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md +++ b/docs/spreadsheet/how-to-open-a-spreadsheet-document-from-a-stream.md @@ -65,7 +65,7 @@ code example. ```xml - + diff --git a/docs/spreadsheet/structure-of-a-spreadsheetml-document.md b/docs/spreadsheet/structure-of-a-spreadsheetml-document.md index 756f3f38..30a97e7a 100644 --- a/docs/spreadsheet/structure-of-a-spreadsheetml-document.md +++ b/docs/spreadsheet/structure-of-a-spreadsheetml-document.md @@ -126,7 +126,7 @@ when you run the Open XML SDK to create a minimum workbook. ```xml - + ``` diff --git a/docs/spreadsheet/working-with-formulas.md b/docs/spreadsheet/working-with-formulas.md index 13409d59..4e4ee6d3 100644 --- a/docs/spreadsheet/working-with-formulas.md +++ b/docs/spreadsheet/working-with-formulas.md @@ -116,7 +116,7 @@ and is contained in the "sheet1.xml" file. ```xml - + diff --git a/docs/spreadsheet/working-with-tables.md b/docs/spreadsheet/working-with-tables.md index 89fbc942..0eae2c08 100644 --- a/docs/spreadsheet/working-with-tables.md +++ b/docs/spreadsheet/working-with-tables.md @@ -156,7 +156,7 @@ displayed in the table, and contains the **tablePart** element that references t ```xml - + @@ -226,7 +226,7 @@ table looks, and defines any autofilters for the table. ```xml - +
diff --git a/docs/spreadsheet/working-with-the-shared-string-table.md b/docs/spreadsheet/working-with-the-shared-string-table.md index a022969b..4a6d71a3 100644 --- a/docs/spreadsheet/working-with-the-shared-string-table.md +++ b/docs/spreadsheet/working-with-the-shared-string-table.md @@ -115,7 +115,7 @@ ISO/IEC 29500 specification. ```xml - + Cell A1 diff --git a/samples/spreadsheet/add_custom_ui/vb/Program.vb b/samples/spreadsheet/add_custom_ui/vb/Program.vb index a756e9a3..a5cd63e7 100644 --- a/samples/spreadsheet/add_custom_ui/vb/Program.vb +++ b/samples/spreadsheet/add_custom_ui/vb/Program.vb @@ -12,7 +12,7 @@ Module MyModule ' Add a custom UI part to the document. ' Use this sample XML to test: - ' + ' ' ' ' From 8a8a95eb0b2b348e5926e6ef06bf0accfe9ba62b Mon Sep 17 00:00:00 2001 From: Michael Bowen Date: Wed, 10 Jan 2024 12:45:30 -0800 Subject: [PATCH 20/21] closes #266 --- ...add-custom-ui-to-a-spreadsheet-document.md | 118 ++++-------------- .../spreadsheet/add_custom_ui/cs/Program.cs | 56 +++++---- .../spreadsheet/add_custom_ui/vb/Program.vb | 59 ++++----- 3 files changed, 83 insertions(+), 150 deletions(-) diff --git a/docs/spreadsheet/how-to-add-custom-ui-to-a-spreadsheet-document.md b/docs/spreadsheet/how-to-add-custom-ui-to-a-spreadsheet-document.md index e6f6af76..ec91a417 100644 --- a/docs/spreadsheet/how-to-add-custom-ui-to-a-spreadsheet-document.md +++ b/docs/spreadsheet/how-to-add-custom-ui-to-a-spreadsheet-document.md @@ -11,7 +11,7 @@ ms.suite: office ms.author: o365devx author: o365devx ms.topic: conceptual -ms.date: 11/01/2017 +ms.date: 01/10/2024 ms.localizationpriority: high --- @@ -24,22 +24,15 @@ this task. ## Creating Custom UI -Before using the Open XML SDK to create a ribbon customization in an Excel workbook, you must first create the customization content. Describing the XML required to create a ribbon customization is beyond the scope of this topic. In addition, you will find it far easier to use the Ribbon Designer in Visual Studio 2010 to create the customization for you. For more information about customizing the ribbon by using the Visual Studio Ribbon Designer, see [Ribbon Designer](https://msdn.microsoft.com/library/26617206-f4da-416f-a18a-d817b2d4872d(Office.15).aspx) and [Walkthrough: Creating a Custom Tab by Using the Ribbon Designer](https://msdn.microsoft.com/library/312865e6-950f-46ab-88de-fe7eb8036bfe(Office.15).aspx). -For the purposes of this demonstration, you will need an XML file that contains a customization, and the following code provides a simple customization (or you can create your own by using the Visual Studio Ribbon Designer, and then right-click to export the customization to an XML file). Copy the following content into a text file that is named AddCustomUI.xml for use as part of this example. This XML content describes a ribbon customization that includes a button labeled "Click Me!" in a group named Group1 on the **Add-Ins** tab in Excel. When you click the button, it attempts to run a macro named **SampleMacro** in the host workbook. - -```xml - - - - - -