Управление текстовыми абзацами PowerPoint в Java

Обзор

Aspose.Slides for Java представляет текст в виде иерархии текстовых рамок, абзацев и частей:

  • ITextFrame представляет контейнер текста в фигуре и предоставляет доступ к его коллекции абзацев.
  • IParagraph представляет один абзац в текстовой рамке и предоставляет доступ к его частям и форматированию уровня абзаца.
  • IPortion представляет фрагмент текста внутри абзаца. Каждая часть может иметь собственный текст и форматирование уровня символов.

Таким образом, абзац может содержать текст с различными шрифтами, цветами, размерами и другим форматированием, используя несколько частей.

Создание и форматирование абзацев

Создание абзацев с несколькими частями

Следующие шаги создают текстовую рамку с тремя абзацами, каждый из которых содержит три части:

  1. Создайте экземпляр класса Presentation.
  2. Получите нужный слайд по его индексу.
  3. Добавьте прямоугольную IAutoShape на слайд.
  4. Получите ITextFrame фигуры.
  5. Используйте абзац по умолчанию и добавьте еще два объекта IParagraph в текстовую рамку.
  6. Добавьте достаточное количество объектов IPortion для каждого абзаца, чтобы в них было по три части. Абзац по умолчанию уже содержит одну пустую часть.
  7. Установите текст каждой части.
  8. Примените форматирование уровня символов через IPortion.getPortionFormat.
  9. Сохраните изменённую презентацию.

Этот пример на Java реализует шаги:

