管理 PowerPoint 文字段落(Python via Java)

概述

Aspose.Slides for Python via Java 將文字表示為文字框、段落和文字片段的層次結構:

  • TextFrame 表示形狀中的文字容器,並提供對其段落集合的存取。
  • Paragraph 表示文字框中的單一段落,並提供對其文字片段與段落層級格式的存取。
  • Portion 表示段落內的文字執行。每個文字片段可以擁有自己的文字與字元層級格式。

因此,段落可透過使用多個文字片段,包含不同字型、顏色、大小與其他格式的文字。

建立與格式化段落

在形狀的文字框中建立段落,並使用文字片段格式化個別的文字執行。本節說明如何在每個段落內結合多個文字片段,並套用不同的顏色、字型大小與樣式。

建立具有多個文字片段的段落

以下 Python 範例建立三個段落,每個段落在由 Paragraph.getPortions 回傳的集合中包含三個文字執行。它重複使用預設段落及其空白文字片段,然後加入其餘段落與文字片段。格式化透過 Portion.getPortionFormat 套用:每個段落的第一個文字片段為紅色、粗體、15 點;第二個為藍色、斜體、18 點。第三個文字片段保留其預設格式:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import FillType, NullableBool, Paragraph, Portion, Presentation, SaveFormat, ShapeType
from java.awt import Color

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 50, 150, 300, 150)
    text_frame = shape.getTextFrame()

    first_paragraph = text_frame.getParagraphs().get_Item(0)
    first_paragraph.getPortions().add(Portion())
    first_paragraph.getPortions().add(Portion())

    second_paragraph = Paragraph()
    second_paragraph.getPortions().add(Portion())
    second_paragraph.getPortions().add(Portion())
    second_paragraph.getPortions().add(Portion())
    text_frame.getParagraphs().add(second_paragraph)

    third_paragraph = Paragraph()
    third_paragraph.getPortions().add(Portion())
    third_paragraph.getPortions().add(Portion())
    third_paragraph.getPortions().add(Portion())
    text_frame.getParagraphs().add(third_paragraph)

    paragraph_count = text_frame.getParagraphs().getCount()
    for paragraph_index in range(paragraph_count):
        paragraph = text_frame.getParagraphs().get_Item(paragraph_index)
        portion_count = paragraph.getPortions().getCount()
        for portion_index in range(portion_count):
            portion = paragraph.getPortions().get_Item(portion_index)
            portion.setText(f"Portion {paragraph_index + 1}.{portion_index + 1}")

            if portion_index == 0:
                portion.getPortionFormat().getFillFormat().setFillType(FillType.Solid)
                portion.getPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.RED)
                portion.getPortionFormat().setFontBold(NullableBool.True_)
                portion.getPortionFormat().setFontHeight(15)
            elif portion_index == 1:
                portion.getPortionFormat().getFillFormat().setFillType(FillType.Solid)
                portion.getPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLUE)
                portion.getPortionFormat().setFontItalic(NullableBool.True_)
                portion.getPortionFormat().setFontHeight(18)

    presentation.save("paragraphs_with_portions.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

建立項目符號與編號清單

將段落文字組織成符號、編號或自訂圖像的清單。本節範例涵蓋項目符號格式、多層清單與自訂起始編號。

建立項目符號或編號清單

項目符號與編號使相關項目更易於掃描。在 Aspose.Slides 中,清單設定透過 BulletFormat 定義。

此 Python 範例在同一文字框中加入符號項目符號與編號項目。 BulletFormat.setType 選擇項目符號類型, BulletFormat.setChar 提供符號, BulletFormat.setNumberedBulletStyle 選擇編號樣式。兩個項目均使用黑色項目符號,高度為 100%,段落縮排為 25 點:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import BulletType, ColorType, NullableBool, NumberedBulletStyle, Paragraph, Presentation, SaveFormat, ShapeType
from java.awt import Color

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200)
    text_frame = shape.getTextFrame()
    text_frame.getParagraphs().clear()

    symbol_paragraph = Paragraph()
    symbol_paragraph.setText("Welcome to Aspose.Slides")
    symbol_paragraph.getParagraphFormat().getBullet().setType(BulletType.Symbol)
    symbol_paragraph.getParagraphFormat().getBullet().setChar("•")
    symbol_paragraph.getParagraphFormat().setIndent(25)
    symbol_paragraph.getParagraphFormat().getBullet().getColor().setColorType(ColorType.RGB)
    symbol_paragraph.getParagraphFormat().getBullet().getColor().setColor(Color.BLACK)
    symbol_paragraph.getParagraphFormat().getBullet().setBulletHardColor(NullableBool.True_)
    symbol_paragraph.getParagraphFormat().getBullet().setHeight(100)
    text_frame.getParagraphs().add(symbol_paragraph)

    numbered_paragraph = Paragraph()
    numbered_paragraph.setText("This is a numbered item")
    numbered_paragraph.getParagraphFormat().getBullet().setType(BulletType.Numbered)
    numbered_paragraph.getParagraphFormat().getBullet().setNumberedBulletStyle(NumberedBulletStyle.BulletCircleNumWDBlackPlain)
    numbered_paragraph.getParagraphFormat().setIndent(25)
    numbered_paragraph.getParagraphFormat().getBullet().getColor().setColorType(ColorType.RGB)
    numbered_paragraph.getParagraphFormat().getBullet().getColor().setColor(Color.BLACK)
    numbered_paragraph.getParagraphFormat().getBullet().setBulletHardColor(NullableBool.True_)
    numbered_paragraph.getParagraphFormat().getBullet().setHeight(100)
    text_frame.getParagraphs().add(numbered_paragraph)

    presentation.save("bulleted_and_numbered_list.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

使用圖片項目符號

圖片項目符號允許使用自訂圖像取代符號或編號。

此 Python 範例將圖像加入簡報的圖像集合,作為 PPImage,並將其用作段落項目符號。它呼叫 BulletFormat.setType 以使用圖片項目符號,並透過 BulletFormat.getPicture 指派圖像。BulletFormat.setHeight 設為 100% 以相對段落文字調整項目符號大小:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import BulletType, Images, Paragraph, Presentation, SaveFormat, ShapeType

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    bullet_image = Images.fromFile("bullets.png")
    try:
        presentation_image = presentation.getImages().addImage(bullet_image)
    finally:
        bullet_image.dispose()

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200)
    text_frame = shape.getTextFrame()
    text_frame.getParagraphs().clear()

    paragraph = Paragraph()
    paragraph.setText("Welcome to Aspose.Slides")
    paragraph.getParagraphFormat().getBullet().setType(BulletType.Picture)
    paragraph.getParagraphFormat().getBullet().getPicture().setImage(presentation_image)
    paragraph.getParagraphFormat().getBullet().setHeight(100)
    text_frame.getParagraphs().add(paragraph)

    presentation.save("picture_bullet.pptx", SaveFormat.Pptx)
    presentation.save("picture_bullet.ppt", SaveFormat.Ppt)
