Управление текстовыми абзацами PowerPoint в Java
Обзор
Aspose.Slides for Java представляет текст как иерархию текстовых рамок, абзацев и частей:
- ITextFrame представляет контейнер текста в фигуре и предоставляет доступ к её коллекции абзацев.
- IParagraph представляет один абзац в текстовой рамке и предоставляет доступ к его частям и форматированию уровня абзаца.
- IPortion представляет фрагмент текста внутри абзаца. Каждая часть может иметь собственный текст и форматирование символов.
Таким образом, абзац может содержать текст с разными шрифтами, цветами, размерами и другим форматированием, используя несколько частей.
Создание и форматирование абзацев
Создавайте абзацы в текстовой рамке фигуры и используйте части для форматирования отдельных фрагментов текста. В этом разделе показано, как сочетать несколько частей внутри каждого абзаца и применять разные цвета, размеры шрифтов и стили.
Создание абзацев с несколькими частями
Следующий пример на Java создаёт три абзаца, каждый из которых содержит три фрагмента текста в коллекции, возвращаемой IParagraph.getPortions . Он переисполняет абзац по умолчанию и его пустую часть, затем добавляет остальные абзацы и части. Форматирование применяется через IPortion.getPortionFormat: первая часть в каждом абзаце красная, полужирная и размером 15 pt; вторая — синяя, курсивная и размером 18 pt. Третья часть сохраняет форматирование по умолчанию:
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.
Этот пример на Java добавляет символический маркер и нумерованный элемент в одну и ту же текстовую рамку. IBulletFormat.setType выбирает тип маркера, IBulletFormat.setChar задаёт символ, а IBulletFormat.setNumberedBulletStyle выбирает стиль нумерации. Оба пункта используют чёрные маркеры высотой 100 % и отступ абзаца 25 pt:
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();
}
Использование изображений в качестве маркеров
Изображения‑маркеры позволяют использовать пользовательское изображение вместо символа или цифры.
Этот пример на Java добавляет изображение в коллекцию изображений презентации как IPPImage и использует его в качестве маркера абзаца. Он вызывает IBulletFormat.setType для выбора маркера‑изображения и назначает изображение через IBulletFormat.getPicture. IBulletFormat.setHeight установлен на 100 % для масштабирования маркера относительно текста абзаца:
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.
Этот пример на Java задаёт значения IParagraphFormat.setDepth от 0 до 3 четырём абзацам, создавая иерархию в одной текстовой рамке. Каждый абзац использует символический маркер, а IBulletFormat.setChar чередует круглой маркер и дефис для различения соседних уровней:
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 для задания начального числа, отображаемого для нумерованного абзаца.
Этот пример на Java устанавливает IBulletFormat.setType для использования нумерации в трёх абзацах и задаёт значения IBulletFormat.setNumberedBulletStartWith — 2, 3 и 7. Начальное значение задаётся отдельно для каждого абзаца, позволяя пропускать номера:
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.setMarginLeft — 20 pt и значения IParagraphFormat.setIndent — 0, 20 и 40 pt. Первые линии начинаются с постепенно увеличивающихся смещений, а перенесённые строки сохраняют одинаковое левое поле:
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. Установите Indent в отрицательное значение, чтобы переместить первую строку влево относительно тела абзаца.
На практике IParagraphFormat.setMarginLeft задаёт левую позицию тела абзаца, а IParagraphFormat.setIndent — позицию первой строки относительно этого поля. Чтобы создать висячий отступ, задайте положительное значение MarginLeft и отрицательное значение Indent.
Это форматирование полезно для библиографий, ссылок, глоссариев и других абзацев, где перенесённые строки должны выравниваться под телом абзаца, а не под первым символом первой строки.
В следующем примере на Java комбинируются значения IParagraphFormat.setMarginLeft — 40 и 60 pt с значениями IParagraphFormat.setIndent — -20 и -30 pt. В каждом абзаце первая строка начинается левее перенесённых строк; во втором абзаце висячий отступ глубже:
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 управляет форматированием знака конца абзаца. В следующем примере создаётся PortionFormat с IBasePortionFormat.setFontHeight = 48 pt и IBasePortionFormat.setLatinFont = Times New Roman. Этот формат назначается знаку конца второго абзаца, не изменяя видимые текстовые части:
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, и он может занимать несколько отрисованных строк. Явный разрыв строки внутри абзаца принуждает к новой строке без создания нового абзаца. Автоматический перенос создаёт строки на основе доступной ширины без вставки явных разрывов в текст. Поэтому подсчёт абзацев или символов разрыва строки не даёт количества отрисованных строк.
В следующем примере создаётся текстовая фигура, вычисляется количество её строк, затем фигура сужается, после чего текст заменяется более короткой строкой. Пример включает перенос с помощью ITextFrameFormat.setWrapText и отключает автоподгонку с помощью ITextFrameFormat.setAutofitType, чтобы ширина фигуры контролировала перенос без автоматического уменьшения текста или изменения размеров фигуры. Каждое измерение использует IParagraph.getLinesCount. Размеры фигуры указаны в пунктах. В конце пример добавляет ещё один абзац и суммирует количество строк по всей текстовой рамке:
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 для импорта текста в презентацию или экспорта существующих абзацев для внешнего использования. В этом разделе также показано, как отрисовывать отдельные абзацы как изображения, включая абзацы в ячейках таблиц.
Импорт HTML‑текста в абзацы
Используйте ParagraphCollection.addFromHtml для преобразования разметки HTML в абзацы и части в текстовой рамке.
Этот пример на Java читает HTML из файла и передаёт разметку в ParagraphCollection.addFromHtml. Он очищает абзац по умолчанию в текстовой рамке, чтобы она содержала только импортированный контент. Прямоугольная фигура оставляет отступ 10 pt со всех сторон слайда:
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. При переиспользовании текста презентации на сайте вы можете захотеть сохранить локальное выделение без переноса шрифта, размера или стилей текстового поля презентации. Установите TextToHtmlConversionOptions.setTextInheritanceLimit для контроля глубины наследования формата.
Скачайте the sample presentation и поместите её в рабочий каталог приложения. На первом слайде находится одна текстовая фигурка с текстом «Inherited text; explicit red 18pt». Ввод намеренно использует несколько уровней форматирования:
- Стиль текста по умолчанию презентации задаёт Calibri и размер 28 pt.
- Стиль текста первого уровня в текстовой рамке задаёт синий цвет и курсив.
- Абзац явно задаёт полужирный текст.
- Вторая часть, «explicit red 18pt», явно задаёт красный цвет и размер 18 pt.
Следующий полный пример экспортирует те же абзацы трижды. Он передаёт объект TextToHtmlConversionOptions в метод экспорта и записывает каждый результат в отдельный UTF‑8 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("text-inheritance.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();
int[] modes = { TextInheritanceLimit.All, TextInheritanceLimit.TextBox, TextInheritanceLimit.ParagraphOnly };
String[] fileNames = { "All.html", "TextBox.html", "ParagraphOnly.html" };
for (int i = 0; i < modes.length; i++) {
TextToHtmlConversionOptions options = new TextToHtmlConversionOptions();
options.setTextInheritanceLimit(modes[i]);
String html = paragraphs.exportToHtml(0, paragraphs.getCount(), options);
byte[] htmlBytes = html.getBytes(StandardCharsets.UTF_8);
try {
Files.write(Paths.get(fileNames[i]), htmlBytes);
} 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();
}
Сгенерированный HTML содержит следующий CSS для первой части, «Inherited text; ». Таблица перечисляет соответствующие декларации; остальные сгенерированные свойства опущены для ясности.
| Вывод | Соответствующий CSS для первой части | Внешний вид |
|---|---|---|
All.html |
font-family:'Calibri'; font-size:28pt; color:#0000ff; font-style:italic; font-weight:bold |
Синий, полужирный, курсивный текст размером 28 pt в шрифте Calibri, если этот шрифт доступен. |
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.
Отрисовка абзаца как изображения
IParagraph.getImage отрисовывает отдельный абзац напрямую и возвращает объект IImage. Сохраните результат в файл или поток с помощью IImage.save. Нет необходимости отрисовывать содержащую фигуру или вручную обрезать растровое изображение.
IParagraph.getImage может вернуть null, если абзац не найден в родительской коллекции, у него нет допустимых границ отрисовки или он не может быть отрисован. Проверьте результат перед сохранением и освободите полученное изображение после использования.
Отрисовка абзаца в масштабе по умолчанию
Пример использует презентацию с одним слайдом, где первая фигура — текстовое поле, содержащее три абзаца.

Следующий пример выбирает второй абзац (индекс 1) и вызывает IParagraph.getImage без параметров масштаба. Он проверяет, что фигура содержит требуемый абзац и что отрисовка возвращает изображение, прежде чем вызвать IImage.save для сохранения в формате 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.
Часто задаваемые вопросы
Могу ли я полностью отключить перенос строк внутри текстового кадра?
Да. Установите ITextFrameFormat.setWrapText в значение, отключающее перенос, чтобы строки не разрывались у краев текстового кадра.
Как получить точные границы конкретного абзаца на слайде?
Используйте IParagraph.getRect для получения ограничивающего прямоугольника абзаца. IPortion.getRect предоставляет границы отдельной части.
Где управляется выравнивание абзаца (по левому, правому краю, по центру или по ширине)?
IParagraphFormat.setAlignment — это настройка уровня абзаца и применяется ко всему абзацу независимо от форматирования отдельных частей.
Чтобы вертикально выровнять части с разными размерами шрифтов внутри каждой строки, см. Выравнивание шрифтов в строке.
Могу ли я задать язык проверки орфографии для части абзаца?
Да. Установите IBasePortionFormat.setLanguageId для отдельных частей, чтобы один абзац мог содержать текст на нескольких языках.