在 Java 中套用或變更投影片版面

概覽

投影片佈局定義了標題、文字、圖片、圖表和表格等佔位元的位置信息與格式設定。套用佈局可為投影片提供一致的結構,同時允許每張投影片包含其各自的內容。

最常見的佈局包括:

  • 標題投影片:包含標題與副標題佔位元。
  • 標題與內容:包含標題佔位元與通用內容佔位元。
  • 空白:不包含任何內容佔位元,適用於需要手動定位所有圖形的情況。

了解佈局繼承

簡報具有三個相關層級:

  1. 主投影片 定義主題、共用格式、背景與通用物件。
  2. 版面投影片 屬於主投影片,並定義特定的佔位元排列。
  3. 一般投影片 使用一個版面,並儲存此投影片的內容。

一般投影片會從其版面繼承主題與格式,而版面則繼承自其主投影片。直接在一般投影片上設定的值會在該層級覆寫繼承值。建立一般投影片時,會根據所選版面產生佔位元圖形,而填入這些佔位元的內容屬於該一般投影片。

在使用版面建立投影片之前,請先在版面上新增所需的佔位元。之後再向版面加入佔位元,並不會自動在現有的一般投影片中新增相應的佔位元圖形。

此關係有兩個重要的結果:

  • 變更版面上繼承的格式或既有佔位元的幾何形狀,可能會更新所有依賴該版面的投影片。編輯已使用的版面前,請先檢查其依賴的投影片並審閱最終簡報。
  • 仍被投影片使用的版面無法直接移除。請先將其依賴的投影片重新指派至其他版面,或僅移除未使用的版面。

如需瞭解此階層最上層的更多資訊,請參閱投影片母片

選取並套用投影片版面

在簡報遵循標準 PowerPoint 版面定義時,使用版面類型。版面名稱可由使用者編輯且可能會本地化,因此除非您能掌控來源範本,否則僅依名稱選取的可靠性較低。

以下範例在第一個主投影片中尋找 標題與內容。若找不到該版面,則會故意退回使用 空白。第二個 null 檢查是必要的,因為簡報可能僅包含自訂版面。選取的版面接著透過 ISlide.setLayoutSlide 方法套用到第一個一般投影片。

import com.aspose.slides.*;