finally:
    presentation.dispose()

建立多層清單

將 ParagraphFormat.setDepth 設為不同深度,以在清單中放置不同層級的段落。最高層的深度為 0。

此 Python 範例將 ParagraphFormat.setDepth 值從 0 設為 3,給四個段落,在同一文字框內建立階層。每個段落使用符號項目符號,透過 BulletFormat.setChar 在圓形項目符號與連字號之間交替,以區別相鄰層級:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import BulletType, FillType, Paragraph, Presentation, SaveFormat, ShapeType
from java.awt import Color

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200)
    text_frame = shape.getTextFrame()
    text_frame.getParagraphs().clear()

    first_paragraph = Paragraph()
    first_paragraph.setText("Content")
    first_paragraph.getParagraphFormat().getBullet().setType(BulletType.Symbol)
    first_paragraph.getParagraphFormat().getBullet().setChar("•")
    first_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    first_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    first_paragraph.getParagraphFormat().setDepth(0)

    second_paragraph = Paragraph()
    second_paragraph.setText("Second level")
    second_paragraph.getParagraphFormat().getBullet().setType(BulletType.Symbol)
    second_paragraph.getParagraphFormat().getBullet().setChar('-')
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    second_paragraph.getParagraphFormat().setDepth(1)

    third_paragraph = Paragraph()
    third_paragraph.setText("Third level")
    third_paragraph.getParagraphFormat().getBullet().setType(BulletType.Symbol)
    third_paragraph.getParagraphFormat().getBullet().setChar("•")
    third_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    third_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    third_paragraph.getParagraphFormat().setDepth(2)

    fourth_paragraph = Paragraph()
    fourth_paragraph.setText("Fourth level")
    fourth_paragraph.getParagraphFormat().getBullet().setType(BulletType.Symbol)
    fourth_paragraph.getParagraphFormat().getBullet().setChar('-')
    fourth_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    fourth_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    fourth_paragraph.getParagraphFormat().setDepth(3)

    text_frame.getParagraphs().add(first_paragraph)
    text_frame.getParagraphs().add(second_paragraph)
    text_frame.getParagraphs().add(third_paragraph)
    text_frame.getParagraphs().add(fourth_paragraph)

    presentation.save("multilevel_list.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

以自訂值開始編號清單項目

使用 BulletFormat.setNumberedBulletStartWith 來設定編號段落的起始數字。

此 Python 範例將 BulletFormat.setType 設為編號,並為三個段落分別指定 BulletFormat.setNumberedBulletStartWith 為 2、3、7。每個段落的起始值獨立設定,可讓顯示的編號跳過指定數值:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import BulletType, Paragraph, Presentation, SaveFormat, ShapeType

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200)
    text_frame = shape.getTextFrame()
    text_frame.getParagraphs().clear()

    first_paragraph = Paragraph()
    first_paragraph.setText("Start at 2")
    first_paragraph.getParagraphFormat().getBullet().setType(BulletType.Numbered)
    first_paragraph.getParagraphFormat().getBullet().setNumberedBulletStartWith(2)

    text_frame.getParagraphs().add(first_paragraph)

    second_paragraph = Paragraph()
    second_paragraph.setText("Start at 3")
    second_paragraph.getParagraphFormat().getBullet().setType(BulletType.Numbered)
    second_paragraph.getParagraphFormat().getBullet().setNumberedBulletStartWith(3)
    text_frame.getParagraphs().add(second_paragraph)

    third_paragraph = Paragraph()
    third_paragraph.setText("Start at 7")
    third_paragraph.getParagraphFormat().getBullet().setType(BulletType.Numbered)
    third_paragraph.getParagraphFormat().getBullet().setNumberedBulletStartWith(7)
    text_frame.getParagraphs().add(third_paragraph)

    presentation.save("custom_numbered_list.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

控制段落版面配置與結尾屬性

調整段落邊距與縮排,以控制首行與換行行的位置。您亦可將段落結束標記的格式獨立於可見文字片段。

設定首行縮排

使用 ParagraphFormat.setIndent 方法控制段落的首行縮排。此設定僅移動首行相對於段落左邊距的距離。正值會將首行向右移動,而其餘行則保持與段落正文對齊。

需要移動整個段落時,請使用 ParagraphFormat.setMarginLeft。若只需移動首行,請使用 ParagraphFormat.setIndent。

以下範例將三個段落的 ParagraphFormat.setMarginLeft 設為 20 點,並將 ParagraphFormat.setIndent 設為 0、20、40 點。首行的起始位置逐漸向右偏移,而換行行則保留相同的左邊距:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import FillType, Paragraph, Presentation, SaveFormat, ShapeType, TextAutofitType
from java.awt import Color

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 50, 50, 420, 220)
    shape.getFillFormat().setFillType(FillType.NoFill)
    shape.getLineFormat().getFillFormat().setFillType(FillType.Solid)
    shape.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.GRAY)

    text_frame = shape.getTextFrame()
    text_frame.getTextFrameFormat().setAutofitType(TextAutofitType.Shape)
    text_frame.getParagraphs().clear()

    first_paragraph = Paragraph()
    first_paragraph.setText("No first-line indent. Wrapped lines start at the same position as the first line.")
    first_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    first_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    first_paragraph.getParagraphFormat().setMarginLeft(20.0)
    first_paragraph.getParagraphFormat().setIndent(0.0)

    second_paragraph = Paragraph()
    second_paragraph.setText("First-line indent of 20 points. The first line moves to the right, while wrapped lines remain aligned to the paragraph body.")
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().setFillType(FillType.Solid)
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    second_paragraph.getParagraphFormat().setMarginLeft(20.0)
    second_paragraph.getParagraphFormat().setIndent(20.0)

    third_paragraph = Paragraph()
    third_paragraph.setText("First-line indent of 40 points. This paragraph shows a larger first-line offset to make the effect easier to see.")
    third_paragraph.getParagraphFormat().getDefaultPortionFormat().setFillType(FillType.Solid)
    third_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    third_paragraph.getParagraphFormat().setMarginLeft(20.0)
    third_paragraph.getParagraphFormat().setIndent(40.0)

    text_frame.getParagraphs().add(first_paragraph)
    text_frame.getParagraphs().add(second_paragraph)
    text_frame.getParagraphs().add(third_paragraph)

    presentation.save("paragraph_indent.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

結果:

段落的首行縮排

設定掛行縮排

掛行縮排是一種段落版面配置,首行會比其餘行更靠左。在 Aspose.Slides 中,您可使用 ParagraphFormat.setIndent 屬性實現此效果。將 Indent 設為負值,即可使首行相對於段落正文向左移動。

實務上,ParagraphFormat.setMarginLeft 定義段落正文的左側位置,而 ParagraphFormat.setIndent 定義首行相對於該左側位置的偏移。若要建立掛行縮排,請將正的 MarginLeft 與負的 Indent 同時設定。

此格式常用於參考文獻、引用、詞彙表條目等段落,因為換行行需要對齊在段落正文之下,而非對齊在首行的第一個字元之下。

以下 Python 範例將 ParagraphFormat.setMarginLeft 分別設為 40 與 60 點,並將 ParagraphFormat.setIndent 設為 -20 與 -30 點。每個段落的首行均比換行行更靠左;第二段落的掛行縮排更深:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import FillType, Paragraph, Presentation, SaveFormat, ShapeType, TextAutofitType
from java.awt import Color

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 50, 50, 420, 220)
    shape.getFillFormat().setFillType(FillType.NoFill)
    shape.getLineFormat().getFillFormat().setFillType(FillType.Solid)
    shape.getLineFormat().getFillFormat().getSolidFillColor().setColor(Color.GRAY)

    text_frame = shape.getTextFrame()
    text_frame.getTextFrameFormat().setAutofitType(TextAutofitType.Shape)
    text_frame.getParagraphs().clear()

    first_paragraph = Paragraph()
    first_paragraph.setText("A hanging indent is created by combining a positive left margin with a negative indent. The first line starts to the left, while wrapped lines align with the paragraph body.")
    first_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    first_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    first_paragraph.getParagraphFormat().setMarginLeft(40.0)
    first_paragraph.getParagraphFormat().setIndent(-20.0)

    second_paragraph = Paragraph()
    second_paragraph.setText("This second example uses a deeper hanging indent so the difference between the first line and the wrapped lines is easier to compare.")
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid)
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK)
    second_paragraph.getParagraphFormat().setMarginLeft(60.0)
    second_paragraph.getParagraphFormat().setIndent(-30.0)

    text_frame.getParagraphs().add(first_paragraph)
    text_frame.getParagraphs().add(second_paragraph)

    presentation.save("hanging_indent.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

結果:

段落的掛行縮排

設定段落結束執行屬性

Paragraph.setEndParagraphPortionFormat 方法控制段落結束標記的格式。以下範例建立一個 PortionFormat ,其 BasePortionFormat.setFontHeight 設為 48 點,且 BasePortionFormat.setLatinFont 設為 Times New Roman。將此格式指派給第二段落的結束標記,保持可見文字片段不變:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import FontData, Paragraph, Portion, PortionFormat, Presentation, SaveFormat, ShapeType

presentation = Presentation("Test.pptx")
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, 200, 250)
    text_frame = shape.getTextFrame()
    text_frame.getParagraphs().clear()

    first_paragraph = Paragraph()
    first_portion = Portion("Sample text")
    first_paragraph.getPortions().add(first_portion)

    second_paragraph = Paragraph()
    second_portion = Portion("Sample text 2")
    second_paragraph.getPortions().add(second_portion)

    end_paragraph_format = PortionFormat()
    end_paragraph_format.setFontHeight(48)
    latin_font = FontData("Times New Roman")
    end_paragraph_format.setLatinFont(latin_font)
    second_paragraph.setEndParagraphPortionFormat(end_paragraph_format)

    text_frame.getParagraphs().add(first_paragraph)
    text_frame.getParagraphs().add(second_paragraph)

    presentation.save("end_paragraph_format.pptx", SaveFormat.Pptx)