import com.aspose.slides.*;
import java.awt.Color;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 50, 150, 300, 150);
    ITextFrame textFrame = shape.getTextFrame();

    IParagraph firstParagraph = textFrame.getParagraphs().get_Item(0);
    firstParagraph.getPortions().add(new Portion());
    firstParagraph.getPortions().add(new Portion());

    IParagraph secondParagraph = new Paragraph();
    secondParagraph.getPortions().add(new Portion());
    secondParagraph.getPortions().add(new Portion());
    secondParagraph.getPortions().add(new Portion());
    textFrame.getParagraphs().add(secondParagraph);

    IParagraph thirdParagraph = new Paragraph();
    thirdParagraph.getPortions().add(new Portion());
    thirdParagraph.getPortions().add(new Portion());
    thirdParagraph.getPortions().add(new Portion());
    textFrame.getParagraphs().add(thirdParagraph);

    int paragraphCount = textFrame.getParagraphs().getCount();
    for (int paragraphIndex = 0; paragraphIndex < paragraphCount; paragraphIndex++) {
        IParagraph paragraph = textFrame.getParagraphs().get_Item(paragraphIndex);
        int portionCount = paragraph.getPortions().getCount();
        for (int portionIndex = 0; portionIndex < portionCount; portionIndex++) {
            IPortion portion = paragraph.getPortions().get_Item(portionIndex);
            portion.setText("Portion " + (paragraphIndex + 1) + "." + (portionIndex + 1));

            if (portionIndex == 0) {
                portion.getPortionFormat().getFillFormat().setFillType(FillType.Solid);
                portion.getPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.RED);
                portion.getPortionFormat().setFontBold(NullableBool.True);
                portion.getPortionFormat().setFontHeight(15);
            } else if (portionIndex == 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 настройки списка определяются через IBulletFormat.

  1. Создайте экземпляр класса Presentation.
  2. Получите нужный слайд по его индексу.
  3. Добавьте IAutoShape на выбранный слайд.
  4. Получите ITextFrame фигуры.
  5. Удалите абзац по умолчанию из текстовой рамки.
  6. Создайте Paragraph для символической маркера.
  7. Установите IBulletFormat.setType в значение BulletType.Symbol и задайте символ маркера.
  8. Установите текст абзаца, отступ, цвет маркера и высоту маркера.
  9. Добавьте абзац в текстовую рамку.
  10. Создайте второй абзац и установите IBulletFormat.setType в значение BulletType.Numbered.
  11. Настройте стиль нумерованного маркера и добавьте абзац в текстовую рамку.
  12. Сохраните презентацию.

Этот пример на Java создаёт символический маркер и нумерованный маркер:

import com.aspose.slides.*;
import java.awt.Color;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getParagraphs().clear();

    Paragraph symbolParagraph = new Paragraph();
    symbolParagraph.setText("Welcome to Aspose.Slides");
    symbolParagraph.getParagraphFormat().getBullet().setType(BulletType.Symbol);
    symbolParagraph.getParagraphFormat().getBullet().setChar((char) 0x2022);
    symbolParagraph.getParagraphFormat().setIndent(25);
    symbolParagraph.getParagraphFormat().getBullet().getColor().setColorType(ColorType.RGB);
    symbolParagraph.getParagraphFormat().getBullet().getColor().setColor(Color.BLACK);
    symbolParagraph.getParagraphFormat().getBullet().setBulletHardColor(NullableBool.True);
    symbolParagraph.getParagraphFormat().getBullet().setHeight(100);
    textFrame.getParagraphs().add(symbolParagraph);

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

    presentation.save("bulleted_and_numbered_list.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Использование графических маркеров

Графические маркеры позволяют использовать собственное изображение вместо символа или числа.

  1. Создайте экземпляр класса Presentation.
  2. Получите нужный слайд по его индексу.
  3. Добавьте IAutoShape и получите его ITextFrame.
  4. Удалите абзац по умолчанию из текстовой рамки.
  5. Загрузите изображение маркера и добавьте его в коллекцию изображений презентации как IPPImage.
  6. Создайте Paragraph и задайте его текст.
  7. Установите IBulletFormat.setType в значение BulletType.Picture.
  8. Присвойте изображение через IBulletFormat.getPicture и задайте высоту маркера.
  9. Добавьте абзац в текстовую рамку.
  10. Сохраните изменённую презентацию.

Этот пример на Java создаёт графический маркер:

import com.aspose.slides.*;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);

    IImage bulletImage = Images.fromFile("bullets.png");
    IPPImage presentationImage;
    try {
        presentationImage = presentation.getImages().addImage(bulletImage);
    } finally {
        bulletImage.dispose();
    }

    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getParagraphs().clear();

    Paragraph paragraph = new Paragraph();
    paragraph.setText("Welcome to Aspose.Slides");
    paragraph.getParagraphFormat().getBullet().setType(BulletType.Picture);
    paragraph.getParagraphFormat().getBullet().getPicture().setImage(presentationImage);
    paragraph.getParagraphFormat().getBullet().setHeight(100);
    textFrame.getParagraphs().add(paragraph);

    presentation.save("picture_bullet.pptx", SaveFormat.Pptx);
    presentation.save("picture_bullet.ppt", SaveFormat.Ppt);
} finally {
    presentation.dispose();
}

Создание многоуровневого списка

Установите IParagraphFormat.setDepth для размещения абзацев на разных уровнях списка. Верхний уровень имеет глубину 0.

  1. Создайте Presentation и получите слайд.
  2. Добавьте IAutoShape и очистите абзац по умолчанию из его текстовой рамки.
  3. Создайте четыре абзаца и настройте их символы маркеров.
  4. Установите их значения IParagraphFormat.setDepth в 0, 1, 2 и 3.
  5. Добавьте абзацы в текстовую рамку и сохраните презентацию.

Этот пример на Java создаёт четырёхуровневый маркированный список:

import com.aspose.slides.*;
import java.awt.Color;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getParagraphs().clear();

    IParagraph firstParagraph = new Paragraph();
    firstParagraph.setText("Content");
    firstParagraph.getParagraphFormat().getBullet().setType(BulletType.Symbol);
    firstParagraph.getParagraphFormat().getBullet().setChar((char) 0x2022);
    firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid);
    firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK);
    firstParagraph.getParagraphFormat().setDepth((short) 0);

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

    IParagraph thirdParagraph = new Paragraph();
    thirdParagraph.setText("Third level");
    thirdParagraph.getParagraphFormat().getBullet().setType(BulletType.Symbol);
    thirdParagraph.getParagraphFormat().getBullet().setChar((char) 0x2022);
    thirdParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid);
    thirdParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK);
    thirdParagraph.getParagraphFormat().setDepth((short) 2);

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

    textFrame.getParagraphs().add(firstParagraph);
    textFrame.getParagraphs().add(secondParagraph);
    textFrame.getParagraphs().add(thirdParagraph);
    textFrame.getParagraphs().add(fourthParagraph);

    presentation.save("multilevel_list.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Начало нумерованных пунктов списка с пользовательскими значениями

Используйте IBulletFormat.setNumberedBulletStartWith для установки начального числа, отображаемого для нумерованного абзаца.

  1. Создайте Presentation и добавьте IAutoShape на слайд.
  2. Очистите абзац по умолчанию из текстовой рамки фигуры.
  3. Создайте три нумерованных абзаца.
  4. Установите IBulletFormat.setNumberedBulletStartWith в 2, 3 и 7 для соответствующих абзацев.
  5. Добавьте абзацы в текстовую рамку и сохраните презентацию.

Этот пример на Java задаёт пользовательский стартовый номер для каждого абзаца:

import com.aspose.slides.*;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getParagraphs().clear();

    Paragraph firstParagraph = new Paragraph();
    firstParagraph.setText("Start at 2");
    firstParagraph.getParagraphFormat().getBullet().setType(BulletType.Numbered);
    firstParagraph.getParagraphFormat().getBullet().setNumberedBulletStartWith((short) 2);
    textFrame.getParagraphs().add(firstParagraph);

    Paragraph secondParagraph = new Paragraph();
    secondParagraph.setText("Start at 3");
    secondParagraph.getParagraphFormat().getBullet().setType(BulletType.Numbered);
    secondParagraph.getParagraphFormat().getBullet().setNumberedBulletStartWith((short) 3);
    textFrame.getParagraphs().add(secondParagraph);

    Paragraph thirdParagraph = new Paragraph();
    thirdParagraph.setText("Start at 7");
    thirdParagraph.getParagraphFormat().getBullet().setType(BulletType.Numbered);
    thirdParagraph.getParagraphFormat().getBullet().setNumberedBulletStartWith((short) 7);
    textFrame.getParagraphs().add(thirdParagraph);

    presentation.save("custom_numbered_list.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Управление макетом абзаца и конечными свойствами

Установка отступа первой строки

Используйте IParagraphFormat.setIndent для управления отступом первой строки абзаца. Этот метод смещает только первую строку относительно левого поля абзаца. Положительное значение сдвигает первую строку вправо, остальные строки остаются выровненными по телу абзаца.

Используйте IParagraphFormat.setMarginLeft когда нужно сместить весь абзац. Используйте IParagraphFormat.setIndent когда нужно сместить только первую строку.

Ниже пример создаёт несколько абзацев и применяет различные значения IParagraphFormat.setIndent для демонстрации влияния отступа первой строки на макет абзаца.

  1. Создайте экземпляр класса Presentation.
  2. Получите целевой слайд.
  3. Добавьте прямоугольный IAutoShape на слайд.
  4. Получите ITextFrame фигуры и удалите абзац по умолчанию.
  5. Создайте несколько абзацев и задайте им разные значения IParagraphFormat.setIndent.
  6. Добавьте абзацы в текстовую рамку.
  7. Сохраните изменённую презентацию.

Этот код показывает, как установить отступ абзаца:

import com.aspose.slides.*;
import java.awt.Color;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);

    IAutoShape 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);

    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getTextFrameFormat().setAutofitType(TextAutofitType.Shape);
    textFrame.getParagraphs().clear();

    Paragraph firstParagraph = new Paragraph();
    firstParagraph.setText("No first-line indent. Wrapped lines start at the same position as the first line.");
    firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid);
    firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK);
    firstParagraph.getParagraphFormat().setMarginLeft(20f);
    firstParagraph.getParagraphFormat().setIndent(0f);

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

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

    textFrame.getParagraphs().add(firstParagraph);
    textFrame.getParagraphs().add(secondParagraph);
    textFrame.getParagraphs().add(thirdParagraph);

    presentation.save("paragraph_indent.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Результат:

Отступ первой строки в абзацах

Установка висячего отступа

Висячий отступ — это макет абзаца, при котором первая строка начинается слева от остальных строк. В Aspose.Slides этот эффект создаётся с помощью IParagraphFormat.setIndent. Передайте отрицательное значение, чтобы переместить первую строку влево относительно тела абзаца.

На практике IParagraphFormat.setMarginLeft определяет левую позицию тела абзаца, а IParagraphFormat.setIndent — позицию первой строки относительно этого поля. Чтобы создать висячий отступ, задайте положительное значение setMarginLeft и отрицательное значение setIndent.

Это форматирование полезно для библиографий, ссылок, записей в глоссариях и других абзацев, где строки‑переносы должны выравниваться под телом абзаца, а не под первым символом первой строки.

  1. Создайте экземпляр класса Presentation.
  2. Получите целевой слайд.
  3. Добавьте прямоугольный IAutoShape на слайд.
  4. Получите ITextFrame фигуры и удалите абзац по умолчанию.
  5. Создайте абзацы и задайте положительное значение IParagraphFormat.setMarginLeft для каждого абзаца.
  6. Передайте отрицательное значение IParagraphFormat.setIndent для создания эффекта висячего отступа.
  7. Добавьте абзацы в текстовую рамку.
  8. Сохраните изменённую презентацию.

Этот код показывает, как установить висячий отступ для абзаца:

import com.aspose.slides.*;
import java.awt.Color;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);

    IAutoShape 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);

    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getTextFrameFormat().setAutofitType(TextAutofitType.Shape);
    textFrame.getParagraphs().clear();

    Paragraph firstParagraph = new Paragraph();
    firstParagraph.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.");
    firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(FillType.Solid);
    firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(Color.BLACK);
    firstParagraph.getParagraphFormat().setMarginLeft(40f);
    firstParagraph.getParagraphFormat().setIndent(-20f);

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

    textFrame.getParagraphs().add(firstParagraph);
    textFrame.getParagraphs().add(secondParagraph);

    presentation.save("hanging_indent.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Результат:

Висячий отступ в абзацах

Установка свойств конечного знака абзаца

IParagraph.setEndParagraphPortionFormat управляет форматированием конечного знака абзаца. В следующем примере задаётся размер шрифта и латинский шрифт для конечного знака второго абзаца:

  1. Загрузите Presentation и получите слайд.
  2. Добавьте IAutoShape и очистите его абзац по умолчанию.
  3. Создайте два абзаца и добавьте в них части текста.
  4. Создайте PortionFormat для конечного знака второго абзаца.
  5. Установите IBasePortionFormat.setFontHeight и IBasePortionFormat.setLatinFont.
  6. Примените формат через IParagraph.setEndParagraphPortionFormat и сохраните презентацию.
import com.aspose.slides.*;

Presentation presentation = new Presentation("Test.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, 200, 250);
    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getParagraphs().clear();

    Paragraph firstParagraph = new Paragraph();
    firstParagraph.getPortions().add(new Portion("Sample text"));

    Paragraph secondParagraph = new Paragraph();
    secondParagraph.getPortions().add(new Portion("Sample text 2"));

    PortionFormat endParagraphFormat = new PortionFormat();
    endParagraphFormat.setFontHeight(48);
    endParagraphFormat.setLatinFont(new FontData("Times New Roman"));
    secondParagraph.setEndParagraphPortionFormat(endParagraphFormat);

    textFrame.getParagraphs().add(firstParagraph);
    textFrame.getParagraphs().add(secondParagraph);

    presentation.save("end_paragraph_format.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Подсчёт отрисованных строк

Для правил абзаца, влияющих на автоматический перенос и пунктуацию в конце строк, см. Control Line Breaking и Control Hanging Punctuation.

Используйте IParagraph.getLinesCount для подсчёта строк, занятых абзацем после раскладки текста, включая автоматический перенос. Это полезно при проверке длины текста и макета в шаблонах презентаций.

Абзац — один элемент в ITextFrame.getParagraphs, и он может занимать несколько отрисованных строк. Явный разрыв строки внутри абзаца принудительно создаёт новую строку без создания нового абзаца. Автоматический перенос создаёт строки на основе доступной ширины без вставки явных разрывов в текст. Поэтому подсчёт абзацев или символов разрыва строк не дает количества отрисованных строк.

В следующем примере создаётся текстовая фигура, подсчитываются её строки, затем ширина фигуры уменьшается, после чего текст заменяется на более короткую строку. Перенос включён, а автоподгонка отключена, чтобы ширина фигуры контролировала перенос без автоматического сжатия текста или изменения размеров фигуры. Размеры фигуры указаны в пунктах. Затем пример добавляет ещё один абзац и суммирует количество строк по всей текстовой рамке.

import com.aspose.slides.*;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);

    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 50, 50, 400, 200);
    ITextFrame textFrame = shape.getTextFrame();
    textFrame.getTextFrameFormat().setWrapText(NullableBool.True);
    textFrame.getTextFrameFormat().setAutofitType(TextAutofitType.None);

    IParagraph paragraph = textFrame.getParagraphs().get_Item(0);
    paragraph.getParagraphFormat().getDefaultPortionFormat().setFontHeight(20);
    paragraph.setText("This text demonstrates how automatic wrapping changes the number of rendered lines.");
    System.out.println("Original width: " + paragraph.getLinesCount());

    shape.setWidth(150);
    System.out.println("Narrower shape: " + paragraph.getLinesCount());

    paragraph.setText("Short text.");
    System.out.println("Shorter text: " + paragraph.getLinesCount());

    Paragraph secondParagraph = new Paragraph();
    secondParagraph.setText("Another paragraph.");
    secondParagraph.getParagraphFormat().getDefaultPortionFormat().setFontHeight(20);
    textFrame.getParagraphs().add(secondParagraph);

    int totalLineCount = 0;
    for (IParagraph currentParagraph : textFrame.getParagraphs()) {
        totalLineCount += currentParagraph.getLinesCount();
    }
    System.out.println("Total lines in the text frame: " + totalLineCount);
} finally {
    presentation.dispose();
}

