ストリームからスプレッドシート ドキュメントを開く
適用対象: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010
この記事の内容
ストリームから開く場合
SpreadsheetDocument オブジェクトを取得する
SpreadsheetML マークアップを生成してワークシートを追加する
サンプル コード
このトピックでは、Open XML SDK 2.0 for Microsoft Office のクラスを使用して、プログラムによって、ストリームからスプレッドシート ドキュメントを開く方法について説明します。
このトピックのコードをコンパイルするには、次のアセンブリ ディレクティブが必要です。
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Linq;
Imports System.IO
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports System.Linq
ストリームから開く場合
ストリーム入出力を使用してドキュメントを操作する Microsoft SharePoint Foundation 2010 などのアプリケーションがあり、Open XML SDK 2.0 を使用していずれかのドキュメントを操作する必要がある場合、その操作は簡単に実行できるようになっています。ドキュメントが存在していて、Open XML SDK 2.0 を使用して開くことができる場合は、特に簡単です。しかし、ドキュメントが、開いているストリームであり、コードの中で SDK を使用して操作する必要がある場合はどうすればよいでしょうか。このトピックではそのようなシナリオについて説明します。サンプル コードで紹介しているサンプル メソッドでは、開いているストリームをパラメーターとして受け取り、Open XML SDK 2.0 を使用して、ストリームの背後でドキュメントにテキストを追加します。
SpreadsheetDocument オブジェクトを取得する
Open XML SDK では、SpreadsheetDocument クラスが Excel ドキュメント パッケージを表します。Excel ドキュメントを開いて操作するには、ドキュメントから SpreadsheetDocument クラスのインスタンスを作成します。ドキュメントからインスタンスを作成した後、ワークシートが含まれているメインのブック パーツにアクセスできます。ドキュメント内のテキストは、パッケージ内で SpreadsheetML マークアップを使用して XML として表されます。
ドキュメントからクラス インスタンスを作成するには、Open() のいずれかのメソッドを呼び出します。メソッドにはいくつかの種類があり、それぞれシグネチャが異なります。このトピックのサンプル コードでは、2 つのパラメーターを必要とするシグネチャを持つ Open(String, Boolean) メソッドを使用します。最初のパラメーターには、開くドキュメントを表す完全なパスの文字列を指定します。2 番目のパラメーターは true または false で、開いたファイルを編集するかどうかを指定します。このパラメーターを false に指定した場合は、ドキュメントに対する変更が保存されません。
Open メソッドを呼び出すコードを以下の例に示します。
// Open the document for editing.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))
' Open the document for editing.
Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
スプレッドシート ドキュメント パッケージを開いたら、ブック内のシートに行を追加できます。各ブックには、ブック パーツと、少なくとも 1 つの Worksheet があります。Workbook にアクセスするには、以下のコード例のように、WorkbookPart によって表される既存のドキュメント本体への参照を割り当てます。
WorkbookPart wbPart = document.WorkbookPart;
Dim wbPart As WorkbookPart = document.WorkbookPart
SpreadsheetML ドキュメントの基本的なドキュメント構造は、Sheets 要素と Sheet 要素で成り立っています。これらはブック内のワークシートを参照します。ワークシートごとに別々の XML ファイルが作成されます。たとえば、Workbook.xml ファイルには、MySheet1 と MySheet2 という名前の 2 つのワークシートを持つブックの SpreadsheetML があります。Workbook.xml を以下のコード例に示します。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<workbook xmlns=https://schemas.openxmlformats.org/spreadsheetml/2006/main xmlns:r="https://schemas.openxmlformats.org/officeDocument/2006/relationships">
<sheets>
<sheet name="MySheet1" sheetId="1" r:id="rId1" />
<sheet name="MySheet2" sheetId="2" r:id="rId2" />
</sheets>
</workbook>
ワークシート XML ファイルは、1 つまたは複数のブロック レベルの要素 (SheetData など) を持ちます。sheetData は、セルのテーブルを表し、1 つまたは複数の Row 要素を持ちます。row は、1 つまたは複数の Cell 要素を持ちます。各セルは、そのセルの値を表す CellValue 要素を持ちます。たとえば、あるブックの最初のワークシート (セル A1 の値が 100 で、それ以外の値はないものとする) の SpreadsheetML は、ファイル Sheet1.xml 内に置かれ、次のコード例のように記述されます。
<?xml version="1.0" encoding="UTF-8" ?>
<worksheet xmlns="https://schemas.openxmlformats.org/spreadsheetml/2006/main">
<sheetData>
<row r="1">
<c r="A1">
<v>100</v>
</c>
</row>
</sheetData>
</worksheet>
Open XML SDK 2.0 を使用すると、SpreadsheetML の要素に対応した、厳密に型指定されたクラスを使用して、ドキュメントの構造と内容を作成できます。これらのクラスは DocumentFormat.OpenXML.Spreadsheet 名前空間にあります。以下の表は、workbook、sheets、sheet、worksheet、sheetData の各要素に対応したクラスのクラス名の一覧です。
SpreadsheetML 要素 |
Open XML SDK 2.0 のクラス |
説明 |
---|---|---|
workbook |
DocumentFormat.OpenXml.Spreadsheet.Workbook |
メイン ドキュメント パーツのルート要素。 |
sheets |
DocumentFormat.OpenXml.Spreadsheet.Sheets |
ISO/IEC 29500 (英語) の仕様で規定されている、シート、ファイル バージョン、その他のブロック レベル構造のコンテナー。 |
sheet |
DocumentFormat.OpenXml.Spreadsheet.Sheet |
シート定義ファイルを指し示すシート。 |
worksheet |
DocumentFormat.OpenXml.Spreadsheet.Worksheet |
シート データが含まれているシート定義ファイル。 |
sheetData |
DocumentFormat.OpenXml.Spreadsheet.SheetData |
セルの表。行ごとにグループ化されています。 |
row |
DocumentFormat.OpenXml.Spreadsheet.Row |
セルの表内の行。 |
c |
DocumentFormat.OpenXml.Spreadsheet.Cell |
行内のセル。 |
v |
DocumentFormat.OpenXml.Spreadsheet.CellValue |
セルの値。 |
SpreadsheetML マークアップを生成してワークシートを追加する
メインのドキュメント パーツの本体にアクセスしたら、ワークシートを追加します。それには、AddNewPart<T>(String, String) メソッドを呼び出して新しい WorksheetPart を作成します。以下のコード例は、新しい WorksheetPart を追加します。
// Add a new worksheet.
WorksheetPart newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
newWorksheetPart.Worksheet.Save();
' Add a new worksheet.
Dim newWorksheetPart As WorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart(Of WorksheetPart)()
newWorksheetPart.Worksheet = New Worksheet(New SheetData())
newWorksheetPart.Worksheet.Save()
サンプル コード
この例では、OpenAndAddToSpreadsheetStream メソッドを使用して、既に開いているストリームからスプレッドシート ドキュメントを開いてテキストを追加します。プログラム内では、次の例を使用して、Sheet11.xslx という名前のファイルを使用する OpenAndAddToSpreadsheetStream メソッドを呼び出すことができます。
string strDoc = @"C:\Users\Public\Documents\Sheet11.xlsx";
;
Stream stream = File.Open(strDoc, FileMode.Open);
OpenAndAddToSpreadsheetStream(stream);
stream.Close();
Dim strDoc As String = "C:\Users\Public\Documents\Sheet11.xlsx"
Dim stream As Stream = File.Open(strDoc, FileMode.Open)
OpenAndAddToSpreadsheetStream(stream)
stream.Close()
OpenAddAndAddToSpreadsheetStream メソッドでは渡されたストリームを閉じていないことに注意してください。呼び出し側でストリームを閉じる必要があります。
以下に、C# と Visual Basic による完全なサンプル コードを示します。
public static void OpenAndAddToSpreadsheetStream(Stream stream)
{
// Open a SpreadsheetDocument based on a stream.
SpreadsheetDocument spreadsheetDocument =
SpreadsheetDocument.Open(stream, true);
// Add a new worksheet.
WorksheetPart newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
newWorksheetPart.Worksheet = new Worksheet(new SheetData());
newWorksheetPart.Worksheet.Save();
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>();
string relationshipId = spreadsheetDocument.WorkbookPart.GetIdOfPart(newWorksheetPart);
// Get a unique ID for the new worksheet.
uint sheetId = 1;
if (sheets.Elements<Sheet>().Count() > 0)
{
sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
}
// Give the new worksheet a name.
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);
spreadsheetDocument.WorkbookPart.Workbook.Save();
// Close the document handle.
spreadsheetDocument.Close();
// Caller must close the stream.
}
Public Sub OpenAndAddToSpreadsheetStream(ByVal stream As Stream)
' 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)
' Get a unique ID for the new worksheet.
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
' Give the new worksheet a name.
Dim sheetName As String = ("Sheet" + sheetId.ToString())
' Append 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)
mySpreadsheetDocument.WorkbookPart.Workbook.Save()
'Close the document handle.
mySpreadsheetDocument.Close()
'Caller must close the stream.
End Sub