finally:
    presentation.dispose()

計算已渲染的行數

有關影響自動換行與行尾標點的段落規則,請參閱 Control Line Breaking 與 Control Hanging Punctuation。

使用 Paragraph.getLinesCount 取得段落在文字排版後佔用的行數,包含自動換行。這在檢查投影片範本中的文字長度與版面配置時很有用。

段落是 TextFrame.getParagraphs 中的一個項目,可能佔用多行已渲染的行數。段落內的顯式換行會強制換行,卻不會產生新段落。自動換行則根據可用寬度產生新行,且不會在文字中插入換行字元。因此,僅統計段落或換行字元並不能得到已渲染的行數。

以下範例建立一個文字形狀,計算其行數,收縮形狀寬度,然後將文字替換為較短的字串。範例使用 TextFrameFormat.setWrapText 啟用換行,並使用 TextFrameFormat.setAutofitType 停用自動適應,讓形狀寬度控制換行而不會自動縮小文字或調整形狀大小。每次測量皆使用 Paragraph.getLinesCount。形狀尺寸以點為單位。最後,範例再加入一個段落,並將整個文字框的行數相加。

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import NullableBool, Paragraph, Presentation, ShapeType, TextAutofitType

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 50, 50, 400, 200)
    text_frame = shape.getTextFrame()
    text_frame.getTextFrameFormat().setWrapText(NullableBool.True_)
    text_frame.getTextFrameFormat().setAutofitType(TextAutofitType.None_)

    paragraph = text_frame.getParagraphs().get_Item(0)
    paragraph.getParagraphFormat().getDefaultPortionFormat().setFontHeight(20)
    paragraph.setText("This text demonstrates how automatic wrapping changes the number of rendered lines.")
    print("Original width:", paragraph.getLinesCount())

    shape.setWidth(150)
    print("Narrower shape:", paragraph.getLinesCount())

    paragraph.setText("Short text.")
    print("Shorter text:", paragraph.getLinesCount())

    second_paragraph = Paragraph()
    second_paragraph.setText("Another paragraph.")
    second_paragraph.getParagraphFormat().getDefaultPortionFormat().setFontHeight(20)
    text_frame.getParagraphs().add(second_paragraph)

    total_line_count = 0
    for current_paragraph in text_frame.getParagraphs():
        total_line_count += current_paragraph.getLinesCount()
    print("Total lines in the text frame:", total_line_count)