С указанным текстом и размерами сужение фигуры увеличивает количество строк, а замена текста короткой строкой уменьшает его. Точные подсчёты могут различаться в зависимости от доступных шрифтов и их подстановки, размера шрифта, полей, отступов, переноса и настроек автоподгонки. При проверке шаблона используйте шрифты и параметры раскладки, предназначенные для целевой среды.

Само количество строк не определяет, выходит ли текст за границы контейнера. Важны доступная высота, высота строк, межабзацный и межстрочный интервалы, а также поведение автоподгонки; даже одна строка может превышать доступную ширину при отключённом переносе.

Импорт и экспорт содержимого абзацев

Импорт HTML‑текста в абзацы

Используйте ParagraphCollection.addFromHtml для преобразования HTML‑разметки в абзацы и части внутри текстовой рамки.

  1. Создайте экземпляр класса Presentation.
  2. Получите слайд и добавьте IAutoShape.
  3. Получите ITextFrame фигуры и очистите её абзац по умолчанию.
  4. Прочитайте исходный HTML‑файл.
  5. Передайте строку HTML в ParagraphCollection.addFromHtml.
  6. Сохраните изменённую презентацию.

Этот пример на Java импортирует HTML в текстовую рамку:

import com.aspose.slides.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    float shapeWidth = (float) presentation.getSlideSize().getSize().getWidth() - 20;
    float shapeHeight = (float) presentation.getSlideSize().getSize().getHeight() - 20;
    IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, shapeWidth, shapeHeight);
    shape.getFillFormat().setFillType(FillType.NoFill);
    shape.getTextFrame().getParagraphs().clear();

    try {
        byte[] htmlBytes = Files.readAllBytes(Paths.get("file.html"));
        String html = new String(htmlBytes, StandardCharsets.UTF_8);
        shape.getTextFrame().getParagraphs().addFromHtml(html);
        presentation.save("html_text.pptx", SaveFormat.Pptx);
    } catch (IOException exception) {
        System.out.println("The HTML file could not be read: " + exception.getMessage());
    }
} finally {
    presentation.dispose();
}

