Управление абзацами PowerPoint в C++
Обзор
Aspose.Slides для C++ представляет текст как иерархию текстовых фреймов, абзацев и фрагментов:
- ITextFrame представляет контейнер текста в фигуре и предоставляет доступ к коллекции абзацев.
- IParagraph представляет один абзац в текстовом фрейме и предоставляет доступ к его фрагментам и форматированию уровня абзаца.
- IPortion представляет текстовый фрагмент внутри абзаца. Каждый фрагмент может иметь собственный текст и форматирование уровня символа.
Таким образом, абзац может содержать текст с разными шрифтами, цветами, размерами и другим форматированием, используя несколько фрагментов.
Создание и форматирование абзацев
Создание абзацев с несколькими фрагментами
Следующие шаги создают текстовый фрейм с тремя абзацами, каждый из которых содержит три фрагмента:
- Создайте экземпляр класса Presentation.
- Получите ссылку на нужный слайд по его индексу.
- Добавьте прямоугольную IAutoShape на слайд.
- Получите ITextFrame у формы.
- Используйте абзац по умолчанию и добавьте два дополнительных объекта IParagraph в текстовый фрейм.
- Добавьте достаточное количество объектов IPortion , чтобы каждый абзац содержал три фрагмента. Абзац по умолчанию уже содержит один пустой фрагмент.
- Установите текст для каждого фрагмента.
- Примените форматирование символов через IPortion::get_PortionFormat.
- Сохраните изменённую презентацию.
Этот пример на C++ реализует шаги:
#include <DOM/FillType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/IPortionCollection.h>
#include <DOM/NullableBool.h>
#include <DOM/Paragraph.h>
#include <DOM/Portion.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 50, 150, 300, 150);
auto textFrame = shape->get_TextFrame();
auto firstParagraph = textFrame->get_Paragraph(0);
firstParagraph->get_Portions()->Add(MakeObject<Portion>());
firstParagraph->get_Portions()->Add(MakeObject<Portion>());
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->get_Portions()->Add(MakeObject<Portion>());
secondParagraph->get_Portions()->Add(MakeObject<Portion>());
secondParagraph->get_Portions()->Add(MakeObject<Portion>());
textFrame->get_Paragraphs()->Add(secondParagraph);
auto thirdParagraph = MakeObject<Paragraph>();
thirdParagraph->get_Portions()->Add(MakeObject<Portion>());
thirdParagraph->get_Portions()->Add(MakeObject<Portion>());
thirdParagraph->get_Portions()->Add(MakeObject<Portion>());
textFrame->get_Paragraphs()->Add(thirdParagraph);
auto paragraphCount = textFrame->get_Paragraphs()->get_Count();
for (int paragraphIndex = 0; paragraphIndex < paragraphCount; paragraphIndex++)
{
auto paragraph = textFrame->get_Paragraph(paragraphIndex);
auto portionCount = paragraph->get_Portions()->get_Count();
for (int portionIndex = 0; portionIndex < portionCount; portionIndex++)
{
auto portion = paragraph->get_Portion(portionIndex);
portion->set_Text(String::Format(u"Portion {0}.{1}", paragraphIndex + 1, portionIndex + 1));
auto portionFormat = portion->get_PortionFormat();
if (portionIndex == 0)
{
portionFormat->get_FillFormat()->set_FillType(FillType::Solid);
portionFormat->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Red());
portionFormat->set_FontBold(NullableBool::True);
portionFormat->set_FontHeight(15);
}
else if (portionIndex == 1)
{
portionFormat->get_FillFormat()->set_FillType(FillType::Solid);
portionFormat->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Blue());
portionFormat->set_FontItalic(NullableBool::True);
portionFormat->set_FontHeight(18);
}
}
}
presentation->Save(u"paragraphs_with_portions.pptx", SaveFormat::Pptx);
presentation->Dispose();
Создание маркированных и нумерованных списков
Создание маркированного или нумерованного списка
Маркировка и нумерация упрощают просмотр связанных элементов. В Aspose.Slides параметры списка определяются через IBulletFormat.
- Создайте экземпляр класса Presentation.
- Получите ссылку на нужный слайд по его индексу.
- Добавьте IAutoShape на выбранный слайд.
- Получите ITextFrame у формы.
- Удалите абзац по умолчанию из текстового фрейма.
- Создайте Paragraph для символного маркера.
- Установите IBulletFormat::set_Type в значение BulletType::Symbol и укажите символ маркера.
- Задайте текст абзаца, отступ, цвет маркера и высоту маркера.
- Добавьте абзац в текстовый фрейм.
- Создайте второй абзац и установите IBulletFormat::set_Type в значение BulletType::Numbered.
- Настройте стиль нумерованного маркера и добавьте абзац в текстовый фрейм.
- Сохраните презентацию.
Этот пример на C++ создаёт символный маркер и нумерованный маркер:
#include <DOM/BulletType.h>
#include <DOM/ColorType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/NullableBool.h>
#include <DOM/NumberedBulletStyle.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/convert.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 200, 200, 400, 200);
auto textFrame = shape->get_TextFrame();
textFrame->get_Paragraphs()->Clear();
auto symbolParagraph = MakeObject<Paragraph>();
symbolParagraph->set_Text(u"Welcome to Aspose.Slides");
symbolParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Symbol);
symbolParagraph->get_ParagraphFormat()->get_Bullet()->set_Char(Convert::ToChar(0x2022));
symbolParagraph->get_ParagraphFormat()->set_Indent(25);
symbolParagraph->get_ParagraphFormat()->get_Bullet()->get_Color()->set_ColorType(ColorType::RGB);
symbolParagraph->get_ParagraphFormat()->get_Bullet()->get_Color()->set_Color(Color::get_Black());
symbolParagraph->get_ParagraphFormat()->get_Bullet()->set_IsBulletHardColor(NullableBool::True);
symbolParagraph->get_ParagraphFormat()->get_Bullet()->set_Height(100);
textFrame->get_Paragraphs()->Add(symbolParagraph);
auto numberedParagraph = MakeObject<Paragraph>();
numberedParagraph->set_Text(u"This is a numbered item");
numberedParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Numbered);
numberedParagraph->get_ParagraphFormat()->get_Bullet()->set_NumberedBulletStyle(NumberedBulletStyle::BulletCircleNumWDBlackPlain);
numberedParagraph->get_ParagraphFormat()->set_Indent(25);
numberedParagraph->get_ParagraphFormat()->get_Bullet()->get_Color()->set_ColorType(ColorType::RGB);
numberedParagraph->get_ParagraphFormat()->get_Bullet()->get_Color()->set_Color(Color::get_Black());
numberedParagraph->get_ParagraphFormat()->get_Bullet()->set_IsBulletHardColor(NullableBool::True);
numberedParagraph->get_ParagraphFormat()->get_Bullet()->set_Height(100);
textFrame->get_Paragraphs()->Add(numberedParagraph);
presentation->Save(u"bulleted_and_numbered_list.pptx", SaveFormat::Pptx);
presentation->Dispose();
Использование картинок в качестве маркеров
Картинки‑маркеры позволяют использовать пользовательское изображение вместо символа или числа.
- Создайте экземпляр класса Presentation.
- Получите ссылку на нужный слайд по его индексу.
- Добавьте IAutoShape и затем получите его ITextFrame.
- Удалите абзац по умолчанию из текстового фрейма.
- Загрузите изображение маркера и добавьте его в коллекцию изображений презентации как IPPImage.
- Создайте Paragraph и задайте его текст.
- Установите IBulletFormat::set_Type в значение BulletType::Picture.
- Назначьте изображение через ISlidesPicture::set_Image и задайте высоту маркера.
- Добавьте абзац в текстовый фрейм.
- Сохраните изменённую презентацию.
Этот пример на C++ создаёт картинку‑маркер:
#include <DOM/BulletType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IImageCollection.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <IImage.h>
#include <Util/Images.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto bulletImage = Images::FromFile(u"bullets.png");
auto presentationImage = presentation->get_Images()->AddImage(bulletImage);
bulletImage->Dispose();
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 200, 200, 400, 200);
auto textFrame = shape->get_TextFrame();
textFrame->get_Paragraphs()->Clear();
auto paragraph = MakeObject<Paragraph>();
paragraph->set_Text(u"Welcome to Aspose.Slides");
paragraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Picture);
paragraph->get_ParagraphFormat()->get_Bullet()->get_Picture()->set_Image(presentationImage);
paragraph->get_ParagraphFormat()->get_Bullet()->set_Height(100);
textFrame->get_Paragraphs()->Add(paragraph);
presentation->Save(u"picture_bullet.pptx", SaveFormat::Pptx);
presentation->Save(u"picture_bullet.ppt", SaveFormat::Ppt);
presentation->Dispose();
Создание многоуровневого списка
Установите IParagraphFormat::set_Depth , чтобы разместить абзацы на разных уровнях списка. Верхний уровень имеет глубину 0.
- Создайте Presentation и получите слайд.
- Добавьте IAutoShape , затем очистите абзац по умолчанию из его текстового фрейма.
- Создайте четыре абзаца и настройте их символы маркеров.
- Установите их значения IParagraphFormat::set_Depth в
0,1,2и3. - Добавьте абзацы в текстовый фрейм и сохраните презентацию.
Этот пример на C++ создаёт четырёхуровневый маркированный список:
#include <DOM/BulletType.h>
#include <DOM/FillType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
#include <system/convert.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 200, 200, 400, 200);
auto textFrame = shape->get_TextFrame();
textFrame->get_Paragraphs()->Clear();
auto firstParagraph = MakeObject<Paragraph>();
firstParagraph->set_Text(u"Content");
firstParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Symbol);
firstParagraph->get_ParagraphFormat()->get_Bullet()->set_Char(Convert::ToChar(0x2022));
firstParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
firstParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
firstParagraph->get_ParagraphFormat()->set_Depth(0);
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->set_Text(u"Second level");
secondParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Symbol);
secondParagraph->get_ParagraphFormat()->get_Bullet()->set_Char(u'-');
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
secondParagraph->get_ParagraphFormat()->set_Depth(1);
auto thirdParagraph = MakeObject<Paragraph>();
thirdParagraph->set_Text(u"Third level");
thirdParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Symbol);
thirdParagraph->get_ParagraphFormat()->get_Bullet()->set_Char(Convert::ToChar(0x2022));
thirdParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
thirdParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
thirdParagraph->get_ParagraphFormat()->set_Depth(2);
auto fourthParagraph = MakeObject<Paragraph>();
fourthParagraph->set_Text(u"Fourth level");
fourthParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Symbol);
fourthParagraph->get_ParagraphFormat()->get_Bullet()->set_Char(u'-');
fourthParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
fourthParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
fourthParagraph->get_ParagraphFormat()->set_Depth(3);
textFrame->get_Paragraphs()->Add(firstParagraph);
textFrame->get_Paragraphs()->Add(secondParagraph);
textFrame->get_Paragraphs()->Add(thirdParagraph);
textFrame->get_Paragraphs()->Add(fourthParagraph);
presentation->Save(u"multilevel_list.pptx", SaveFormat::Pptx);
presentation->Dispose();
Начало нумерованных пунктов списка со своих значений
Используйте IBulletFormat::set_NumberedBulletStartWith , чтобы задать начальный номер, отображаемый для нумерованного абзаца.
- Создайте Presentation и добавьте IAutoShape на слайд.
- Очистите абзац по умолчанию из текстового фрейма формы.
- Создайте три нумерованных абзаца.
- Установите IBulletFormat::set_NumberedBulletStartWith в
2,3и7для соответствующих абзацев. - Добавьте абзацы в текстовый фрейм и сохраните презентацию.
Этот пример на C++ задаёт пользовательский начальный номер для каждого абзаца:
#include <DOM/BulletType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 200, 200, 400, 200);
auto textFrame = shape->get_TextFrame();
textFrame->get_Paragraphs()->Clear();
auto firstParagraph = MakeObject<Paragraph>();
firstParagraph->set_Text(u"Start at 2");
firstParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Numbered);
firstParagraph->get_ParagraphFormat()->get_Bullet()->set_NumberedBulletStartWith(2);
textFrame->get_Paragraphs()->Add(firstParagraph);
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->set_Text(u"Start at 3");
secondParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Numbered);
secondParagraph->get_ParagraphFormat()->get_Bullet()->set_NumberedBulletStartWith(3);
textFrame->get_Paragraphs()->Add(secondParagraph);
auto thirdParagraph = MakeObject<Paragraph>();
thirdParagraph->set_Text(u"Start at 7");
thirdParagraph->get_ParagraphFormat()->get_Bullet()->set_Type(BulletType::Numbered);
thirdParagraph->get_ParagraphFormat()->get_Bullet()->set_NumberedBulletStartWith(7);
textFrame->get_Paragraphs()->Add(thirdParagraph);
presentation->Save(u"custom_numbered_list.pptx", SaveFormat::Pptx);
presentation->Dispose();
Управление макетом абзаца и конечными свойствами
Установка отступа первой строки
Используйте IParagraphFormat::set_Indent , чтобы управлять отступом первой строки абзаца. Этот метод перемещает только первую строку относительно левого поля абзаца. Положительное значение сдвигает первую строку вправо, остальные строки остаются выровненными по телу абзаца.
Используйте IParagraphFormat::set_MarginLeft , когда нужно переместить весь абзац. Используйте IParagraphFormat::set_Indent , когда нужно переместить только первую строку.
Пример ниже создаёт несколько абзацев и применяет разные значения IParagraphFormat::set_Indent , чтобы продемонстрировать влияние отступа первой строки на макет абзаца.
- Создайте экземпляр класса Presentation.
- Получите целевой слайд.
- Добавьте прямоугольную IAutoShape на слайд.
- Получите ITextFrame формы и удалите абзац по умолчанию.
- Создайте несколько абзацев и задайте им разные значения IParagraphFormat::set_Indent .
- Добавьте абзацы в текстовый фрейм.
- Сохраните изменённую презентацию.
Этот код показывает, как задать отступ абзаца:
#include <DOM/FillType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <DOM/TextAutofitType.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 50, 50, 420, 220);
shape->get_FillFormat()->set_FillType(FillType::NoFill);
shape->get_LineFormat()->get_FillFormat()->set_FillType(FillType::Solid);
shape->get_LineFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Gray());
auto textFrame = shape->get_TextFrame();
textFrame->get_TextFrameFormat()->set_AutofitType(TextAutofitType::Shape);
textFrame->get_Paragraphs()->Clear();
auto firstParagraph = MakeObject<Paragraph>();
firstParagraph->set_Text(u"No first-line indent. Wrapped lines start at the same position as the first line.");
firstParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
firstParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
firstParagraph->get_ParagraphFormat()->set_MarginLeft(20);
firstParagraph->get_ParagraphFormat()->set_Indent(0);
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->set_Text(u"First-line indent of 20 points. The first line moves to the right, while wrapped lines remain aligned to the paragraph body.");
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
secondParagraph->get_ParagraphFormat()->set_MarginLeft(20);
secondParagraph->get_ParagraphFormat()->set_Indent(20);
auto thirdParagraph = MakeObject<Paragraph>();
thirdParagraph->set_Text(u"First-line indent of 40 points. This paragraph shows a larger first-line offset to make the effect easier to see.");
thirdParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
thirdParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
thirdParagraph->get_ParagraphFormat()->set_MarginLeft(20);
thirdParagraph->get_ParagraphFormat()->set_Indent(40);
textFrame->get_Paragraphs()->Add(firstParagraph);
textFrame->get_Paragraphs()->Add(secondParagraph);
textFrame->get_Paragraphs()->Add(thirdParagraph);
presentation->Save(u"paragraph_indent.pptx", SaveFormat::Pptx);
presentation->Dispose();
Результат:

Установка висячего отступа
Висячий отступ — это макет абзаца, при котором первая строка начинается левее остальных строк. В Aspose.Slides этот эффект создаётся с помощью IParagraphFormat::set_Indent. Установите отрицательное значение отступа, чтобы сдвинуть первую строку влево относительно тела абзаца.
На практике IParagraphFormat::set_MarginLeft определяет левую позицию тела абзаца, а IParagraphFormat::set_Indent задаёт позицию первой строки относительно этого поля. Чтобы создать висячий отступ, задайте положительное значение margin-left и отрицательное значение indent.
Это форматирование удобно для библиографий, ссылок, глоссариев и других абзацев, где строки‑переносы должны выравниваться по телу абзаца, а не под первым символом первой строки.
- Создайте экземпляр класса Presentation .
- Получите целевой слайд.
- Добавьте прямоугольную IAutoShape на слайд.
- Получите ITextFrame формы и удалите абзац по умолчанию.
- Создайте абзацы и задайте каждому положительное значение IParagraphFormat::set_MarginLeft .
- Установите отрицательное значение IParagraphFormat::set_Indent , чтобы создать эффект висячего отступа.
- Добавьте абзацы в текстовый фрейм.
- Сохраните изменённую презентацию.
Этот код показывает, как задать висячий отступ для абзаца:
#include <DOM/FillType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <DOM/TextAutofitType.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 50, 50, 420, 220);
shape->get_FillFormat()->set_FillType(FillType::NoFill);
shape->get_LineFormat()->get_FillFormat()->set_FillType(FillType::Solid);
shape->get_LineFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Gray());
auto textFrame = shape->get_TextFrame();
textFrame->get_TextFrameFormat()->set_AutofitType(TextAutofitType::Shape);
textFrame->get_Paragraphs()->Clear();
auto firstParagraph = MakeObject<Paragraph>();
firstParagraph->set_Text(u"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->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
firstParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
firstParagraph->get_ParagraphFormat()->set_MarginLeft(40);
firstParagraph->get_ParagraphFormat()->set_Indent(-20);
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->set_Text(u"This second example uses a deeper hanging indent so the difference between the first line and the wrapped lines is easier to compare.");
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->set_FillType(FillType::Solid);
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->get_FillFormat()->get_SolidFillColor()->set_Color(Color::get_Black());
secondParagraph->get_ParagraphFormat()->set_MarginLeft(60);
secondParagraph->get_ParagraphFormat()->set_Indent(-30);
textFrame->get_Paragraphs()->Add(firstParagraph);
textFrame->get_Paragraphs()->Add(secondParagraph);
presentation->Save(u"hanging_indent.pptx", SaveFormat::Pptx);
presentation->Dispose();
Результат:

Установка свойств завершающего фрагмента абзаца
IParagraph::set_EndParagraphPortionFormat управляет форматированием конечного маркера абзаца. В следующем примере задаётся размер шрифта и латинский шрифт конечному маркеру второго абзаца:
- Загрузите Presentation и получите слайд.
- Добавьте IAutoShape и очистите его абзац по умолчанию.
- Создайте два абзаца и добавьте к ним текстовые фрагменты.
- Создайте PortionFormat для конечного маркера второго абзаца.
- Задайте IBasePortionFormat::set_FontHeight и IBasePortionFormat::set_LatinFont .
- Примените формат через IParagraph::set_EndParagraphPortionFormat и сохраните презентацию.
#include <DOM/Fonts/FontData.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/IPortionCollection.h>
#include <DOM/Paragraph.h>
#include <DOM/Portion.h>
#include <DOM/PortionFormat.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>(u"Test.pptx");
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 10, 10, 200, 250);
auto textFrame = shape->get_TextFrame();
textFrame->get_Paragraphs()->Clear();
auto firstParagraph = MakeObject<Paragraph>();
firstParagraph->get_Portions()->Add(MakeObject<Portion>(u"Sample text"));
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->get_Portions()->Add(MakeObject<Portion>(u"Sample text 2"));
auto endParagraphFormat = MakeObject<PortionFormat>();
endParagraphFormat->set_FontHeight(48);
endParagraphFormat->set_LatinFont(MakeObject<FontData>(u"Times New Roman"));
secondParagraph->set_EndParagraphPortionFormat(endParagraphFormat);
textFrame->get_Paragraphs()->Add(firstParagraph);
textFrame->get_Paragraphs()->Add(secondParagraph);
presentation->Save(u"end_paragraph_format.pptx", SaveFormat::Pptx);
presentation->Dispose();
Подсчёт отрисованных строк
Для правил абзаца, влияющих на автоматический перенос и пунктуацию в конце строк, см. Управление разрывом строк и Управление висячей пунктуацией.
Используйте IParagraph::GetLinesCount , чтобы подсчитать строки, занимаемые абзацем после компоновки текста, включая автоматический перенос. Это полезно при проверке длины текста и компоновки в шаблонах презентаций.
Абзац — это один элемент в ITextFrame::get_Paragraphs, и он может занимать несколько отрисованных строк. Явный разрыв строки внутри абзаца заставляет перейти на новую строку без создания нового абзаца. Автоматический перенос создаёт строки в зависимости от доступной ширины, не вставляя явные разрывы в текст. Поэтому подсчёт абзацев или символов разрыва строки не даёт количества отрисованных строк.
Следующий пример создаёт текстовую форму, подсчитывает её строки, сужает форму, а затем заменяет текст более короткой строкой. Перенос включён, а автоподгонка отключена, поэтому ширина формы управляет переносом без автоматического сжатия текста или изменения размеров формы. Размеры формы указаны в пунктах. В конце пример добавляет ещё один абзац и суммирует количества строк по всему текстовому фрейму.
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/NullableBool.h>
#include <DOM/Paragraph.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <DOM/TextAutofitType.h>
#include <system/console.h>
using namespace Aspose::Slides;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 50, 50, 400, 200);
auto textFrame = shape->get_TextFrame();
textFrame->get_TextFrameFormat()->set_WrapText(NullableBool::True);
textFrame->get_TextFrameFormat()->set_AutofitType(TextAutofitType::None);
auto paragraph = textFrame->get_Paragraph(0);
paragraph->get_ParagraphFormat()->get_DefaultPortionFormat()->set_FontHeight(20);
paragraph->set_Text(u"This text demonstrates how automatic wrapping changes the number of rendered lines.");
Console::WriteLine(u"Original width: {0}", paragraph->GetLinesCount());
shape->set_Width(150);
Console::WriteLine(u"Narrower shape: {0}", paragraph->GetLinesCount());
paragraph->set_Text(u"Short text.");
Console::WriteLine(u"Shorter text: {0}", paragraph->GetLinesCount());
auto secondParagraph = MakeObject<Paragraph>();
secondParagraph->set_Text(u"Another paragraph.");
secondParagraph->get_ParagraphFormat()->get_DefaultPortionFormat()->set_FontHeight(20);
textFrame->get_Paragraphs()->Add(secondParagraph);
auto totalLineCount = 0;
for (auto currentParagraph : textFrame->get_Paragraphs())
{
totalLineCount += currentParagraph->GetLinesCount();
}
Console::WriteLine(u"Total lines in the text frame: {0}", totalLineCount);
presentation->Dispose();
С этим текстом и этими размерами сужение формы увеличивает количество строк, а замена текста короткой строкой уменьшает его. Точные подсчёты могут различаться в зависимости от доступных шрифтов и их подстановки, размера шрифта, полей, отступов, переноса и настроек автоподгонки. Используйте шрифты и настройки компоновки, предназначенные для целевой среды, при проверке шаблона.
Само количество строк не определяет, переполняет ли текст свой контейнер. Важны доступная высота, высота строк, интервалы между абзацами и строками, а также поведение автоподгонки; даже одна строка может превысить доступную ширину, если перенос отключён.
Импорт и экспорт содержимого абзацев
Импорт HTML‑текста в абзацы
Используйте IParagraphCollection::AddFromHtml , чтобы преобразовать разметку HTML в абзацы и фрагменты в текстовом фрейме.
- Создайте экземпляр класса Presentation .
- Получите слайд и добавьте IAutoShape .
- Получите ITextFrame формы и очистите её абзац по умолчанию.
- Прочитайте исходный HTML‑файл.
- Передайте строку HTML в IParagraphCollection::AddFromHtml .
- Сохраните изменённую презентацию.
Этот пример на C++ импортирует HTML в текстовый фрейм:
#include <DOM/FillType.h>
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/ISlideSize.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <system/io/stream_reader.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::IO;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto slideSize = presentation->get_SlideSize()->get_Size();
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 10, 10, slideSize.get_Width() - 20, slideSize.get_Height() - 20);
shape->get_FillFormat()->set_FillType(FillType::NoFill);
shape->get_TextFrame()->get_Paragraphs()->Clear();
auto reader = MakeObject<StreamReader>(u"file.html");
auto html = reader->ReadToEnd();
reader->Close();
shape->get_TextFrame()->get_Paragraphs()->AddFromHtml(html);
presentation->Save(u"html_text.pptx", SaveFormat::Pptx);
presentation->Dispose();
Экспорт текста абзаца в HTML
Используйте IParagraphCollection::ExportToHtml , чтобы экспортировать выбранный диапазон абзацев в виде HTML.
- Создайте экземпляр класса Presentation и загрузите нужную презентацию.
- Получите слайд и найдите IAutoShape , содержащий текст.
- Получите ITextFrame формы.
- Вызовите IParagraphCollection::ExportToHtml с индексом начального абзаца и количеством экспортируемых абзацев.
- Запишите полученную строку HTML в файл.
Этот пример на C++ экспортирует все абзацы из первой текстовой формы:
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Presentation.h>
#include <system/console.h>
#include <system/io/stream_writer.h>
#include <system/object_ext.h>
#include <system/text/encoding.h>
using namespace Aspose::Slides;
using namespace System;
using namespace System::IO;
using namespace System::Text;
auto presentation = MakeObject<Presentation>(u"ExportingHTMLText.pptx");
auto shape = presentation->get_Slide(0)->get_Shape(0);
auto textShape = AsCast<IAutoShape>(shape);
if (textShape != nullptr && textShape->get_TextFrame() != nullptr)
{
auto paragraphs = textShape->get_TextFrame()->get_Paragraphs();
auto html = paragraphs->ExportToHtml(0, paragraphs->get_Count(), nullptr);
auto writer = MakeObject<StreamWriter>(u"paragraphs.html", false, Encoding::get_UTF8());
writer->Write(html);
writer->Close();
}
else
{
Console::WriteLine(u"The first shape is not a text shape.");
}
presentation->Dispose();
Отрисовка абзаца в виде изображения
IParagraph::GetImage отрисовывает отдельный абзац напрямую и возвращает IImage. Сохраните результат в файл или поток с помощью IImage::Save. Отрисовывать содержащую форму или вручную обрезать bitmap не требуется.
IParagraph::GetImage может вернуть nullptr, если абзац не найден в родительской коллекции, не имеет валидных границ отрисовки или не может быть отрисован. Проверьте результат перед сохранением и освободите полученное изображение после использования.
Отрисовка абзаца в масштабе по умолчанию
Предположим, у нас есть файл презентации sample.pptx с одним слайдом, где первая форма — это текстовое поле, содержащее три абзаца.