finally:
    presentation.dispose()

使用此文字與這些尺寸時,收縮形狀會增加行數,而將文字換成短字串會減少行數。精確的行數會因字型可用性與替代、字型大小、邊距、縮排、換行與自動適應設定而異;請使用目標環境的字型與版面設定來檢查範本。

僅依行數無法判斷文字是否溢出容器。可用高度、行高、段落與行間距以及自動適應行為也很重要;即使只有單行文字,若關閉換行,仍可能超出可用寬度。

匯入與匯出段落內容

使用 HTML 將文字帶入投影片,或將現有段落匯出以供外部使用。本節亦說明如何將個別段落渲染為影像,包括表格儲存格內的段落。

將 HTML 文字匯入段落

使用 ParagraphCollection.addFromHtml 將 HTML 標記轉換為文字框中的段落與文字片段。

此 Python 範例從檔案讀取 HTML,並將標記傳遞給 ParagraphCollection.addFromHtml。它會清除文字框的預設段落,使框僅保留匯入的內容。矩形形狀在投影片的每一側留下 10 點的邊距:

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import FillType, Presentation, SaveFormat, ShapeType
from pathlib import Path

presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    shape_width = presentation.getSlideSize().getSize().getWidth() - 20
    shape_height = presentation.getSlideSize().getSize().getHeight() - 20

    shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, shape_width, shape_height)
    shape.getFillFormat().setFillType(FillType.NoFill)
    shape.getTextFrame().getParagraphs().clear()

    try:
        html = Path("file.html").read_text(encoding="utf-8")
        shape.getTextFrame().getParagraphs().addFromHtml(html)

        presentation.save("html_text.pptx", SaveFormat.Pptx)
    except OSError as exception:
        print("The HTML file could not be read: " + str(exception))
