使用 C++ 管理 PowerPoint 文本段落
概述
Aspose.Slides for C++ 将文本表示为文本框、段落和文本段的层次结构:
- ITextFrame 表示形状中的文本容器,并提供对其段落集合的访问。
- IParagraph 表示文本框中的一个段落,并提供对其文本段和段落级格式的访问。
- IPortion 表示段落内的一个文本运行。每个文本段可以拥有自己的文本和字符级格式。
因此,一个段落可以通过使用多个文本段来包含具有不同字体、颜色、大小和其他格式的文本。
创建并格式化段落
在形状的文本框中创建段落,并使用文本段来格式化各个文本运行。本节展示如何在每个段落中组合多个文本段,并应用不同的颜色、字体大小和样式。
创建包含多个文本段的段落
以下 C++ 示例在其 IParagraph::get_Portions 集合中创建了三个段落,每个段落包含三个文本运行。它复用了默认段落及其空文本段,然后添加其余的段落和文本段。通过 IPortion::get_PortionFormat 应用格式:每个段落的第一个文本段为红色、粗体、15 磅;第二个为蓝色、斜体、18 磅。第三个文本段保留默认格式:
#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 (auto paragraphIndex = 0; paragraphIndex < paragraphCount; paragraphIndex++)
{
auto paragraph = textFrame->get_Paragraph(paragraphIndex);
auto portionCount = paragraph->get_Portions()->get_Count();
for (auto 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 定义。
此 C++ 示例向同一文本框添加符号项目符号和编号项。IBulletFormat::set_Type 选择项目符号类型,IBulletFormat::set_Char 提供符号,而 IBulletFormat::set_NumberedBulletStyle 选择编号样式。两项均使用黑色项目符号,高度为 100%,段落缩进为 25 磅:
#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();
使用图片项目符号
图片项目符号允许使用自定义图像代替符号或数字。
示例需要工作目录中存在 bullets.png。此 C++ 示例将图像作为 IPPImage 添加到演示文稿的图像集合,并将其用作段落项目符号。它将 IBulletFormat::set_Type 设置为使用图片项目符号,并通过 IBulletFormat::get_Picture 分配图像。IBulletFormat::set_Height 设置为 100% 以相对于段落文本大小调整项目符号:
#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。
此 C++ 示例为四个段落分别设置 0 到 3 的 IParagraphFormat::set_Depth 值,在同一文本框中创建层级结构。每个段落使用符号项目符号,IBulletFormat::set_Char 在圆形项目符号和连字符之间交替,以区分相邻层级:
#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 设置编号段落的起始编号。
此 C++ 示例将 IBulletFormat::set_Type 设置为使用编号,并为三个段落分别分配 2、3、7 的 IBulletFormat::set_NumberedBulletStartWith 值。每个段落的起始值独立配置,使显示的编号可以跳过数值:
#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_MarginLeft 为 20 磅,并将 IParagraphFormat::set_Indent 分别设为 0、20、40 磅。首行起始偏移逐渐增大,而换行行保持相同的左边距:
#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 定义首行相对于该边距的位置。要创建悬挂缩进,设置正的 MarginLeft 值和负的 Indent 值。
此布局常用于参考文献、词汇表条目等需要换行行在段落主体下方对齐的段落。
以下 C++ 示例将 IParagraphFormat::set_MarginLeft 分别设为 40 和 60 磅,配合 IParagraphFormat::set_Indent 设为 -20 和 -30 磅。每个段落的首行均位于换行行左侧;第二段落的悬挂缩进更深:
#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 方法控制段落结束标记的格式。示例加载包含至少一张幻灯片的 Test.pptx。下面的示例创建一个 PortionFormat ,将 IBasePortionFormat::set_FontHeight 设置为 48 磅, 将 IBasePortionFormat::set_LatinFont 设置为 Times New Roman。随后将该格式分配给第二段落的结束标记,保持可见文本段不变:
#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();
统计渲染行数
有关影响自动换行和行尾标点的段落规则,请参阅 Control Line Breaking 和 Control Hanging Punctuation。
使用 IParagraph::GetLinesCount 可统计段落在文本布局后占用的行数,包括自动换行。这在检查演示模板中文本长度和布局时非常有用。
段落是 ITextFrame::get_Paragraphs 中的一个项目,可能占据多行渲染。段落内的显式换行符会强制新行,但不会创建新段落。自动换行根据可用宽度生成行,而不向文本插入显式换行符。因此,仅统计段落或换行字符并不能得到渲染行数。
下面的示例创建一个文本形状,统计其行数,随后缩窄形状宽度,再将文本替换为更短的字符串。示例启用 ITextFrameFormat::set_WrapText 并禁用 ITextFrameFormat::set_AutofitType,使形状宽度控制换行,而不自动缩小文本或调整形状大小。每次测量均使用 IParagraph::GetLinesCount。形状尺寸以磅为单位。最后,示例添加另一段落并对整个文本框的行数求和。
#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 将文本导入演示文稿,或将现有段落导出供外部使用。本节还展示如何将单独段落渲染为图像,包括表格单元格中的段落。
将 HTML 文本导入段落
使用 ParagraphCollection::AddFromHtml 将 HTML 标记转换为文本框中的段落和文本段。
此 C++ 示例从文件读取 HTML 并将标记传递给 ParagraphCollection::AddFromHtml。它清除文本框的默认段落,使框仅包含导入的内容。矩形形状在幻灯片每侧留有 10 磅的边距:
#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
使用 ParagraphCollection::ExportToHtml 将选定范围的段落导出为 HTML。当在网站上复用演示文稿文本时,您可能希望保留本地强调而不携带演示文稿的字体、大小或文本框样式。通过设置 TextToHtmlConversionOptions::set_TextInheritanceLimit 可以控制导出器遵循格式继承的深度。
下载 示例演示文稿 并放置在应用程序的工作目录中。其第一张幻灯片包含一个文本形状,文本为 “Inherited text; explicit red 18pt”。输入有意使用了多层格式:
- 演示文稿的默认文本样式提供 Calibri 字体,大小为 28 pt。
- 文本框的一级文本样式提供蓝色文本和斜体。
- 段落显式设置粗体。
- 第二个文本段 “explicit red 18pt” 显式设置红色文本和 18 pt 大小。
以下示例将相同段落导出三次。它将 TextToHtmlConversionOptions 传递给导出方法,并将每个结果写入单独的 UTF-8 HTML 文件:
#include <DOM/IAutoShape.h>
#include <DOM/IParagraphCollection.h>
#include <DOM/Presentation.h>
#include <Export/TextInheritanceLimit.h>
#include <Export/TextToHtmlConversionOptions.h>
#include <system/array.h>
#include <system/console.h>
#include <system/io/file.h>
#include <system/object_ext.h>
#include <system/text/encoding.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::IO;
using namespace System::Text;
auto presentation = MakeObject<Presentation>(u"text-inheritance.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 modes = MakeArray<TextInheritanceLimit>({TextInheritanceLimit::All, TextInheritanceLimit::TextBox, TextInheritanceLimit::ParagraphOnly});
auto fileNames = MakeArray<String>({u"All.html", u"TextBox.html", u"ParagraphOnly.html"});
for (auto i = 0; i < modes->get_Length(); i++)
{
auto options = MakeObject<TextToHtmlConversionOptions>();
options->set_TextInheritanceLimit(modes[i]);
auto html = paragraphs->ExportToHtml(0, paragraphs->get_Count(), options);
File::WriteAllText(fileNames[i], html, Encoding::get_UTF8());
}
}
else
{
Console::WriteLine(u"The first shape is not a text shape.");
}
presentation->Dispose();
生成的 HTML 为第一段(“Inherited text; ”)包含以下 CSS。表格列出了相关声明,其他生成的属性为简洁起见已省略。
| 输出 | 第一段的相关 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 可能返回 nullptr。在保存之前检查返回值,并在使用后释放图像。
以默认比例渲染段落
示例使用 sample.pptx,该演示文稿包含一张幻灯片,第一形状为包含三个段落的文本框。

以下示例在索引为 1 的位置选择第二段落,并在不提供比例参数的情况下调用 IParagraph::GetImage。它检查形状是否包含所需段落,并在渲染返回图像后调用 IImage::Save 将其以 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();
结果:

在表格单元格中渲染段落并缩放
使用接受 float scaleX 和 float scaleY 参数的 IParagraph::GetImage 重载来设置水平和垂直缩放因子。以下示例创建表格,在其第一个单元格中以默认宽度和高度的两倍渲染段落,并将结果保存为 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。
常见问题
我可以完全禁用文本框内的换行吗?
可以。使用 ITextFrameFormat::set_WrapText 禁用换行,使行不会在文本框边缘断开。
如何获取特定段落在幻灯片上的确切边界?
使用 IParagraph::GetRect 获取段落的边界矩形。IPortion::GetRect 提供单个文本段的边界。
段落对齐(左、右、居中或两端对齐)在哪里控制?
IParagraphFormat::set_Alignment 是段落级设置,适用于整个段落,而不受单个文本段格式的影响。
要在每行中垂直对齐不同字号的文本段,请参阅 Align Fonts Within a Line。
我可以为段落的部分设置校对语言吗?
可以。使用 IBasePortionFormat::set_LanguageId 为单独的文本段设置语言,这样一个段落可以包含多种语言的文本。