Следующий пример отрисовывает второй абзац в обычной текстовой форме в масштабе по умолчанию и сохраняет полученное изображение в формате PNG.
#include <DOM/IAutoShape.h>
#include <DOM/IParagraph.h>
#include <DOM/Presentation.h>
#include <IImage.h>
#include <ImageFormat.h>
#include <system/console.h>
#include <system/object_ext.h>
using namespace Aspose::Slides;
using namespace System;
auto presentation = MakeObject<Presentation>(u"sample.pptx");
auto shape = presentation->get_Slide(0)->get_Shape(0);
auto textShape = AsCast<IAutoShape>(shape);
if (textShape != nullptr && textShape->get_TextFrame() != nullptr && textShape->get_TextFrame()->get_Paragraphs()->get_Count() > 1)
{
auto paragraph = textShape->get_TextFrame()->get_Paragraph(1);
auto paragraphImage = paragraph->GetImage();
if (paragraphImage != nullptr)
{
paragraphImage->Save(u"paragraph.png", ImageFormat::Png);
paragraphImage->Dispose();
}
else
{
Console::WriteLine(u"The paragraph could not be rendered.");
}
}
else
{
Console::WriteLine(u"The expected text shape or paragraph was not found.");
}
presentation->Dispose();
Результат:

Отрисовка абзаца в ячейке таблицы с масштабированием
Используйте перегрузку IParagraph::GetImage , принимающая параметры float scaleX и float scaleY , чтобы задать горизонтальные и вертикальные коэффициенты масштабирования. Следующий пример создаёт таблицу, отрисовывает абзац в её первой ячейке с двойной шириной и высотой по сравнению с масштабом по умолчанию и сохраняет результат в виде PNG‑изображения.
#include <DOM/IParagraph.h>
#include <DOM/Presentation.h>
#include <DOM/Table/ITable.h>
#include <IImage.h>
#include <ImageFormat.h>
#include <system/array.h>
#include <system/console.h>
using namespace Aspose::Slides;
using namespace System;
auto scaleX = 2.0f;
auto scaleY = 2.0f;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto table = slide->get_Shapes()->AddTable(50, 50, MakeArray<double>({300}), MakeArray<double>({80}));
auto paragraph = table->idx_get(0, 0)->get_TextFrame()->get_Paragraph(0);
paragraph->set_Text(u"Text in a table cell");
auto paragraphImage = paragraph->GetImage(scaleX, scaleY);
if (paragraphImage != nullptr)
{
paragraphImage->Save(u"table_paragraph.png", ImageFormat::Png);
paragraphImage->Dispose();
}
else
{
Console::WriteLine(u"The paragraph could not be rendered.");
}
presentation->Dispose();
Коэффициент масштабирования 1 сохраняет соответствующую ось в её стандартном пиксельном размере. Например, 2 для обеих осей создаёт изображение, ширина и высота которого примерно вдвое превышают стандартные размеры, что приводит к четырёмкратному количеству пикселей. Большие коэффициенты обычно дают более чёткий текст для увеличения или вывода в высоком разрешении, но также увеличивают потребление памяти и размер файла. Коэффициенты ниже 1 дают более маленькие изображения с меньшей детализацией. Используйте одинаковые коэффициенты, чтобы сохранить пропорции абзаца; разные горизонтальный и вертикальный коэффициенты растягивают вывод независимо.
Отрисовка всей формы с помощью IShape::GetImage остаётся полезной, когда в выводе должны присутствовать заливка формы, граница или другой визуальный контекст. Для изображения только абзаца используйте IParagraph::GetImage .
FAQ
Могу ли я полностью отключить перенос строк внутри текстового фрейма?
Да. Используйте ITextFrameFormat::set_WrapText , чтобы отключить перенос, чтобы строки не разрывались у краёв текстового фрейма.
Как получить точные границы конкретного абзаца на слайде?
Используйте IParagraph::GetRect , чтобы получить ограничивающий прямоугольник абзаца. IPortion::GetRect предоставляет границы отдельного фрагмента.
Где управляется выравнивание абзаца (по левому, правому краю, по центру или по ширине)?
IParagraphFormat::set_Alignment — это настройка уровня абзаца и применяется к всему абзацу независимо от форматирования отдельных фрагментов.
Чтобы вертикально выровнять фрагменты разного размера шрифта в каждой строке, см. Align Fonts Within a Line.
Можно ли задать язык проверки правописания для части абзаца?
Да. Используйте IBasePortionFormat::set_LanguageId для отдельных фрагментов, чтобы один абзац мог содержать текст на нескольких языках.