Управление абзацами текста PowerPoint в JavaScript
Обзор
Aspose.Slides for Node.js via Java представляет текст как иерархию текстовых фреймов, абзацев и частей:
- TextFrame представляет контейнер текста в фигуре и предоставляет доступ к её коллекции абзацев.
- Paragraph представляет один абзац в текстовом фрейме и предоставляет доступ к его частям и форматированию уровня абзаца.
- Portion представляет текстовый фрагмент внутри абзаца. Каждая часть может иметь собственный текст и форматирование на уровне символов.
Таким образом, абзац может содержать текст с разными шрифтами, цветами, размерами и другим форматированием, используя несколько частей.
Создание и форматирование абзацев
Создавайте абзацы в текстовом фрейме фигуры и используйте части для форматирования отдельных фрагментов текста. В этом разделе показано, как комбинировать несколько частей внутри каждого абзаца и применять разные цвета, размеры шрифта и стили.
Создание абзацев с несколькими частями
Следующий пример на JavaScript создаёт три абзаца, каждый из которых содержит три текстовых фрагмента в коллекции, возвращаемой методом Paragraph.getPortions. Он переиспользует абзац по умолчанию и его пустую часть, затем добавляет оставшиеся абзацы и части. Форматирование применяется через Portion.getPortionFormat: первая часть в каждом абзаце красная, полужирная и 15 пунктов; вторая — синяя, курсивная и 18 пунктов. Третья часть сохраняет форматирование по умолчанию:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 50, 150, 300, 150);
const textFrame = shape.getTextFrame();
const firstParagraph = textFrame.getParagraphs().get_Item(0);
firstParagraph.getPortions().add(new aspose.slides.Portion());
firstParagraph.getPortions().add(new aspose.slides.Portion());
const secondParagraph = new aspose.slides.Paragraph();
secondParagraph.getPortions().add(new aspose.slides.Portion());
secondParagraph.getPortions().add(new aspose.slides.Portion());
secondParagraph.getPortions().add(new aspose.slides.Portion());
textFrame.getParagraphs().add(secondParagraph);
const thirdParagraph = new aspose.slides.Paragraph();
thirdParagraph.getPortions().add(new aspose.slides.Portion());
thirdParagraph.getPortions().add(new aspose.slides.Portion());
thirdParagraph.getPortions().add(new aspose.slides.Portion());
textFrame.getParagraphs().add(thirdParagraph);
const paragraphCount = textFrame.getParagraphs().getCount();
for (let paragraphIndex = 0; paragraphIndex < paragraphCount; paragraphIndex++) {
const paragraph = textFrame.getParagraphs().get_Item(paragraphIndex);
const portionCount = paragraph.getPortions().getCount();
for (let portionIndex = 0; portionIndex < portionCount; portionIndex++) {
const portion = paragraph.getPortions().get_Item(portionIndex);
portion.setText("Portion " + (paragraphIndex + 1) + "." + (portionIndex + 1));
if (portionIndex === 0) {
portion.getPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
portion.getPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "RED"));
portion.getPortionFormat().setFontBold(java.newByte(aspose.slides.NullableBool.True));
portion.getPortionFormat().setFontHeight(15);
} else if (portionIndex === 1) {
portion.getPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
portion.getPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLUE"));
portion.getPortionFormat().setFontItalic(java.newByte(aspose.slides.NullableBool.True));
portion.getPortionFormat().setFontHeight(18);
}
}
}
presentation.save("paragraphs_with_portions.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Создание маркированных и нумерованных списков
Организуйте текст абзаца в списки с символами, цифрами или пользовательскими изображениями. Примеры в этом разделе охватывают форматирование маркеров, многоуровневые списки и пользовательские начальные номера.
Создание маркированного или нумерованного списка
Маркеры и нумерация делают связанные элементы более удобными для просмотра. В Aspose.Slides настройки списка определяются через BulletFormat.
Этот пример на JavaScript добавляет символ‑маркер и нумерованный элемент в один и тот же текстовый фрейм. BulletFormat.setType выбирает тип маркера, а BulletFormat.setChar задаёт символ и BulletFormat.setNumberedBulletStyle выбирает стиль нумерации. Оба элемента используют чёрные маркеры высотой 100 % и отступ абзаца 25 пунктов:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 200, 200, 400, 200);
const textFrame = shape.getTextFrame();
textFrame.getParagraphs().clear();
const symbolParagraph = new aspose.slides.Paragraph();
symbolParagraph.setText("Welcome to Aspose.Slides");
symbolParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Symbol));
symbolParagraph.getParagraphFormat().getBullet().setChar(java.newChar(0x2022));
symbolParagraph.getParagraphFormat().setIndent(25);
symbolParagraph.getParagraphFormat().getBullet().getColor().setColorType(aspose.slides.ColorType.RGB);
symbolParagraph.getParagraphFormat().getBullet().getColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
symbolParagraph.getParagraphFormat().getBullet().setBulletHardColor(java.newByte(aspose.slides.NullableBool.True));
symbolParagraph.getParagraphFormat().getBullet().setHeight(100);
textFrame.getParagraphs().add(symbolParagraph);
const numberedParagraph = new aspose.slides.Paragraph();
numberedParagraph.setText("This is a numbered item");
numberedParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Numbered));
numberedParagraph.getParagraphFormat().getBullet().setNumberedBulletStyle(java.newByte(aspose.slides.NumberedBulletStyle.BulletCircleNumWDBlackPlain));
numberedParagraph.getParagraphFormat().setIndent(25);
numberedParagraph.getParagraphFormat().getBullet().getColor().setColorType(aspose.slides.ColorType.RGB);
numberedParagraph.getParagraphFormat().getBullet().getColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
numberedParagraph.getParagraphFormat().getBullet().setBulletHardColor(java.newByte(aspose.slides.NullableBool.True));
numberedParagraph.getParagraphFormat().getBullet().setHeight(100);
textFrame.getParagraphs().add(numberedParagraph);
presentation.save("bulleted_and_numbered_list.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Использование изображений в качестве маркеров
Изображения‑маркеры позволяют использовать пользовательское изображение вместо символа или числа.
Этот пример на JavaScript загружает image.png из рабочей директории приложения, добавляет изображение в коллекцию изображений презентации как PPImage и использует его в качестве маркера абзаца. Он вызывает BulletFormat.setType для использования маркера‑изображения и назначает изображение через BulletFormat.getPicture. BulletFormat.setHeight установлен в 100 % для масштабирования маркера относительно текста абзаца:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const bulletImage = aspose.slides.Images.fromFile("image.png");
let presentationImage;
try {
presentationImage = presentation.getImages().addImage(bulletImage);
} finally {
bulletImage.dispose();
}
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 200, 200, 400, 200);
const textFrame = shape.getTextFrame();
textFrame.getParagraphs().clear();
const paragraph = new aspose.slides.Paragraph();
paragraph.setText("Welcome to Aspose.Slides");
paragraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Picture));
paragraph.getParagraphFormat().getBullet().getPicture().setImage(presentationImage);
paragraph.getParagraphFormat().getBullet().setHeight(100);
textFrame.getParagraphs().add(paragraph);
presentation.save("picture_bullet.pptx", aspose.slides.SaveFormat.Pptx);
presentation.save("picture_bullet.ppt", aspose.slides.SaveFormat.Ppt);
} finally {
presentation.dispose();
}
Создание многоуровневого списка
Установите ParagraphFormat.setDepth для размещения абзацев на разных уровнях списка. Верхний уровень имеет глубину 0.
Этот пример на JavaScript присваивает значения ParagraphFormat.setDepth от 0 до 3 четырём абзацам, создавая иерархию внутри одного текстового фрейма. Каждый абзац использует символ‑маркер, при этом BulletFormat.setChar чередуется между круглым маркером и дефисом для различения соседних уровней:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 200, 200, 400, 200);
const textFrame = shape.getTextFrame();
textFrame.getParagraphs().clear();
const firstParagraph = new aspose.slides.Paragraph();
firstParagraph.setText("Content");
firstParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Symbol));
firstParagraph.getParagraphFormat().getBullet().setChar(java.newChar(0x2022));
firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
firstParagraph.getParagraphFormat().setDepth(java.newShort(0));
const secondParagraph = new aspose.slides.Paragraph();
secondParagraph.setText("Second level");
secondParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Symbol));
secondParagraph.getParagraphFormat().getBullet().setChar(java.newChar(45));
secondParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
secondParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
secondParagraph.getParagraphFormat().setDepth(java.newShort(1));
const thirdParagraph = new aspose.slides.Paragraph();
thirdParagraph.setText("Third level");
thirdParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Symbol));
thirdParagraph.getParagraphFormat().getBullet().setChar(java.newChar(0x2022));
thirdParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
thirdParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
thirdParagraph.getParagraphFormat().setDepth(java.newShort(2));
const fourthParagraph = new aspose.slides.Paragraph();
fourthParagraph.setText("Fourth level");
fourthParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Symbol));
fourthParagraph.getParagraphFormat().getBullet().setChar(java.newChar(45));
fourthParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
fourthParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
fourthParagraph.getParagraphFormat().setDepth(java.newShort(3));
textFrame.getParagraphs().add(firstParagraph);
textFrame.getParagraphs().add(secondParagraph);
textFrame.getParagraphs().add(thirdParagraph);
textFrame.getParagraphs().add(fourthParagraph);
presentation.save("multilevel_list.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Начало нумерованных пунктов списка с пользовательских значений
Используйте BulletFormat.setNumberedBulletStartWith для установки начального номера, отображаемого для нумерованного абзаца.
Этот пример на JavaScript устанавливает BulletFormat.setType для использования нумерации в трёх абзацах и задаёт значения BulletFormat.setNumberedBulletStartWith 2, 3 и 7. Начальное значение задаётся отдельно для каждого абзаца, позволяя пропускать числа:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 200, 200, 400, 200);
const textFrame = shape.getTextFrame();
textFrame.getParagraphs().clear();
const firstParagraph = new aspose.slides.Paragraph();
firstParagraph.setText("Start at 2");
firstParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Numbered));
firstParagraph.getParagraphFormat().getBullet().setNumberedBulletStartWith(java.newShort(2));
textFrame.getParagraphs().add(firstParagraph);
const secondParagraph = new aspose.slides.Paragraph();
secondParagraph.setText("Start at 3");
secondParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Numbered));
secondParagraph.getParagraphFormat().getBullet().setNumberedBulletStartWith(java.newShort(3));
textFrame.getParagraphs().add(secondParagraph);
const thirdParagraph = new aspose.slides.Paragraph();
thirdParagraph.setText("Start at 7");
thirdParagraph.getParagraphFormat().getBullet().setType(java.newByte(aspose.slides.BulletType.Numbered));
thirdParagraph.getParagraphFormat().getBullet().setNumberedBulletStartWith(java.newShort(7));
textFrame.getParagraphs().add(thirdParagraph);
presentation.save("custom_numbered_list.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Управление расположением абзаца и свойствами завершения
Регулируйте поля и отступы абзаца, чтобы контролировать положение первой строки и строк переноса. Вы также можете форматировать маркер конца абзаца отдельно от видимых текстовых частей.
Установка отступа первой строки
Используйте метод ParagraphFormat.setIndent для контроля отступа первой строки абзаца. Эта настройка смещает только первую строку относительно левого поля абзаца. Положительное значение сдвигает первую строку вправо, остальные строки остаются выровненными по телу абзаца.
Используйте ParagraphFormat.setMarginLeft когда нужно переместить весь абзац. Используйте ParagraphFormat.setIndent когда требуется сдвинуть только первую строку.
Следующий пример задаёт трём абзацам одинаковый ParagraphFormat.setMarginLeft — 20 пунктов и значения ParagraphFormat.setIndent — 0, 20 и 40 пунктов. Первые строки начинаются с постепенно большего смещения, в то время как строки переноса сохраняют одинаковое левое поле:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 50, 50, 420, 220);
shape.getFillFormat().setFillType(java.newByte(aspose.slides.FillType.NoFill));
shape.getLineFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
shape.getLineFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "GRAY"));
const textFrame = shape.getTextFrame();
textFrame.getTextFrameFormat().setAutofitType(java.newByte(aspose.slides.TextAutofitType.Shape));
textFrame.getParagraphs().clear();
const firstParagraph = new aspose.slides.Paragraph();
firstParagraph.setText("No first-line indent. Wrapped lines start at the same position as the first line.");
firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
firstParagraph.getParagraphFormat().setMarginLeft(20);
firstParagraph.getParagraphFormat().setIndent(0);
const secondParagraph = new aspose.slides.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(java.newByte(aspose.slides.FillType.Solid));
secondParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
secondParagraph.getParagraphFormat().setMarginLeft(20);
secondParagraph.getParagraphFormat().setIndent(20);
const thirdParagraph = new aspose.slides.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(java.newByte(aspose.slides.FillType.Solid));
thirdParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
thirdParagraph.getParagraphFormat().setMarginLeft(20);
thirdParagraph.getParagraphFormat().setIndent(40);
textFrame.getParagraphs().add(firstParagraph);
textFrame.getParagraphs().add(secondParagraph);
textFrame.getParagraphs().add(thirdParagraph);
presentation.save("paragraph_indent.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

Установка висячего отступа
Висячий отступ — это расположение абзаца, при котором первая строка начинается левее остальных строк. В Aspose.Slides этот эффект создаётся методом ParagraphFormat.setIndent. Установите отступ в отрицательное значение, чтобы переместить первую строку влево относительно тела абзаца.
На практике ParagraphFormat.setMarginLeft определяет левую позицию тела абзаца, а ParagraphFormat.setIndent — позицию первой строки относительно этого поля. Чтобы создать висячий отступ, задайте положительное левое поле и отрицательный отступ.
Это форматирование полезно для библиографий, ссылок, глоссариев и других абзацев, где строки переноса должны выравниваться под телом абзаца, а не под первым символом первой строки.
Следующий пример на JavaScript сочетает значения ParagraphFormat.setMarginLeft — 40 и 60 пунктов с значениями ParagraphFormat.setIndent — ‑20 и ‑30 пунктов. В каждом абзаце первая строка начинается левее строк переноса; во втором абзаце висячий отступ глубже:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 50, 50, 420, 220);
shape.getFillFormat().setFillType(java.newByte(aspose.slides.FillType.NoFill));
shape.getLineFormat().getFillFormat().setFillType(java.newByte(aspose.slides.FillType.Solid));
shape.getLineFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "GRAY"));
const textFrame = shape.getTextFrame();
textFrame.getTextFrameFormat().setAutofitType(java.newByte(aspose.slides.TextAutofitType.Shape));
textFrame.getParagraphs().clear();
const firstParagraph = new aspose.slides.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(java.newByte(aspose.slides.FillType.Solid));
firstParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
firstParagraph.getParagraphFormat().setMarginLeft(40);
firstParagraph.getParagraphFormat().setIndent(-20);
const secondParagraph = new aspose.slides.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(java.newByte(aspose.slides.FillType.Solid));
secondParagraph.getParagraphFormat().getDefaultPortionFormat().getFillFormat().getSolidFillColor().setColor(java.getStaticFieldValue("java.awt.Color", "BLACK"));
secondParagraph.getParagraphFormat().setMarginLeft(60);
secondParagraph.getParagraphFormat().setIndent(-30);
textFrame.getParagraphs().add(firstParagraph);
textFrame.getParagraphs().add(secondParagraph);
presentation.save("hanging_indent.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Результат:

Установка свойств завершающего фрагмента абзаца
Метод Paragraph.setEndParagraphPortionFormat контролирует форматирование маркера конца абзаца. Следующий пример создаёт PortionFormat с BasePortionFormat.setFontHeight = 48 пунктов и BasePortionFormat.setLatinFont = Times New Roman. Этот формат назначается маркеру конца второго абзаца, оставляя видимые части текста без изменений:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 10, 10, 200, 250);
const textFrame = shape.getTextFrame();
textFrame.getParagraphs().clear();
const firstParagraph = new aspose.slides.Paragraph();
firstParagraph.getPortions().add(new aspose.slides.Portion("Sample text"));
const secondParagraph = new aspose.slides.Paragraph();
secondParagraph.getPortions().add(new aspose.slides.Portion("Sample text 2"));
const endParagraphFormat = new aspose.slides.PortionFormat();
endParagraphFormat.setFontHeight(48);
endParagraphFormat.setLatinFont(new aspose.slides.FontData("Times New Roman"));
secondParagraph.setEndParagraphPortionFormat(endParagraphFormat);
textFrame.getParagraphs().add(firstParagraph);
textFrame.getParagraphs().add(secondParagraph);
presentation.save("end_paragraph_format.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Подсчет отрисованных строк
Для правил абзаца, влияющих на автоматический перенос и пунктуацию в конце строки, см. Control Line Breaking и Control Hanging Punctuation.
Используйте Paragraph.getLinesCount для подсчёта строк, занимаемых абзацем после размещения текста, включая автоматический перенос. Это полезно при проверке длины текста и разметки в шаблонах презентаций.
Абзац — это один элемент в TextFrame.getParagraphs, и он может занимать несколько отрисованных строк. Явный разрыв строки внутри абзаца принудительно создаёт новую строку без создания нового абзаца. Автоматический перенос формирует строки на основе доступной ширины без вставки явных разрывов в текст. Поэтому подсчёт абзацев или символов разрыва не даёт количества отрисованных строк.
Следующий пример создаёт текстовую фигуру, считает её строки, сужает фигуру, а затем заменяет текст более короткой строкой. Пример включает перенос, задав TextFrameFormat.setWrapText и отключив автоподгонку через TextFrameFormat.setAutofitType, чтобы ширина фигуры регулировала перенос без автоматического уменьшения текста или изменения размеров фигуры. Каждое измерение использует Paragraph.getLinesCount. Размеры фигур указаны в пунктах. В конце пример добавляет ещё один абзац и суммирует количество строк по всему текстовому фрейму.
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 50, 50, 400, 200);
const textFrame = shape.getTextFrame();
textFrame.getTextFrameFormat().setWrapText(java.newByte(aspose.slides.NullableBool.True));
textFrame.getTextFrameFormat().setAutofitType(java.newByte(aspose.slides.TextAutofitType.None));
const 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.");
console.log("Original width: " + paragraph.getLinesCount());
shape.setWidth(150);
console.log("Narrower shape: " + paragraph.getLinesCount());
paragraph.setText("Short text.");
console.log("Shorter text: " + paragraph.getLinesCount());
const secondParagraph = new aspose.slides.Paragraph();
secondParagraph.setText("Another paragraph.");
secondParagraph.getParagraphFormat().getDefaultPortionFormat().setFontHeight(20);
textFrame.getParagraphs().add(secondParagraph);
let totalLineCount = 0;
for (let i = 0; i < textFrame.getParagraphs().getCount(); i++) {
const currentParagraph = textFrame.getParagraphs().get_Item(i);
totalLineCount += currentParagraph.getLinesCount();
}
console.log("Total lines in the text frame: " + totalLineCount);
} finally {
presentation.dispose();
}
С этими текстом и размерами сужение фигуры увеличивает количество строк, а замена текста короткой строкой уменьшает его. Точные значения могут различаться в зависимости от доступных шрифтов и их замен, размера шрифта, полей, отступов, переноса и настроек автоподгонки. Используйте шрифты и параметры разметки, предназначенные для целевой среды, при проверке шаблона.
Само количество строк не определяет, выходит ли текст за пределы контейнера. Важны доступная высота, высота строк, межстрочный и абзацный интервал, а также поведение автоподгонки; даже одна строка может превышать доступную ширину, если перенос отключён.
Импорт и экспорт содержимого абзаца
Используйте HTML для импорта текста в презентацию или экспорта существующих абзацев для использования вне её. В этом разделе также показано, как визуализировать отдельные абзацы как изображения, включая абзацы в ячейках таблиц.
Импорт HTML‑текста в абзацы
Для преобразования разметки HTML в абзацы и части внутри текстового фрейма используйте ParagraphCollection.addFromHtml.
Этот пример на JavaScript читает HTML из file.html в рабочей директории приложения и передаёт разметку в ParagraphCollection.addFromHtml. Он очищает абзац по умолчанию в текстовом фрейме, так что фрейм содержит только импортированный контент. Прямоугольная фигура оставляет 10‑пунктовый отступ со всех сторон слайда:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const fs = require("fs");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const shapeWidth = presentation.getSlideSize().getSize().getWidth() - 20;
const shapeHeight = presentation.getSlideSize().getSize().getHeight() - 20;
const shape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 10, 10, shapeWidth, shapeHeight);
shape.getFillFormat().setFillType(java.newByte(aspose.slides.FillType.NoFill));
shape.getTextFrame().getParagraphs().clear();
const html = fs.readFileSync("file.html", "utf8");
shape.getTextFrame().getParagraphs().addFromHtml(html);
presentation.save("html_text.pptx", aspose.slides.SaveFormat.Pptx);
} finally {
presentation.dispose();
}
Экспорт текста абзаца в HTML
Для экспорта выбранного диапазона абзацев в HTML используйте ParagraphCollection.exportToHtml. При повторном использовании текста презентации на веб‑сайте вы можете захотеть сохранить локальное акцентирование без переноса шрифта, размера или стилей текстового окна презентации. Установите TextToHtmlConversionOptions.setTextInheritanceLimit для ограничения глубины наследования форматирования.
Скачайте пример презентации и разместите её в рабочей директории приложения. На первом слайде находится один текстовый блок с текстом «Inherited text; explicit red 18pt». Входной файл намеренно использует несколько уровней форматирования:
- Стиль текста по умолчанию презентации задаёт шрифт Calibri и размер 28 pt.
- Стиль текста первого уровня в текстовом фрейме задаёт синий цвет и курсив.
- Абзац явно задаёт полужирный текст.
- Вторая часть, «explicit red 18pt», явно задаёт красный цвет и размер 18 pt.
Следующий полный пример экспортирует те же абзацы трижды. Он передаёт TextToHtmlConversionOptions в метод экспорта и записывает каждый результат в отдельный UTF‑8 HTML‑файл:
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const fs = require("fs");
const presentation = new aspose.slides.Presentation("text-inheritance.pptx");
try {
const shape = presentation.getSlides().get_Item(0).getShapes().get_Item(0);
if (java.instanceOf(shape, "com.aspose.slides.IAutoShape")) {
const textFrame = shape.getTextFrame();
if (textFrame !== null) {
const paragraphs = textFrame.getParagraphs();
const modes = [aspose.slides.TextInheritanceLimit.All, aspose.slides.TextInheritanceLimit.TextBox, aspose.slides.TextInheritanceLimit.ParagraphOnly];
const fileNames = ["All.html", "TextBox.html", "ParagraphOnly.html"];
for (let i = 0; i < modes.length; i++) {
const options = new aspose.slides.TextToHtmlConversionOptions();
options.setTextInheritanceLimit(modes[i]);
const html = paragraphs.exportToHtml(0, paragraphs.getCount(), options);
fs.writeFileSync(fileNames[i], html, "utf8");
}
} else {
console.log("The first shape does not contain a text frame.");
}
} else {
console.log("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. Ограничение наследования therefore does not remove formatting explicitly assigned to a paragraph or portion.
Откройте файлы в одном браузере для их сравнения. В двух ограниченных режимах пропущенные CSS‑свойства разрешаются стилями целевой страницы или браузерными настройками, поэтому окончательный вид зависит от места использования HTML.
Рендеринг абзаца как изображения
Paragraph.getImage рендерит отдельный абзац напрямую и возвращает IImage. Сохраните результат в файл или поток с помощью IImage.save. Вам не требуется рендерить содержащую фигуру или вручную обрезать bitmap.
Paragraph.getImage может вернуть null, если абзац не найден в родительской коллекции, не имеет допустимых границ рендеринга или не может быть отрендерен. Проверьте результат перед сохранением и освободите возвращённое изображение после использования.
Рендеринг абзаца в масштабе по умолчанию
Пример создаёт презентацию с одним слайдом, первый объект — текстовый блок, содержащий три абзаца.

Следующий пример выбирает второй абзац с индексом 1 и вызывает Paragraph.getImage без параметров масштаба. Он проверяет, что фигура содержит требуемый абзац и что рендеринг возвращает изображение, прежде чем вызвать IImage.save для сохранения в формате PNG. Блок finally освобождает изображение после использования.
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const sourceShape = slide.getShapes().addAutoShape(aspose.slides.ShapeType.Rectangle, 20, 20, 400, 100);
const sourceTextFrame = sourceShape.getTextFrame();
sourceTextFrame.getParagraphs().clear();
for (const text of ["First paragraph", "Second paragraph", "Third paragraph"]) {
const sourceParagraph = new aspose.slides.Paragraph();
sourceParagraph.setText(text);
sourceTextFrame.getParagraphs().add(sourceParagraph);
}
const shape = slide.getShapes().get_Item(0);
if (java.instanceOf(shape, "com.aspose.slides.IAutoShape")) {
const textFrame = shape.getTextFrame();
if (textFrame !== null && textFrame.getParagraphs().getCount() > 1) {
const paragraph = textFrame.getParagraphs().get_Item(1);
const paragraphImage = paragraph.getImage();
if (paragraphImage !== null) {
try {
paragraphImage.save("paragraph.png", aspose.slides.ImageFormat.Png);
} finally {
paragraphImage.dispose();
}
} else {
console.log("The paragraph could not be rendered.");
}
} else {
console.log("The expected paragraph was not found.");
}
} else {
console.log("The first shape is not a text shape.");
}
} finally {
presentation.dispose();
}
Результат:

Рендеринг абзаца в ячейке таблицы с масштабированием
Используйте перегрузку Paragraph.getImage, принимающую параметры scaleX и scaleY для задания горизонтального и вертикального коэффициентов масштаба. Следующий пример создаёт таблицу, рендерит абзац в её первой ячейке с двойной шириной и высотой по сравнению с масштабом по умолчанию и сохраняет результат в виде PNG‑изображения.
var aspose = aspose || {};
aspose.slides = require("aspose.slides.via.java");
const java = require("java");
const scaleX = 2;
const scaleY = 2;
const presentation = new aspose.slides.Presentation();
try {
const slide = presentation.getSlides().get_Item(0);
const columnWidths = java.newArray("double", [300]);
const rowHeights = java.newArray("double", [80]);
const table = slide.getShapes().addTable(50, 50, columnWidths, rowHeights);
const paragraph = table.get_Item(0, 0).getTextFrame().getParagraphs().get_Item(0);
paragraph.setText("Text in a table cell");
const paragraphImage = paragraph.getImage(scaleX, scaleY);
if (paragraphImage !== null) {
try {
paragraphImage.save("table_paragraph.png", aspose.slides.ImageFormat.Png);
} finally {
paragraphImage.dispose();
}
} else {
console.log("The paragraph could not be rendered.");
}
} finally {
presentation.dispose();
}
Коэффициент масштаба 1 сохраняет размер по умолчанию для соответствующей оси. Например, 2 для обеих осей создаёт изображение, ширина и высота которого примерно вдвое превышают исходные размеры, что приводит к четырёхкратному количеству пикселей. Большие коэффициенты обычно дают более чёткий текст при увеличении или выводе в высоком разрешении, но также увеличивают потребление памяти и размер файла. Коэффициенты ниже 1 создают меньшее изображение с меньшим детализмом. Используйте одинаковые коэффициенты, чтобы сохранять пропорции абзаца; разные горизонтальные и вертикальные коэффициенты растягивают вывод независимо.
Рендеринг всей фигуры с помощью Shape.getImage остаётся полезным, когда необходимо включить заливку, границу или иной визуальный контекст фигуры. Для изображения только абзаца используйте Paragraph.getImage.
Часто задаваемые вопросы
Могу ли я полностью отключить перенос строк внутри текстового фрейма?
Да. Установите TextFrameFormat.setWrapText для отключения переноса, чтобы строки не разбивались у границ текстового фрейма.
Как я могу получить точные границы конкретного абзаца на слайде?
Используйте Paragraph.getRect для получения ограничивающего прямоугольника абзаца. Portion.getRect предоставляет границы отдельной части.
Где управляется выравнивание абзаца (по левому, правому, центру или по ширине)?
ParagraphFormat.setAlignment — это настройка уровня абзаца, применяемая ко всему абзацу независимо от форматирования отдельных частей.
Чтобы вертикально выравнивать части с разными размерами шрифтов в каждой строке, см. Align Fonts Within a Line.
Могу ли я задать язык подтверждения для части абзаца?
Да. Установите BasePortionFormat.setLanguageId для отдельных частей, чтобы один абзац мог содержать текст на нескольких языках.