Экспорт текста абзаца в HTML

Используйте ParagraphCollection.exportToHtml для экспорта выбранного диапазона абзацев в виде HTML.

  1. Создайте экземпляр класса Presentation и загрузите нужную презентацию.
  2. Получите слайд и найдите IAutoShape, содержащий текст.
  3. Получите ITextFrame фигуры.
  4. Вызовите ParagraphCollection.exportToHtml с индексом начального абзаца и количеством абзацев для экспорта.
  5. Запишите возвращённую строку HTML в файл.

Этот пример на Java экспортирует все абзацы из первой текстовой фигуры:

import com.aspose.slides.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

Presentation presentation = new Presentation("ExportingHTMLText.pptx");
try {
    IShape shape = presentation.getSlides().get_Item(0).getShapes().get_Item(0);

    if (shape instanceof IAutoShape) {
        IAutoShape textShape = (IAutoShape) shape;
        ITextFrame textFrame = textShape.getTextFrame();
        if (textFrame != null) {
            IParagraphCollection paragraphs = textFrame.getParagraphs();
            String html = paragraphs.exportToHtml(0, paragraphs.getCount(), null);
            try {
                Files.write(Paths.get("paragraphs.html"), html.getBytes(StandardCharsets.UTF_8));
            } catch (IOException exception) {
                System.out.println("The HTML file could not be written: " + exception.getMessage());
            }
        } else {
            System.out.println("The first shape does not contain a text frame.");
        }
    } else {
        System.out.println("The first shape is not a text shape.");
    }
} finally {
    presentation.dispose();
}