Presentation presentation = new Presentation("input.pptx");
try {
    IMasterLayoutSlideCollection layoutSlides = presentation.getMasters().get_Item(0).getLayoutSlides();
    ILayoutSlide targetLayout = layoutSlides.getByType(SlideLayoutType.TitleAndObject);

    if (targetLayout == null) {
        targetLayout = layoutSlides.getByType(SlideLayoutType.Blank);
    }

    if (targetLayout == null) {
        throw new IllegalStateException("The first master does not contain a suitable layout slide.");
    }

    presentation.getSlides().get_Item(0).setLayoutSlide(targetLayout);
    presentation.save("output-with-new-layout.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

變更投影片的版面不會移除直接添加於投影片的普通圖形。然而,佔位元位置、繼承的格式以及現有佔位元與新版面之間的對應關係可能會改變,因此在切換差異極大的版面時請檢查輸出結果。

新增版面投影片

選取與建立是分離的操作。前一個範例僅選取既有版面,並未建立新版面。若要建立版面,請在目標主投影片的版面集合上呼叫 IMasterLayoutSlideCollection.add 方法。

以下範例始終新增一個名為 Report Title and Content標題與內容 版面,然後基於該版面新增一般投影片。版面名稱在集合中必須唯一。

import com.aspose.slides.*;

Presentation presentation = new Presentation("input.pptx");
try {
    IMasterSlide masterSlide = presentation.getMasters().get_Item(0);
    ILayoutSlide reportLayout = masterSlide.getLayoutSlides().add(SlideLayoutType.TitleAndObject, "Report Title and Content");
    presentation.getSlides().addEmptySlide(reportLayout);

    presentation.save("output-with-report-layout.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

只有在範本確實需要另一個可重複使用的結構時才新增版面。若已有合適的版面,請選取並重用,而非建立重複的版面。

為版面投影片新增佔位元

ILayoutSlide.getPlaceholderManager 方法提供一個 ILayoutPlaceholderManager,用於向版面新增佔位元圖形。

PowerPoint 佔位元 ILayoutPlaceholderManager 方法
內容 addContentPlaceholder(float x, float y, float width, float height)
內容(垂直) addVerticalContentPlaceholder(float x, float y, float width, float height)
文字 addTextPlaceholder(float x, float y, float width, float height)
文字(垂直) addVerticalTextPlaceholder(float x, float y, float width, float height)
圖片 addPicturePlaceholder(float x, float y, float width, float height)
圖表 addChartPlaceholder(float x, float y, float width, float height)
表格 addTablePlaceholder(float x, float y, float width, float height)
SmartArt addSmartArtPlaceholder(float x, float y, float width, float height)
媒體 addMediaPlaceholder(float x, float y, float width, float height)
線上圖片 addOnlineImagePlaceholder(float x, float y, float width, float height)

以下範例驗證 空白 版面是否存在,向其新增四個佔位元,然後建立使用該修改版面的普通投影片。順序刻意安排:先新增佔位元再建立普通投影片,以便 Aspose.Slides 能在該投影片上產生相對應的佔位元圖形。

import com.aspose.slides.*;

Presentation presentation = new Presentation();
try {
    ILayoutSlide blankLayout = presentation.getLayoutSlides().getByType(SlideLayoutType.Blank);

    if (blankLayout == null) {
        throw new IllegalStateException("The presentation does not contain a Blank layout slide.");
    }

    ILayoutPlaceholderManager placeholderManager = blankLayout.getPlaceholderManager();
    placeholderManager.addContentPlaceholder(20, 20, 310, 270);
    placeholderManager.addVerticalTextPlaceholder(350, 20, 350, 270);
    placeholderManager.addChartPlaceholder(20, 310, 310, 180);
    placeholderManager.addTablePlaceholder(350, 310, 350, 180);

    presentation.getSlides().addEmptySlide(blankLayout);
    presentation.save("output-with-placeholders.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

結果:

版面投影片上的佔位元

移除未使用的版面投影片

使用 Compress.removeUnusedLayoutSlides 方法移除未被任何一般投影片參考的版面。此方法會保留仍在使用中的版面。

import com.aspose.slides.*;

Presentation presentation = new Presentation("input.pptx");
try {
    Compress.removeUnusedLayoutSlides(presentation);
    presentation.save("output-without-unused-layouts.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

若要移除特定的版面,首先使用其 hasDependingSlidesgetDependingSlides 方法。呼叫 ILayoutSlide.remove 前,請先重新指派任何依賴的投影片。嘗試移除正在使用的版面會拋出 PptxEditException

在版面投影片上控制頁腳可見性

版面擁有自己的頁腳、投影片編號與日期時間佔位元。可使用 ILayoutSlide.getHeaderFooterManager 方法來控制單一版面的這些佔位元。例如,內容版面應顯示頁腳,但標題版面則不需要。

以下範例安全地選取一個版面,並將其頁腳元素設為可見:

import com.aspose.slides.*;

Presentation presentation = new Presentation("input.pptx");
try {
    ILayoutSlide layoutSlide = presentation.getLayoutSlides().getByType(SlideLayoutType.TitleAndObject);

    if (layoutSlide == null) {
        layoutSlide = presentation.getLayoutSlides().getByType(SlideLayoutType.Blank);
    }

    if (layoutSlide == null) {
        throw new IllegalStateException("The presentation does not contain a suitable layout slide.");
    }

    ILayoutSlideHeaderFooterManager headerFooterManager = layoutSlide.getHeaderFooterManager();
    headerFooterManager.setFooterVisibility(true);
    headerFooterManager.setSlideNumberVisibility(true);
    headerFooterManager.setDateTimeVisibility(true);
    headerFooterManager.setFooterText("Footer text");
    headerFooterManager.setDateTimeText("Date and time text");

    presentation.save("output-with-layout-footers.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

在母片及其子版面上控制頁腳可見性

若要在母片階層中套用一致的頁腳設定,請使用 IMasterSlide.getHeaderFooterManager 方法。IMasterSlideHeaderFooterManager 的傳播方法會作用於母片及其依賴的版面投影片與一般投影片;不會僅針對單一一般投影片。

import com.aspose.slides.*;

Presentation presentation = new Presentation("input.pptx");
try {
    IMasterSlideHeaderFooterManager headerFooterManager = presentation.getMasters().get_Item(0).getHeaderFooterManager();
    headerFooterManager.setFooterAndChildFootersVisibility(true);
    headerFooterManager.setSlideNumberAndChildSlideNumbersVisibility(true);
    headerFooterManager.setDateTimeAndChildDateTimesVisibility(true);
    headerFooterManager.setFooterAndChildFootersText("Footer text");
    headerFooterManager.setDateTimeAndChildDateTimesText("Date and time text");

    presentation.save("output-with-master-footers.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

常見問題

母片與版面投影片有何不同?

母片定義簡報的主題與共用格式。版面投影片屬於母片,定義一種可重複使用的佔位元排列。一般投影片使用這些版面,並儲存投影片特定的內容。

我可以將版面投影片從一個簡報複製到另一個嗎?

可以。使用 addClone 方法將副本加入目標集合。於簡報之間複製時,亦須確認來源版面所使用的字型、主題、影像與其他資源。

當我修改已在使用的版面時會發生什麼?

除非依賴投影片在本地覆寫受影響的格式或物件,否則它們會繼承版面的變更。因此,佔位元的幾何形狀與繼承樣式可能會同時在多張投影片上變化。編輯版面前,可使用 getDependingSlides 來識別受影響的投影片。

如果移除仍在使用的版面會發生什麼?

Aspose.Slides 會拋出 PptxEditException。請先重新指派依賴的投影片,或使用 removeUnusedLayoutSlides 只移除未被參考的版面。