プレゼンテーション ドキュメントを読み取り専用アクセス用に開く
このトピックでは、Open XML SDK for Office のクラスを使用して、読み取り専用アクセス用のプレゼンテーション ドキュメントをプログラムで開く方法について説明します。
ファイルを読み取り専用で開く方法
プレゼンテーション ドキュメントを開いてスライドを参照したいときがあります。 場合によっては、スライドから情報を取得したり、スライドをスライド ライブラリにコピーしたり、スライドのタイトルをリストしたりすることもあります。 しかも、それらの操作を、ドキュメントの内容を変更せずに実行したいときがあります。 そのようなときは、ドキュメントを読み取り専用で開きます。 このハウツー トピックでは、プログラムによって、プレゼンテーション ドキュメントを読み取り専用で開く方法についていくつか説明します。
PresentationDocument クラスのインスタンスを作成する
Open XML SDK では、 PresentationDocument クラスはプレゼンテーション ドキュメント パッケージを表します。 プレゼンテーション ドキュメントを操作するには、まず PresentationDocument
クラスのインスタンスを作成してから、そのインスタンスを操作します。 ドキュメントからクラス インスタンスを作成するには、 Open メソッドのいずれかを呼び出します。 いくつかの Open メソッドが提供されていて、シグネチャがそれぞれ異なります。 次の表に、パッケージを開くために使用できる Open
メソッドのオーバーロードのサブセットを示します。
名前 | 説明 |
---|---|
Open | 指定したファイルから PresentationDocument クラスの新しいインスタンスを作成します。 |
Open | I/O ストリームから PresentationDocument クラスの新しいインスタンスを作成します。 |
Open | 指定したパッケージから PresentationDocument クラスの新しいインスタンスを作成します。 |
前の表には、ブール値を 2 番目のパラメーターとして受け取り、ドキュメントが編集可能かどうかを指定する 2 つの Open
メソッドが含まれています。 読み取り専用アクセス用にドキュメントを開くには、このパラメーターに false
値を指定します。
たとえば、次の using
ステートメントに示すように、プレゼンテーション ファイルを読み取り専用として開き、PresentationDocument オブジェクトに割り当てることができます。 このコードでは、 presentationFile
パラメーターは、ドキュメントを開くファイルのパスを表す文字列です。
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFilePath, false))
{
// Insert other code here.
}
上の表の Open
メソッドの 2 番目のオーバーロードを使用して、I/O ストリームに基づいて PresentationDocument
クラスのインスタンスを作成することもできます。 ストリーム I/O を使用するMicrosoft SharePoint Foundation 2010 アプリケーションがあり、Open XML SDK を使用してドキュメントを操作する場合は、この方法を使用できます。 次のコード セグメントでは、ストリームに基づいてドキュメントを開きます。
Stream stream = File.Open(strDoc, FileMode.Open);
using (PresentationDocument presentationDocument = PresentationDocument.Open(stream, false))
{
// Place other code here.
}
.NET Framework クラス ライブラリの System.IO.Packaging
名前空間で Open XML サポートを使用するアプリケーションがあり、Open XML SDK を使用してパッケージの読み取り専用を操作するとします。 Open XML SDK には、唯一のパラメーターとして Package
を受け入れるメソッド オーバーロードが含まれています。 ドキュメントを編集用として開く必要があるかどうかを指定するブール値パラメーターはありません。 推奨される方法は、 PresentationDocument
クラスのインスタンスを作成する前に、パッケージを読み取り専用として開く方法です。 この操作を次のコード セグメントに示します。
Package presentationPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read);
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationPackage))
{
// Other code goes here.
}
プレゼンテーション ドキュメントの基本構造
PresentationML
ドキュメントの基本的なドキュメント構造は、多数のパーツで構成され、その中にはプレゼンテーション定義を含むメインパーツがあります。
ISO/IEC 29500 仕様の次のテキストでは、PresentationML
パッケージの全体的な形式について説明します。
PresentationML
パッケージのメイン部分は、プレゼンテーション ルート要素で始まります。 この要素にはプレゼンテーションが含まれており、プレゼンテーションは スライド リスト、スライド マスター リスト、ノート マスター リスト、配布資料マスター リストを参照します。 スライド リストはプレゼンテーション内のすべてのスライドを参照します。スライド マスター リストはプレゼンテーションで使用されるスライド マスター全体を参照します。ノート マスターにはノート ページの書式設定に関する情報が含まれます。配布資料マスターは配布資料がどのように表示されるかを示します。配布資料とは、聴衆に提供できるように一連のスライドを印刷したものです。
テキストやグラフィックのように、各スライドにはコメントとノートを含めることができ、レイアウトを指定したり、1 つ以上のカスタム プレゼンテーションに組み込んだりできます。 コメントは、プレゼンテーション スライド デッキをメンテナンスする人向けの注釈です。 ノートは、プレゼンテーションの発表者または参加者向けのリマインダーやメモです。
PresentationML
ドキュメントには、アニメーション、オーディオ、ビデオ、スライド間の切り替えなどのその他の機能があります。
PresentationML
ドキュメントは、1 つのパーツに 1 つの大きな本文として格納されません。 その代わりに、特定のグループの機能を実現する要素が別個のパーツに格納されます。 たとえば、ドキュメント内のすべての作成者は 1 つの作成者パーツに格納され、各スライドには独自のパーツがあります。ISO/IEC 29500: 2016
次の XML コードの例は、267 と 256 という ID で示される 2 つのスライドを含むプレゼンテーションを表します。
<p:presentation xmlns:p="…" … >
<p:sldMasterIdLst>
<p:sldMasterId
xmlns:rel="https://…/relationships" rel:id="rId1"/>
</p:sldMasterIdLst>
<p:notesMasterIdLst>
<p:notesMasterId
xmlns:rel="https://…/relationships" rel:id="rId4"/>
</p:notesMasterIdLst>
<p:handoutMasterIdLst>
<p:handoutMasterId
xmlns:rel="https://…/relationships" rel:id="rId5"/>
</p:handoutMasterIdLst>
<p:sldIdLst>
<p:sldId id="267"
xmlns:rel="https://…/relationships" rel:id="rId2"/>
<p:sldId id="256"
xmlns:rel="https://…/relationships" rel:id="rId3"/>
</p:sldIdLst>
<p:sldSz cx="9144000" cy="6858000"/>
<p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>
Open XML SDK を使用すると、PresentationML 要素に対応する厳密に型指定されたクラスを使用して、ドキュメント構造とコンテンツを作成できます。 これらのクラスは、 名前空間にあります。 次の表に、 sld
、 sldLayout
、 sldMaster
、および notesMaster
の各要素に対応するクラスのクラス名を示します。
PresentationML 要素 | Open XML SDK クラス | 説明 |
---|---|---|
<sld/> |
Slide | プレゼンテーション スライド。 SlidePart のルート要素 |
<sldLayout/> |
SlideLayout | スライド レイアウト。 SlideLayoutPart のルート要素 |
<sldMaster/> |
SlideMaster | スライド マスター。 SlideMasterPart のルート要素 |
<notesMaster/> |
NotesMaster | ノート マスター (または handoutMaster)。 NotesMasterPart のルート要素 |
サンプル コードの動作のしくみ
サンプル コードでは、読み取り専用アクセス用の using
ステートメントでプレゼンテーション ドキュメントを開いた後、 PresentationPart
をインスタンス化し、スライド リストを開きます。 次に、1 番目のスライドのリレーションシップ ID を取得します。
// Get the relationship ID of the first slide.
PresentationPart? part = ppt.PresentationPart;
OpenXmlElementList slideIds = part?.Presentation?.SlideIdList?.ChildElements ?? default;
// If there are no slide IDs then there are no slides.
if (slideIds.Count == 0)
{
sldText = "";
return;
}
string? relId = (slideIds[index] as SlideId)?.RelationshipId;
if (relId is null)
{
sldText = "";
return;
}
リレーションシップ ID relId
から、スライド パーツを取得し、次に、 StringBuilder
を使用してテキスト文字列を作成することで、スライドの内部テキストを取得します。
// Get the slide part from the relationship ID.
SlidePart slide = (SlidePart)part!.GetPartById(relId);
// Build a StringBuilder object.
StringBuilder paragraphText = new StringBuilder();
// Get the inner text of the slide:
IEnumerable<A.Text> texts = slide.Slide.Descendants<A.Text>();
foreach (A.Text text in texts)
{
paragraphText.Append(text.Text);
}
sldText = paragraphText.ToString();
GetSlideIdAndText
メソッドのout
パラメーターであるスライドの内部テキストは、表示するメイン メソッドに返されます。
重要
[!重要] この例では、プレゼンテーション ファイルのテキストのみを表示します。 テキスト以外の図形やグラフィックスなどのパーツは表示されません。
サンプル コード
次の例では、読み取り専用アクセスでプレゼンテーション ファイルを開き、指定したインデックスにあるスライドの内部テキストを取得します。 メソッドを呼び出すには GetSlideIdAndText
プレゼンテーション ドキュメントの完全なパスを渡します。 また、メソッド自体に値が割り当てられる out
パラメーター sldText
を渡すと、その値をメイン プログラムに表示できます。 たとえば、 GetSlideIdAndText
メソッドの次の呼び出しは、引数としてアプリケーションに渡されるインデックスとファイル パスからプレゼンテーション ファイル内の内部テキストを取得します。
ヒント
このプログラムで最も予期される例外は、 ArgumentOutOfRangeException
例外です。 たとえば、この例外は、2 つのスライドを含むファイルで、スライド番号 4 のテキストを表示しようとするとスローされます。 したがって、次の例に示すように、GetSlideIdAndText
メソッドを呼び出すときは、try
ブロックを使用することをお勧めします。
try
{
string file = args[0];
bool isInt = int.TryParse(args[1], out int i);
if (isInt)
{
GetSlideIdAndText(out string sldText, file, i);
Console.WriteLine($"The text in slide #{i + 1} is {sldText}");
}
}
catch(ArgumentOutOfRangeException exp) {
Console.Error.WriteLine(exp.Message);
}
以下は、C# および Visual Basic の完全なコードです。
static void GetSlideIdAndText(out string sldText, string docName, int index)
{
using (PresentationDocument ppt = PresentationDocument.Open(docName, false))
{
// Get the relationship ID of the first slide.
PresentationPart? part = ppt.PresentationPart;
OpenXmlElementList slideIds = part?.Presentation?.SlideIdList?.ChildElements ?? default;
// If there are no slide IDs then there are no slides.
if (slideIds.Count == 0)
{
sldText = "";
return;
}
string? relId = (slideIds[index] as SlideId)?.RelationshipId;
if (relId is null)
{
sldText = "";
return;
}
// Get the slide part from the relationship ID.
SlidePart slide = (SlidePart)part!.GetPartById(relId);
// Build a StringBuilder object.
StringBuilder paragraphText = new StringBuilder();
// Get the inner text of the slide:
IEnumerable<A.Text> texts = slide.Slide.Descendants<A.Text>();
foreach (A.Text text in texts)
{
paragraphText.Append(text.Text);
}
sldText = paragraphText.ToString();
}
}