Отображение абзаца в виде изображения

IParagraph.getImage отрисовывает отдельный абзац напрямую и возвращает IImage. Сохраните результат в файл или поток с помощью IImage.save. Отрисовывать всю содержащую фигуру или вручную обрезать bitmap не требуется.

IParagraph.getImage может вернуть null, если абзац не найден в своей родительской коллекции, не имеет корректных границ отрисовки или не может быть отрисован. Проверьте результат перед сохранением и освободите полученное изображение после использования.

Отображение абзаца в масштабе по умолчанию

Предположим, что у нас есть файл презентации sample.pptx с одним слайдом, где первая фигура — текстовое поле, содержащее три абзаца.

Текстовое поле с тремя абзацами

Следующий пример отрисовывает второй абзац в обычной текстовой фигуре в масштабе по умолчанию и сохраняет полученное изображение в формате PNG. Блок finally гарантирует корректное освобождение изображения.

import com.aspose.slides.*;

Presentation presentation = new Presentation("sample.pptx");
try {
    IShape shape = presentation.getSlides().get_Item(0).getShapes().get_Item(0);

    if (shape instanceof IAutoShape) {
        IAutoShape textShape = (IAutoShape) shape;
        ITextFrame textFrame = textShape.getTextFrame();
        if (textFrame != null && textFrame.getParagraphs().getCount() > 1) {
            IParagraph paragraph = textFrame.getParagraphs().get_Item(1);
            IImage paragraphImage = paragraph.getImage();

            if (paragraphImage != null) {
                try {
                    paragraphImage.save("paragraph.png", ImageFormat.Png);
                } finally {
                    paragraphImage.dispose();
                }
            } else {
                System.out.println("The paragraph could not be rendered.");
            }
        } else {
            System.out.println("The expected paragraph was not found.");
        }
    } else {
        System.out.println("The first shape is not a text shape.");
    }
} finally {
    presentation.dispose();
}

