別のプレゼンテーションに段落を移動する
適用対象: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010
この記事の内容
PresentationDocument オブジェクトの取得
プレゼンテーション ドキュメントの基本構造
図形テキスト本体の構造
サンプル コードの動作のしくみ
サンプル コード
このトピックでは、プログラムで Open XML SDK 2.0 for Microsoft Office のクラスを使用してプレゼンテーション内の段落を別のプレゼンテーションに移動する方法を説明します。
このトピックのコードをコンパイルするには、以下のアセンブリ ディレクティブが必要です。
using System.Linq;
using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Packaging;
using Drawing = DocumentFormat.OpenXml.Drawing;
Imports System.Linq
Imports DocumentFormat.OpenXml.Presentation
Imports DocumentFormat.OpenXml.Packaging
Imports Drawing = DocumentFormat.OpenXml.Drawing
PresentationDocument オブジェクトの取得
In the Open XML SDK では、PresentationDocument クラスがプレゼンテーション ドキュメント パッケージを表します。プレゼンテーション ドキュメントを操作するには、まず PresentationDocument クラスのインスタンスを作成して、そのインスタンスを操作します。このドキュメントからクラス インスタンスを作成するには、 Open(String, Boolean) メソッドを呼び出します。このメソッドは、ファイル パスの他に、第 2 パラメーターとして、ドキュメントが編集可能かどうかを示す Boolean 値を持ちます。ドキュメントを読み取り/書き込み用に開くには、次の using ステートメントの例のように、このパラメーターに値 true を指定します。このコードの file パラメーターは、開くドキュメントのファイルのパスを表す文字列です。
using (PresentationDocument doc = PresentationDocument.Open(file, true))
{
// Insert other code here.
}
Using doc As PresentationDocument = PresentationDocument.Open(file, True)
' Insert other code here.
End Using
using ステートメントは、一般的な .Open, .Save, .Close シーケンスに代わる手段として推奨されます。これを使用すると、対応する右かっこに達したとき、Dispose メソッド (Open XML SDK でリソースのクリーンアップに使われる内部メソッド) が自動的に呼び出されます。using ステートメントに続くブロックが、using ステートメントで作成または指定したオブジェクト (このケースでは doc) のスコープとして設定されます。
プレゼンテーション ドキュメントの基本構造
PresentationML ドキュメントの基本構造は、いくつかのパーツで構成され、そのうちの 1 つであるメイン パーツにプレゼンテーション定義が含まれます。ISO/IEC 29500 (英語) 仕様で、PresentationML パッケージの全体的なフォームは次のように記述されています。
PresentationML パッケージのメイン パーツはプレゼンテーション ルート要素から始まります。この要素にはプレゼンテーションが含まれ、このプレゼンテーションから スライド リスト、スライド マスター リスト、ノート マスター リスト、および配布資料マスター リストが参照されます。スライド リストはプレゼンテーションのすべてのスライドを参照します。スライド マスター リストは、プレゼンテーションで使用されるスライド マスター全体を参照します。ノート マスターはノート ページの書式設定に関する情報を含み、配布資料マスターは配布資料の見た目を記述します。
"配布資料" とは、"聴衆" に後で参照してもらうために一連のスライドを印刷したものです。
各スライドには、テキストやグラフィックスの他に、"コメント" と "ノート" を含めることができ、さらに "レイアウト" を与えることができます。また、各スライドを 1 つまたは複数のカスタム プレゼンテーションの一部にすることができます ("コメント" はプレゼンテーション スライド デッキのメンテナンス担当者用の注釈、"ノート" はプレゼンテーションの発表者または参加者用のメモです)。
PresentationML ドキュメントに含めることができるその他の機能には、アニメーション、サウンド、ビデオ、スライド間の画面切り替えなどがあります。
PresentationML ドキュメントが単一のパーツ内に 1 つの大きな本体として格納されることはありません。その代わり、機能グループごとにその機能を実現する要素が別々のパーツに格納されます。たとえば、ドキュメント内のすべてのコメントが 1 つのコメント パーツに格納される一方で、各スライドは自分のパーツを持ちます。
c ISO/IEC29500: 2008.
次の XML コードは、ID 267 および 256 で示される 2 つのスライドを含むプレゼンテーションを表します。
<p:presentation xmlns:p="…" … >
<p:sldMasterIdLst>
<p:sldMasterId
xmlns:rel="http://…/relationships" rel:id="rId1"/>
</p:sldMasterIdLst>
<p:notesMasterIdLst>
<p:notesMasterId
xmlns:rel="http://…/relationships" rel:id="rId4"/>
</p:notesMasterIdLst>
<p:handoutMasterIdLst>
<p:handoutMasterId
xmlns:rel="http://…/relationships" rel:id="rId5"/>
</p:handoutMasterIdLst>
<p:sldIdLst>
<p:sldId id="267"
xmlns:rel="http://…/relationships" rel:id="rId2"/>
<p:sldId id="256"
xmlns:rel="http://…/relationships" rel:id="rId3"/>
</p:sldIdLst>
<p:sldSz cx="9144000" cy="6858000"/>
<p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>
Open XML SDK 2.0 を使用すると、PresentationML 要素に対応する厳密に型指定されたクラスを使用したドキュメント構造とコンテンツを作成できます。これらのクラスは DocumentFormat.OpenXml.Presentation 名前空間にあります。以下の表に、sld、sldLayout、sldMaster、notesMaster の各要素に対応するクラスのクラス名を示します。
PresentationML 要素 |
Open XML SDK 2.0 クラス |
説明 |
---|---|---|
sld |
プレゼンテーション スライド。SlidePart のルート要素 |
|
sldLayout |
スライド レイアウト。SlideLayoutPart のルート要素 |
|
sldMaster |
スライド マスター。SlideMasterPart のルート要素 |
|
notesMaster |
ノート マスター (または handoutMaster)。NotesMasterPart のルート要素 |
図形テキスト本体の構造
ISO/IEC 29500 (英語) 仕様で、この要素の構造は次のように記述されています。
この要素は、対応する図形の内側に含めるテキストが存在することを指定するものです。目に見えるすべてのテキストと、目に見えるすべてのテキスト関連プロパティがこの要素に含まれます。複数の段落と、段落内に複数のテキスト セクションを含めることもできます。
c ISO/IEC29500: 2008.
次の表に、図形テキスト本体の子要素と、各子要素の説明を示します。
子要素 |
説明 |
---|---|
bodyPr |
本体のプロパティ |
lstStyle |
テキスト リストのプロパティ |
p |
テキスト段落 |
次の XML スキーマ フラグメントが、この要素のコンテンツを定義します。
<complexType name="CT_TextBody">
<sequence>
<element name="bodyPr" type="CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
<element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
<element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
サンプル コードの動作のしくみ
このトピックのコードは 2 つのメソッド MoveParagraphToPresentation と GetFirstSlide で構成されます。最初のメソッドは、2 つの文字列パラメーターを取ります。1 つは、移動する段落を含む移動元ファイルを表し、もう 1 つは、段落の移動先ファイルを表します。このメソッドは、両方のプレゼンテーション ファイルを開き、GetFirstSlide メソッドを呼び出して各ファイルの最初のスライドを取得します。次に、各スライドの最初の TextBody 図形と、移動元の図形の最初の段落を取得します。そして、移動元の段落についてディープ クローンを実行して、移動元の Paragraph オブジェクトそのものと、そのオブジェクトに含まれるテキストなどのあらゆるものをコピーします。その後、移動先ファイルにクローン段落を挿入し、移動元ファイルから元の段落を削除してそれをプレースホルダー段落に置き換えます。最後に、変更されたスライドを両方のプレゼンテーションに保存します。
// Moves a paragraph range in a TextBody shape in the source document
// to another TextBody shape in the target document.
public static void MoveParagraphToPresentation(string sourceFile, string targetFile)
{
// Open the source file as read/write.
using (PresentationDocument sourceDoc = PresentationDocument.Open(sourceFile, true))
{
// Open the target file as read/write.
using (PresentationDocument targetDoc = PresentationDocument.Open(targetFile, true))
{
// Get the first slide in the source presentation.
SlidePart slide1 = GetFirstSlide(sourceDoc);
// Get the first TextBody shape in it.
TextBody textBody1 = slide1.Slide.Descendants<TextBody>().First();
// Get the first paragraph in the TextBody shape.
// Note: "Drawing" is the alias of namespace DocumentFormat.OpenXml.Drawing
Drawing.Paragraph p1 = textBody1.Elements<Drawing.Paragraph>().First();
// Get the first slide in the target presentation.
SlidePart slide2 = GetFirstSlide(targetDoc);
// Get the first TextBody shape in it.
TextBody textBody2 = slide2.Slide.Descendants<TextBody>().First();
// Clone the source paragraph and insert the cloned. paragraph into the target TextBody shape.
// Passing "true" creates a deep clone, which creates a copy of the
// Paragraph object and everything directly or indirectly referenced by that object.
textBody2.Append(p1.CloneNode(true));
// Remove the source paragraph from the source file.
textBody1.RemoveChild<Drawing.Paragraph>(p1);
// Replace the removed paragraph with a placeholder.
textBody1.AppendChild<Drawing.Paragraph>(new Drawing.Paragraph());
// Save the slide in the source file.
slide1.Slide.Save();
// Save the slide in the target file.
slide2.Slide.Save();
}
}
}
' Moves a paragraph range in a TextBody shape in the source document
' to another TextBody shape in the target document.
Public Shared Sub MoveParagraphToPresentation(ByVal sourceFile As String, ByVal targetFile As String)
' Open the source file as read/write.
Using sourceDoc As PresentationDocument = PresentationDocument.Open(sourceFile, True)
' Open the target file as read/write.
Using targetDoc As PresentationDocument = PresentationDocument.Open(targetFile, True)
' Get the first slide in the source presentation.
Dim slide1 As SlidePart = GetFirstSlide(sourceDoc)
' Get the first TextBody shape in it.
Dim textBody1 As TextBody = slide1.Slide.Descendants(Of TextBody)().First()
' Get the first paragraph in the TextBody shape.
' Note: "Drawing" is the alias of namespace DocumentFormat.OpenXml.Drawing
Dim p1 As Drawing.Paragraph = textBody1.Elements(Of Drawing.Paragraph)().First()
' Get the first slide in the target presentation.
Dim slide2 As SlidePart = GetFirstSlide(targetDoc)
' Get the first TextBody shape in it.
Dim textBody2 As TextBody = slide2.Slide.Descendants(Of TextBody)().First()
' Clone the source paragraph and insert the cloned. paragraph into the target TextBody shape.
' Passing "true" creates a deep clone, which creates a copy of the
' Paragraph object and everything directly or indirectly referenced by that object.
textBody2.Append(p1.CloneNode(True))
' Remove the source paragraph from the source file.
textBody1.RemoveChild(Of Drawing.Paragraph)(p1)
' Replace the removed paragraph with a placeholder.
textBody1.AppendChild(Of Drawing.Paragraph)(New Drawing.Paragraph())
' Save the slide in the source file.
slide1.Slide.Save()
' Save the slide in the target file.
slide2.Slide.Save()
End Using
End Using
End Sub
GetFirstSlide メソッドは、渡された PresentationDocument オブジェクトを受け取り、そのプレゼンテーション パーツを取得し、そのスライド リストの最初のスライドの ID を取得します。その後、スライドのリレーションシップ ID を取得し、リレーションシップ ID からスライド パーツを取得して、呼び出し元のメソッドにスライド パーツを返します。
// Get the slide part of the first slide in the presentation document.
public static SlidePart GetFirstSlide(PresentationDocument presentationDocument)
{
// Get relationship ID of the first slide
PresentationPart part = presentationDocument.PresentationPart;
SlideId slideId = part.Presentation.SlideIdList.GetFirstChild<SlideId>();
string relId = slideId.RelationshipId;
// Get the slide part by the relationship ID.
SlidePart slidePart = (SlidePart)part.GetPartById(relId);
return slidePart;
}
' Get the slide part of the first slide in the presentation document.
Public Shared Function GetFirstSlide(ByVal presentationDocument As PresentationDocument) As SlidePart
' Get relationship ID of the first slide
Dim part As PresentationPart = presentationDocument.PresentationPart
Dim slideId As SlideId = part.Presentation.SlideIdList.GetFirstChild(Of SlideId)()
Dim relId As String = slideId.RelationshipId
' Get the slide part by the relationship ID.
Dim slidePart As SlidePart = CType(part.GetPartById(relId), SlidePart)
Return slidePart
End Function
サンプル コード
このサンプル コードを使用すると、プレゼンテーション内の段落を別のプレゼンテーションに移動できます。プログラム内で MoveParagraphToPresentation メソッドを次のように呼び出すと、プレゼンテーション ファイル "Myppt4.pptx" の最初の段落がプレゼンテーション ファイル "Myppt12.pptx" に移動されます。
string sourceFile = @"C:\Users\Public\Documents\Myppt4.pptx";
string targetFile = @"C:\Users\Public\Documents\Myppt12.pptx";
MoveParagraphToPresentation(sourceFile, targetFile);
Dim sourceFile As String = "C:\Users\Public\Documents\Myppt4.pptx"
Dim targetFile As String = "C:\Users\Public\Documents\Myppt12.pptx"
MoveParagraphToPresentation(sourceFile, targetFile)
プログラムを実行した後、移動元と移動先のファイルの内容を調べて段落が移動したことを確認してください。
以下に、C# と Visual Basic による完全なサンプル コードを示します。
// Moves a paragraph range in a TextBody shape in the source document
// to another TextBody shape in the target document.
public static void MoveParagraphToPresentation(string sourceFile, string targetFile)
{
// Open the source file as read/write.
using (PresentationDocument sourceDoc = PresentationDocument.Open(sourceFile, true))
{
// Open the target file as read/write.
using (PresentationDocument targetDoc = PresentationDocument.Open(targetFile, true))
{
// Get the first slide in the source presentation.
SlidePart slide1 = GetFirstSlide(sourceDoc);
// Get the first TextBody shape in it.
TextBody textBody1 = slide1.Slide.Descendants<TextBody>().First();
// Get the first paragraph in the TextBody shape.
// Note: "Drawing" is the alias of namespace DocumentFormat.OpenXml.Drawing
Drawing.Paragraph p1 = textBody1.Elements<Drawing.Paragraph>().First();
// Get the first slide in the target presentation.
SlidePart slide2 = GetFirstSlide(targetDoc);
// Get the first TextBody shape in it.
TextBody textBody2 = slide2.Slide.Descendants<TextBody>().First();
// Clone the source paragraph and insert the cloned. paragraph into the target TextBody shape.
// Passing "true" creates a deep clone, which creates a copy of the
// Paragraph object and everything directly or indirectly referenced by that object.
textBody2.Append(p1.CloneNode(true));
// Remove the source paragraph from the source file.
textBody1.RemoveChild<Drawing.Paragraph>(p1);
// Replace the removed paragraph with a placeholder.
textBody1.AppendChild<Drawing.Paragraph>(new Drawing.Paragraph());
// Save the slide in the source file.
slide1.Slide.Save();
// Save the slide in the target file.
slide2.Slide.Save();
}
}
}
// Get the slide part of the first slide in the presentation document.
public static SlidePart GetFirstSlide(PresentationDocument presentationDocument)
{
// Get relationship ID of the first slide
PresentationPart part = presentationDocument.PresentationPart;
SlideId slideId = part.Presentation.SlideIdList.GetFirstChild<SlideId>();
string relId = slideId.RelationshipId;
// Get the slide part by the relationship ID.
SlidePart slidePart = (SlidePart)part.GetPartById(relId);
return slidePart;
}
' Moves a paragraph range in a TextBody shape in the source document
' to another TextBody shape in the target document.
Public Sub MoveParagraphToPresentation(ByVal sourceFile As String, ByVal targetFile As String)
' Open the source file.
Dim sourceDoc As PresentationDocument = PresentationDocument.Open(sourceFile, True)
' Open the target file.
Dim targetDoc As PresentationDocument = PresentationDocument.Open(targetFile, True)
' Get the first slide in the source presentation.
Dim slide1 As SlidePart = GetFirstSlide(sourceDoc)
' Get the first TextBody shape in it.
Dim textBody1 As TextBody = slide1.Slide.Descendants(Of TextBody).First()
' Get the first paragraph in the TextBody shape.
' Note: Drawing is the alias of the namespace DocumentFormat.OpenXml.Drawing
Dim p1 As Drawing.Paragraph = textBody1.Elements(Of Drawing.Paragraph).First()
' Get the first slide in the target presentation.
Dim slide2 As SlidePart = GetFirstSlide(targetDoc)
' Get the first TextBody shape in it.
Dim textBody2 As TextBody = slide2.Slide.Descendants(Of TextBody).First()
' Clone the source paragraph and insert the cloned paragraph into the target TextBody shape.
textBody2.Append(p1.CloneNode(True))
' Remove the source paragraph from the source file.
textBody1.RemoveChild(Of Drawing.Paragraph)(p1)
' Replace it with an empty one, because a paragraph is required for a TextBody shape.
textBody1.AppendChild(Of Drawing.Paragraph)(New Drawing.Paragraph())
' Save the slide in the source file.
slide1.Slide.Save()
' Save the slide in the target file.
slide2.Slide.Save()
End Sub
' Get the slide part of the first slide in the presentation document.
Public Function GetFirstSlide(ByVal presentationDoc As PresentationDocument) As SlidePart
' Get relationship ID of the first slide.
Dim part As PresentationPart = presentationDoc.PresentationPart
Dim slideId As SlideId = part.Presentation.SlideIdList.GetFirstChild(Of SlideId)()
Dim relId As String = slideId.RelationshipId
' Get the slide part by the relationship ID.
Dim slidePart As SlidePart = CType(part.GetPartById(relId), SlidePart)
Return slidePart
End Function