プレゼンテーションからスライドを削除する
このトピックでは、Open XML SDK for Office を使用してプレゼンテーションからスライドをプログラムで削除する方法について説明します。 また、存在する可能性があるカスタム ショーからスライドへのすべての参照を削除する方法も示します。 プレゼンテーション ファイル内の特定のスライドを削除するには、プレゼンテーション内のスライドの数を最初に把握しておく必要があります。 そのため、このハウツーのコードは 2 つの部分に分かれています。 1 つ目はスライドの数をカウントし、2 つ目は特定のインデックスでスライドを削除しています。
注:
[!メモ] アウトライン表示の設定を含むプレゼンテーションなど、より複雑なプレゼンテーションからスライドを削除する場合は、追加の手順が必要になることがあります。
Presentation オブジェクトの取得
Open XML SDK では、 PresentationDocument クラスはプレゼンテーション ドキュメント パッケージを表します。 プレゼンテーション ドキュメントを操作するには、まず PresentationDocument
クラスのインスタンスを作成してから、そのインスタンスを操作します。 ドキュメントからクラス インスタンスを作成するには、 Open
メソッドオーバーロードのいずれかを呼び出します。 このトピックのコードでは、 Open メソッドを使用します。このメソッドは、開くファイルを指定する最初のパラメーターとしてファイル パスを受け取り、2 番目のパラメーターとしてブール値を使用してドキュメントが編集可能かどうかを指定します。 この 2 番目のパラメーターを false
に設定して、読み取り専用アクセス用にファイルを開くか、読み取り/書き込みアクセス用にファイルを開く場合は true
します。 このトピックのコードはファイルを 2 回開きます。1 回目はスライドの数をカウントし、もう 1 回は特定のスライドを削除します。 プレゼンテーション内のスライドの数をカウントする場合、誤って書き込みをしてしまわないようにファイルを保護するため、読み取り専用アクセスでファイルを開くのが最善です。 次の using
ステートメントは、読み取り専用アクセス用にファイルを開きます。 このコード例では、 presentationFile
パラメーターは、ドキュメントを開くファイルのパスを表す文字列です。
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
プレゼンテーション ファイルからスライドを削除するには、次の using
ステートメントに示すように、読み取り/書き込みアクセス用にスライドを開きます。
// Open the source document as read/write.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
v3.0.0 以降では、using ステートメントに依存することを優先して、Close() メソッドが削除されました。
これにより、閉じかっこに達したときに、 Dispose() メソッドが自動的に呼び出されます。
using
ステートメントに続くブロックは、using
ステートメントで作成または名前付けされたオブジェクトのスコープを確立します(この場合はpresentationDocument
。
プレゼンテーション ドキュメントの基本構造
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 のルート要素 |
スライドの数をカウントする
サンプル コードは、 CountSlides
メソッドの 2 つのオーバーロードで構成されます。 最初のオーバーロードは string
パラメーターを使用し、2 番目のオーバーロードでは PresentationDocument
パラメーターを使用します。 最初の CountSlides
メソッドでは、サンプル コードによって、 using
ステートメントでプレゼンテーション ドキュメントが開きます。 次に、 PresentationDocument
オブジェクトを 2 番目の CountSlides
メソッドに渡します。これは、プレゼンテーション内のスライドの数を表す整数を返します。
// Pass the presentation to the next CountSlide method
// and return the slide count.
return CountSlides(presentationDocument);
2 番目のCountSlides
メソッドでは、渡されたPresentationDocument
オブジェクトがnull
されていないことを確認し、PresentationDocument
オブジェクトからPresentationPart
オブジェクトを取得します。
SlideParts
を使用して、コードは slideCount を取得し、それを返します。
if (presentationDocument is null)
{
throw new ArgumentNullException("presentationDocument");
}
int slidesCount = 0;
// Get the presentation part of document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Get the slide count from the SlideParts.
if (presentationPart is not null)
{
slidesCount = presentationPart.SlideParts.Count();
}
// Return the slide count to the previous method.
return slidesCount;
特定のスライドを削除する
スライドを削除するためのコードでは、 DeleteSlide
メソッドの 2 つのオーバーロードを使用します。 最初にオーバーロードされた DeleteSlide
メソッドは、プレゼンテーション ファイル名とパスを表す文字列と、削除するスライドの 0 から始まるインデックス位置を表す整数の 2 つのパラメーターを受け取ります。 読み取り/書き込みアクセス用のプレゼンテーション ファイルを開き、 PresentationDocument
オブジェクトを取得し、そのオブジェクトとインデックス番号を次にオーバーロードされた DeleteSlide
メソッドに渡します。これにより、削除が実行されます。
// Get the presentation object and pass it to the next DeleteSlide method.
static void DeleteSlide(string presentationFile, int slideIndex)
{
// Open the source document as read/write.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
// Pass the source document and the index of the slide to be deleted to the next DeleteSlide method.
DeleteSlide(presentationDocument, slideIndex);
}
}
2 つ目のオーバーロードされた DeleteSlide
メソッドの最初のセクションでは、 CountSlides
メソッドを使用してプレゼンテーション内のスライドの数を取得します。 次に、プレゼンテーションにあるスライド ID のリストを取得し、指定したスライドをスライド リストの中で探して、そのスライドをスライド リストから削除します。
// Delete the specified slide from the presentation.
static void DeleteSlide(PresentationDocument presentationDocument, int slideIndex)
{
if (presentationDocument is null)
{
throw new ArgumentNullException(nameof(presentationDocument));
}
// Use the CountSlides sample to get the number of slides in the presentation.
int slidesCount = CountSlides(presentationDocument);
if (slideIndex < 0 || slideIndex >= slidesCount)
{
throw new ArgumentOutOfRangeException("slideIndex");
}
// Get the presentation part from the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Get the presentation from the presentation part.
Presentation? presentation = presentationPart?.Presentation;
// Get the list of slide IDs in the presentation.
SlideIdList? slideIdList = presentation?.SlideIdList;
// Get the slide ID of the specified slide
SlideId? slideId = slideIdList?.ChildElements[slideIndex] as SlideId;
// Get the relationship ID of the slide.
string? slideRelId = slideId?.RelationshipId;
// If there's no relationship ID, there's no slide to delete.
if (slideRelId is null)
{
return;
}
// Remove the slide from the slide list.
slideIdList!.RemoveChild(slideId);
2 つ目のオーバーロードされた DeleteSlide
メソッドの次のセクションでは、カスタム ショーから削除されたスライドへのすべての参照が削除されます。 この作業は、ユーザー設定のスライド ショーのリストと、それらの各スライド ショーにあるスライドのリストの反復処理によって行われます。
続いてこのメソッドは、スライド リスト エントリのリンクされたリストを宣言およびインスタンス化し、削除されたスライドのリレーションシップ ID を使用してそのスライドへの参照を見つけ出します。 さらに、それらの参照をスライド リスト エントリのリストに追加した後、各参照をそれぞれのユーザー設定のスライド ショーのスライド リストから削除します。
// Remove references to the slide from all custom shows.
if (presentation!.CustomShowList is not null)
{
// Iterate through the list of custom shows.
foreach (var customShow in presentation.CustomShowList.Elements<CustomShow>())
{
if (customShow.SlideList is not null)
{
// Declare a link list of slide list entries.
LinkedList<SlideListEntry> slideListEntries = new LinkedList<SlideListEntry>();
foreach (SlideListEntry slideListEntry in customShow.SlideList.Elements())
{
// Find the slide reference to remove from the custom show.
if (slideListEntry.Id is not null && slideListEntry.Id == slideRelId)
{
slideListEntries.AddLast(slideListEntry);
}
}
// Remove all references to the slide from the custom show.
foreach (SlideListEntry slideListEntry in slideListEntries)
{
customShow.SlideList.RemoveChild(slideListEntry);
}
}
}
}
最後に、削除されたスライドのスライド パーツが削除されます。
// Get the slide part for the specified slide.
SlidePart slidePart = (SlidePart)presentationPart!.GetPartById(slideRelId);
// Remove the slide part.
presentationPart.DeletePart(slidePart);
サンプル コード
以下は、C# および Visual Basic の完全なサンプル コードです。
// Get the presentation object and pass it to the next CountSlides method.
static int CountSlides(string presentationFile)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Pass the presentation to the next CountSlide method
// and return the slide count.
return CountSlides(presentationDocument);
}
}
// Count the slides in the presentation.
static int CountSlides(PresentationDocument presentationDocument)
{
if (presentationDocument is null)
{
throw new ArgumentNullException("presentationDocument");
}
int slidesCount = 0;
// Get the presentation part of document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Get the slide count from the SlideParts.
if (presentationPart is not null)
{
slidesCount = presentationPart.SlideParts.Count();
}
// Return the slide count to the previous method.
return slidesCount;
}
// Get the presentation object and pass it to the next DeleteSlide method.
static void DeleteSlide(string presentationFile, int slideIndex)
{
// Open the source document as read/write.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
// Pass the source document and the index of the slide to be deleted to the next DeleteSlide method.
DeleteSlide(presentationDocument, slideIndex);
}
}
// Delete the specified slide from the presentation.
static void DeleteSlide(PresentationDocument presentationDocument, int slideIndex)
{
if (presentationDocument is null)
{
throw new ArgumentNullException(nameof(presentationDocument));
}
// Use the CountSlides sample to get the number of slides in the presentation.
int slidesCount = CountSlides(presentationDocument);
if (slideIndex < 0 || slideIndex >= slidesCount)
{
throw new ArgumentOutOfRangeException("slideIndex");
}
// Get the presentation part from the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Get the presentation from the presentation part.
Presentation? presentation = presentationPart?.Presentation;
// Get the list of slide IDs in the presentation.
SlideIdList? slideIdList = presentation?.SlideIdList;
// Get the slide ID of the specified slide
SlideId? slideId = slideIdList?.ChildElements[slideIndex] as SlideId;
// Get the relationship ID of the slide.
string? slideRelId = slideId?.RelationshipId;
// If there's no relationship ID, there's no slide to delete.
if (slideRelId is null)
{
return;
}
// Remove the slide from the slide list.
slideIdList!.RemoveChild(slideId);
// Remove references to the slide from all custom shows.
if (presentation!.CustomShowList is not null)
{
// Iterate through the list of custom shows.
foreach (var customShow in presentation.CustomShowList.Elements<CustomShow>())
{
if (customShow.SlideList is not null)
{
// Declare a link list of slide list entries.
LinkedList<SlideListEntry> slideListEntries = new LinkedList<SlideListEntry>();
foreach (SlideListEntry slideListEntry in customShow.SlideList.Elements())
{
// Find the slide reference to remove from the custom show.
if (slideListEntry.Id is not null && slideListEntry.Id == slideRelId)
{
slideListEntries.AddLast(slideListEntry);
}
}
// Remove all references to the slide from the custom show.
foreach (SlideListEntry slideListEntry in slideListEntries)
{
customShow.SlideList.RemoveChild(slideListEntry);
}
}
}
}
// Get the slide part for the specified slide.
SlidePart slidePart = (SlidePart)presentationPart!.GetPartById(slideRelId);
// Remove the slide part.
presentationPart.DeletePart(slidePart);
}