Результат:

Изображение абзаца

Отображение абзаца в ячейке таблицы с масштабированием

Используйте перегрузку IParagraph.getImage с параметрами float scaleX и float scaleY для задания горизонтального и вертикального коэффициентов масштабирования. Следующий пример создаёт таблицу, отрисовывает абзац в её первой ячейке с двойной шириной и высотой относительно значений по умолчанию и сохраняет результат в PNG‑изображении.

import com.aspose.slides.*;

float scaleX = 2f;
float scaleY = 2f;

Presentation presentation = new Presentation();
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    ITable table = slide.getShapes().addTable(50, 50, new double[] { 300 }, new double[] { 80 });
    IParagraph paragraph = table.get_Item(0, 0).getTextFrame().getParagraphs().get_Item(0);
    paragraph.setText("Text in a table cell");

    IImage paragraphImage = paragraph.getImage(scaleX, scaleY);
    if (paragraphImage != null) {
        try {
            paragraphImage.save("table_paragraph.png", ImageFormat.Png);
        } finally {
            paragraphImage.dispose();
        }
    } else {
        System.out.println("The paragraph could not be rendered.");
    }
} finally {
    presentation.dispose();
}

Коэффициент масштаба 1 сохраняет размер оси по умолчанию. Например, 2 для обеих осей создаёт изображение, ширина и высота которого примерно вдвое больше стандартных размеров, что даёт в четыре раза больше пикселей. Более большие коэффициенты обычно дают более чёткий текст для увеличения или вывода в высоком разрешении, но также увеличивают потребление памяти и размер файла. Коэффициенты ниже 1 дают более мелкие изображения с меньшей детализацией. Используйте одинаковые коэффициенты для сохранения пропорций абзаца; разные горизонтальный и вертикальный коэффициенты растягивают вывод независимо.

Отрисовка всей фигуры с помощью IShape.getImage остаётся полезной, когда требуется включить заливку, границу или другой визуальный контекст фигуры. Для изображения только абзаца используйте IParagraph.getImage.

FAQ

Можно ли полностью отключить перенос строк внутри текстовой рамки?

Да. Установите ITextFrameFormat.setWrapText, чтобы отключить перенос, и строки не будут разрываться по краям текстовой рамки.

Как получить точные границы конкретного абзаца на слайде?

Используйте IParagraph.getRect для получения ограничивающего прямоугольника абзаца. IPortion.getRect предоставляет границы отдельной части.

Где управляется выравнивание абзаца (по левому, правому краю, по центру или по ширине)?

IParagraphFormat.setAlignment — это настройка уровня абзаца и применяется ко всему абзацу независимо от форматирования отдельных частей.

Чтобы вертикально выровнять части с разными размерами шрифтов в каждой строке, см. Align Fonts Within a Line.

Можно ли задать язык проверки орфографии только для части абзаца?

Да. Установите IBasePortionFormat.setLanguageId для отдельных частей, чтобы один абзац мог содержать текст на нескольких языках.