finally:
    presentation.dispose()

將段落文字匯出為 HTML

使用 ParagraphCollection.exportToHtml 將選定範圍的段落匯出為 HTML。當在網站上重新使用投影片文字時,您可能希望保留本地強調效果,同時不帶入投影片的字型、大小或文字方塊樣式。透過設定 TextToHtmlConversionOptions.setTextInheritanceLimit 來控制匯出器遵循格式繼承的深度。

下載 範例投影片 並將其放置於應用程式的工作目錄。其第一張投影片包含一個文字形狀,文字為「Inherited text; explicit red 18pt」。輸入特意使用了多層格式:

  • 投影片的預設文字樣式提供 Calibri 字型與 28 pt 大小。
  • 文字框的第一層文字樣式提供藍色文字與斜體。
  • 段落明確設定為粗體。
  • 第二個文字片段「explicit red 18pt」明確設定為紅色文字與 18 pt 大小。

以下完整範例將相同段落各匯出三次。它將 TextToHtmlConversionOptions 傳遞給匯出方法,並將每個結果寫入獨立的 UTF-8 HTML 檔案:

import jpype
import asposeslides
from pathlib import Path

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import AutoShape, Presentation, TextInheritanceLimit, TextToHtmlConversionOptions

presentation = Presentation("text-inheritance.pptx")
try:
    shape = presentation.getSlides().get_Item(0).getShapes().get_Item(0)

    if isinstance(shape, AutoShape):
        text_frame = shape.getTextFrame()
        if text_frame is not None:
            paragraphs = text_frame.getParagraphs()
            
            modes = [TextInheritanceLimit.All, TextInheritanceLimit.TextBox, TextInheritanceLimit.ParagraphOnly]
            file_names = ["All.html", "TextBox.html", "ParagraphOnly.html"]

            for mode, file_name in zip(modes, file_names):
                options = TextToHtmlConversionOptions()
                options.setTextInheritanceLimit(mode)

                html = paragraphs.exportToHtml(0, paragraphs.getCount(), options)
                try:
                    Path(file_name).write_text(str(html), encoding="utf-8")
                except OSError as exception:
                    print("The HTML file could not be written: " + str(exception))
        else:
            print("The first shape does not contain a text frame.")
    else:
        print("The first shape is not a text shape.")
finally:
    presentation.dispose()

產生的 HTML 包含第一段片段「Inherited text; 」的以下 CSS。表格列出相關宣告;其他產生的屬性為了清晰起見已省略。

輸出 第一段的相關 CSS 外觀
All.html font-family:'Calibri'; font-size:28pt; color:#0000ff; font-style:italic; font-weight:bold 藍色、粗體、斜體文字,字型為 Calibri、28 pt(若該字型可用)。
TextBox.html color:#0000ff; font-style:italic; font-weight:bold 藍色、粗體、斜體文字;字型與大小由周圍頁面或瀏覽器提供。
ParagraphOnly.html font-weight:bold 粗體文字;字型、大小、顏色與斜體樣式由周圍頁面或瀏覽器提供。

第二段保留 color:#ff0000、font-size:18pt 與 font-weight:bold 在所有三個輸出中。它在 All 與 TextBox 中仍保留斜體,但在 ParagraphOnly 中不保留。限制繼承因此不會移除明確指派給段落或文字片段的格式。

在相同瀏覽器中開啟檔案以比較它們。於受限模式下,省略的 CSS 屬性會由目標頁面的樣式或瀏覽器預設解析,因此最終外觀取決於 HTML 使用的環境。

將段落渲染為影像

Paragraph.getImage 直接渲染單一段落並傳回影像物件。使用其 save 方法將結果儲存為檔案或串流。您不需要渲染包含的形狀或手動裁切位圖。

如果段落無法在其父集合中找到、沒有有效的渲染邊界,或無法渲染,Paragraph.getImage 可能會傳回 None。使用前請檢查結果,使用後請釋放回傳的影像。

以預設比例渲染段落

此範例使用一份投影片,第一個形狀為包含三個段落的文字方塊。

包含三個段落的文字方塊

以下範例選取索引為 1 的第二段,並在未提供比例參數的情況下呼叫 Paragraph.getImage。它會先檢查形狀是否包含所需段落,以及渲染是否回傳影像,然後呼叫其 save 方法以 PNG 格式儲存。finally 區塊在使用完畢後釋放影像。

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import AutoShape, ImageFormat, Presentation

presentation = Presentation("sample.pptx")
try:
    shape = presentation.getSlides().get_Item(0).getShapes().get_Item(0)

    if isinstance(shape, AutoShape):
        text_shape = shape
        text_frame = text_shape.getTextFrame()
        if text_frame is not None and text_frame.getParagraphs().getCount() > 1:
            paragraph = text_frame.getParagraphs().get_Item(1)
            paragraph_image = paragraph.getImage()

            if paragraph_image is not None:
                try:
                    paragraph_image.save("paragraph.png", ImageFormat.Png)
                finally:
                    paragraph_image.dispose()
            else:
                print("The paragraph could not be rendered.")
        else:
            print("The expected paragraph was not found.")
    else:
        print("The first shape is not a text shape.")
finally:
    presentation.dispose()

結果:

段落影像

在表格儲存格中以比例渲染段落

使用接受 scale_x 與 scale_y 參數的 Paragraph.getImage 重載,以設定水平與垂直比例因子。以下範例建立表格,在第一個儲存格中將段落以預設寬高的兩倍渲染,並將結果儲存為 PNG 影像。

import jpype
import asposeslides

if not jpype.isJVMStarted():
    jpype.startJVM()

from asposeslides.api import ImageFormat, Presentation

scale_x = 2.0
scale_y = 2.0
presentation = Presentation()
try:
    slide = presentation.getSlides().get_Item(0)

    table = slide.getShapes().addTable(50, 50, [300.0], [80.0])

    paragraph = table.get_Item(0, 0).getTextFrame().getParagraphs().get_Item(0)
    paragraph.setText("Text in a table cell")

    paragraph_image = paragraph.getImage(scale_x, scale_y)

    if paragraph_image is not None:
        try:
            paragraph_image.save("table_paragraph.png", ImageFormat.Png)
        finally:
            paragraph_image.dispose()
    else:
        print("The paragraph could not be rendered.")
finally:
    presentation.dispose()

比例因子 1 保持該軸的預設像素尺寸。例如,兩個因子皆為 2 時,產生的影像寬度與高度約為預設尺寸的兩倍,像素數量為四倍。較大的因子通常可在放大或高解析度輸出時產生更清晰的文字,但也會增加記憶體使用與檔案大小。低於 1 的因子會產生較小且細節較少的影像。使用相同的因子可保留段落的長寬比;不同的水平與垂直因子則會分別拉伸輸出。

在需要包含形狀填色、邊框或其他視覺上下文的情況下,使用 Shape.getImage 來渲染整個形狀仍然實用。若僅需段落影像,請使用 Paragraph.getImage。

FAQ

我可以完全停用文字框內的換行嗎?

可以。將 TextFrameFormat.setWrapText 設為停用,即可關閉換行,使行不會在文字框邊緣斷開。

我如何取得特定段落在投影片上的精確邊界?

使用 Paragraph.getRect 取得段落的邊界矩形。Portion.getRect 則提供單一文字片段的邊界。

段落對齊(左、右、置中或左右對齊)在哪裡控制?

ParagraphFormat.setAlignment 為段落層級設定,會套用到整個段落,與單一文字片段的格式無關。

若要在每行內垂直對齊不同字型大小的文字片段,請參閱 Align Fonts Within a Line。

我可以為段落的部分文字設定校對語言嗎?

可以。對個別文字片段設定 BasePortionFormat.setLanguageId,即可讓同一段落內包含多種語言的文字。