Управление текстовыми абзацами PowerPoint в .NET
Обзор
Aspose.Slides для .NET представляет текст как иерархию текстовых фреймов, абзацев и фрагментов:
- ITextFrame представляет контейнер текста в фигуре и предоставляет доступ к её коллекции абзацев.
- IParagraph представляет один абзац в текстовом фрейме и предоставляет доступ к его фрагментам и форматированию уровня абзаца.
- IPortion представляет текстовый отрезок внутри абзаца. Каждый фрагмент может иметь собственный текст и форматирование на уровне символов.
Таким образом, абзац может содержать текст с различными шрифтами, цветами, размерами и другим форматированием, используя несколько фрагментов.
Создание и форматирование абзацев
Создавайте абзацы в текстовом фрейме фигуры и используйте фрагменты для форматирования отдельных текстовых отрезков. В этом разделе показано, как комбинировать несколько фрагментов в каждом абзаце и применять разные цвета, размеры шрифтов и стили.
Создание абзацев с несколькими фрагментами
Следующий пример на C# создает три абзаца, каждый из которых содержит три текстовых отрезка в своей коллекции IParagraph.Portions . Он повторно использует абзац по умолчанию и его пустой фрагмент, затем добавляет оставшиеся абзацы и фрагменты. Форматирование применяется через IPortion.PortionFormat: первый фрагмент в каждом абзаце красный, полужирный и 15 пунктов; второй — синий, курсив и 18 пунктов. Третий фрагмент сохраняет форматирование по умолчанию:
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 50, 150, 300, 150);
var textFrame = shape.TextFrame;
var firstParagraph = textFrame.Paragraphs[0];
firstParagraph.Portions.Add(new Portion());
firstParagraph.Portions.Add(new Portion());
var secondParagraph = new Paragraph();
secondParagraph.Portions.Add(new Portion());
secondParagraph.Portions.Add(new Portion());
secondParagraph.Portions.Add(new Portion());
textFrame.Paragraphs.Add(secondParagraph);
var thirdParagraph = new Paragraph();
thirdParagraph.Portions.Add(new Portion());
thirdParagraph.Portions.Add(new Portion());
thirdParagraph.Portions.Add(new Portion());
textFrame.Paragraphs.Add(thirdParagraph);
var paragraphCount = textFrame.Paragraphs.Count;
for (var paragraphIndex = 0; paragraphIndex < paragraphCount; paragraphIndex++)
{
var paragragaph = textFrame.Paragraphs[paragraphIndex];
var portionCount = paragragaph.Portions.Count;
for (var portionIndex = 0; portionIndex < portionCount; portionIndex++)
{
var portion = paragragaph.Portions[portionIndex];
portion.Text = $"Portion {paragraphIndex + 1}.{portionIndex + 1}";
if (portionIndex == 0)
{
portion.PortionFormat.FillFormat.FillType = FillType.Solid;
portion.PortionFormat.FillFormat.SolidFillColor.Color = Color.Red;
portion.PortionFormat.FontBold = NullableBool.True;
portion.PortionFormat.FontHeight = 15;
}
else if (portionIndex == 1)
{
portion.PortionFormat.FillFormat.FillType = FillType.Solid;
portion.PortionFormat.FillFormat.SolidFillColor.Color = Color.Blue;
portion.PortionFormat.FontItalic = NullableBool.True;
portion.PortionFormat.FontHeight = 18;
}
}
}
presentation.Save("paragraphs_with_portions.pptx", SaveFormat.Pptx);
Создание маркированных и нумерованных списков
Организуйте текст абзацев в списки с символами, цифрами или пользовательскими изображениями. Примеры в этом разделе охватывают форматирование маркеров, многомерные списки и пользовательские стартовые номера.
Создание маркированного или нумерованного списка
Маркеры и нумерация упрощают восприятие связанных пунктов. В Aspose.Slides настройки списка определяются через IBulletFormat.
В этом примере на C# добавляются символический маркер и нумерованный элемент в один и тот же текстовый фрейм. IBulletFormat.Type выбирает тип маркера, в то время как IBulletFormat.Char задаёт символ, а IBulletFormat.NumberedBulletStyle выбирает стиль нумерации. Оба элемента используют чёрные маркеры высотой 100 % и отступ абзаца 25 пунктов:
using System;
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
var textFrame = shape.TextFrame;
textFrame.Paragraphs.Clear();
var symbolParagraph = new Paragraph { Text = "Welcome to Aspose.Slides" };
symbolParagraph.ParagraphFormat.Bullet.Type = BulletType.Symbol;
symbolParagraph.ParagraphFormat.Bullet.Char = Convert.ToChar(0x2022);
symbolParagraph.ParagraphFormat.Indent = 25;
symbolParagraph.ParagraphFormat.Bullet.Color.ColorType = ColorType.RGB;
symbolParagraph.ParagraphFormat.Bullet.Color.Color = Color.Black;
symbolParagraph.ParagraphFormat.Bullet.IsBulletHardColor = NullableBool.True;
symbolParagraph.ParagraphFormat.Bullet.Height = 100;
textFrame.Paragraphs.Add(symbolParagraph);
var numberedParagraph = new Paragraph { Text = "This is a numbered item" };
numberedParagraph.ParagraphFormat.Bullet.Type = BulletType.Numbered;
numberedParagraph.ParagraphFormat.Bullet.NumberedBulletStyle = NumberedBulletStyle.BulletCircleNumWDBlackPlain;
numberedParagraph.ParagraphFormat.Indent = 25;
numberedParagraph.ParagraphFormat.Bullet.Color.ColorType = ColorType.RGB;
numberedParagraph.ParagraphFormat.Bullet.Color.Color = Color.Black;
numberedParagraph.ParagraphFormat.Bullet.IsBulletHardColor = NullableBool.True;
numberedParagraph.ParagraphFormat.Bullet.Height = 100;
textFrame.Paragraphs.Add(numberedParagraph);
presentation.Save("bulleted_and_numbered_list.pptx", SaveFormat.Pptx);
Использование изображений в качестве маркеров
Маркированные изображения позволяют использовать пользовательское изображение вместо символа или цифры.
В этом примере на C# изображение добавляется в коллекцию изображений презентации как IPPImage и используется в качестве маркера абзаца. Он устанавливает IBulletFormat.Type для использования маркера‑изображения и задаёт изображение через IBulletFormat.Picture. IBulletFormat.Height устанавливается в 100 % для масштабирования маркера относительно текста абзаца:
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
using var bulletImage = Images.FromFile("bullets.png");
var presentationImage = presentation.Images.AddImage(bulletImage);
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
var textFrame = shape.TextFrame;
textFrame.Paragraphs.Clear();
var paragraph = new Paragraph { Text = "Welcome to Aspose.Slides" };
paragraph.ParagraphFormat.Bullet.Type = BulletType.Picture;
paragraph.ParagraphFormat.Bullet.Picture.Image = presentationImage;
paragraph.ParagraphFormat.Bullet.Height = 100;
textFrame.Paragraphs.Add(paragraph);
presentation.Save("picture_bullet.pptx", SaveFormat.Pptx);
presentation.Save("picture_bullet.ppt", SaveFormat.Ppt);
Создание многоуровневого списка
Установите IParagraphFormat.Depth , чтобы разместить абзацы на разных уровнях списка. Верхний уровень имеет глубину 0.
В этом примере на C# значения IParagraphFormat.Depth от 0 до 3 назначаются четырём абзацам, создавая иерархию в одном текстовом фрейме. Каждый абзац использует символический маркер, при этом IBulletFormat.Char чередуется между круглым маркером и дефисом для различения смежных уровней:
using System;
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
var textFrame = shape.TextFrame;
textFrame.Paragraphs.Clear();
var firstParagraph = new Paragraph { Text = "Content" };
firstParagraph.ParagraphFormat.Bullet.Type = BulletType.Symbol;
firstParagraph.ParagraphFormat.Bullet.Char = Convert.ToChar(0x2022);
firstParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
firstParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
firstParagraph.ParagraphFormat.Depth = 0;
var secondParagraph = new Paragraph { Text = "Second level" };
secondParagraph.ParagraphFormat.Bullet.Type = BulletType.Symbol;
secondParagraph.ParagraphFormat.Bullet.Char = '-';
secondParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
secondParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
secondParagraph.ParagraphFormat.Depth = 1;
var thirdParagraph = new Paragraph { Text = "Third level" };
thirdParagraph.ParagraphFormat.Bullet.Type = BulletType.Symbol;
thirdParagraph.ParagraphFormat.Bullet.Char = Convert.ToChar(0x2022);
thirdParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
thirdParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
thirdParagraph.ParagraphFormat.Depth = 2;
var fourthParagraph = new Paragraph { Text = "Fourth level" };
fourthParagraph.ParagraphFormat.Bullet.Type = BulletType.Symbol;
fourthParagraph.ParagraphFormat.Bullet.Char = '-';
fourthParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
fourthParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
fourthParagraph.ParagraphFormat.Depth = 3;
textFrame.Paragraphs.Add(firstParagraph);
textFrame.Paragraphs.Add(secondParagraph);
textFrame.Paragraphs.Add(thirdParagraph);
textFrame.Paragraphs.Add(fourthParagraph);
presentation.Save("multilevel_list.pptx", SaveFormat.Pptx);
Начало нумерованных пунктов списка со пользовательских значений
Используйте IBulletFormat.NumberedBulletStartWith , чтобы задать начальное число, отображаемое для нумерованного абзаца.
В этом примере на C# IBulletFormat.Type устанавливается для использования нумерации в трёх абзацах, а IBulletFormat.NumberedBulletStartWith получает значения 2, 3 и 7. Начальное значение задаётся отдельно для каждого абзаца, позволяя пропускать числа в отображаемой нумерации:
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 200, 200, 400, 200);
var textFrame = shape.TextFrame;
textFrame.Paragraphs.Clear();
var firstParagraph = new Paragraph { Text = "Start at 2" };
firstParagraph.ParagraphFormat.Bullet.Type = BulletType.Numbered;
firstParagraph.ParagraphFormat.Bullet.NumberedBulletStartWith = 2;
textFrame.Paragraphs.Add(firstParagraph);
var secondParagraph = new Paragraph { Text = "Start at 3" };
secondParagraph.ParagraphFormat.Bullet.Type = BulletType.Numbered;
secondParagraph.ParagraphFormat.Bullet.NumberedBulletStartWith = 3;
textFrame.Paragraphs.Add(secondParagraph);
var thirdParagraph = new Paragraph { Text = "Start at 7" };
thirdParagraph.ParagraphFormat.Bullet.Type = BulletType.Numbered;
thirdParagraph.ParagraphFormat.Bullet.NumberedBulletStartWith = 7;
textFrame.Paragraphs.Add(thirdParagraph);
presentation.Save("custom_numbered_list.pptx", SaveFormat.Pptx);
Управление макетом абзаца и свойствами окончания
Регулируйте поля и отступы абзаца, чтобы управлять позицией первой строки и перенесённых строк. Вы также можете форматировать знак конца абзаца отдельно от видимых фрагментов текста.
Установка отступа первой строки
Используйте свойство IParagraphFormat.Indent для управления отступом первой строки абзаца. Это свойство смещает только первую строку относительно левого поля абзаца. Положительное значение смещает первую строку вправо, в то время как остальные строки остаются выровненными по телу абзаца.
Используйте IParagraphFormat.MarginLeft , когда требуется переместить весь абзац. Используйте IParagraphFormat.Indent , когда необходимо переместить только первую строку.
В следующем примере трём абзацам задаётся одинаковый IParagraphFormat.MarginLeft в 20 пунктов и значения IParagraphFormat.Indent 0, 20 и 40 пунктов. Первые строки начинаются с постепенно увеличивающихся смещений, в то время как перенесённые строки сохраняют тот же левый отступ:
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 420, 220);
shape.FillFormat.FillType = FillType.NoFill;
shape.LineFormat.FillFormat.FillType = FillType.Solid;
shape.LineFormat.FillFormat.SolidFillColor.Color = Color.Gray;
var textFrame = shape.TextFrame;
textFrame.TextFrameFormat.AutofitType = TextAutofitType.Shape;
textFrame.Paragraphs.Clear();
var firstParagraph = new Paragraph { Text = "No first-line indent. Wrapped lines start at the same position as the first line." };
firstParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
firstParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
firstParagraph.ParagraphFormat.MarginLeft = 20;
firstParagraph.ParagraphFormat.Indent = 0;
var secondParagraph = new Paragraph { Text = "First-line indent of 20 points. The first line moves to the right, while wrapped lines remain aligned to the paragraph body." };
secondParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
secondParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
secondParagraph.ParagraphFormat.MarginLeft = 20;
secondParagraph.ParagraphFormat.Indent = 20;
var thirdParagraph = new Paragraph { Text = "First-line indent of 40 points. This paragraph shows a larger first-line offset to make the effect easier to see." };
thirdParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
thirdParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
thirdParagraph.ParagraphFormat.MarginLeft = 20;
thirdParagraph.ParagraphFormat.Indent = 40;
textFrame.Paragraphs.Add(firstParagraph);
textFrame.Paragraphs.Add(secondParagraph);
textFrame.Paragraphs.Add(thirdParagraph);
presentation.Save("paragraph_indent.pptx", SaveFormat.Pptx);
Результат:

Установка висячего отступа
Висячий отступ — это макет абзаца, при котором первая строка начинается левее остальных строк. В Aspose.Slides этот эффект создаётся с помощью свойства IParagraphFormat.Indent. Установите Indent в отрицательное значение, чтобы переместить первую строку влево относительно тела абзаца.
На практике IParagraphFormat.MarginLeft определяет левую позицию тела абзаца, а IParagraphFormat.Indent задаёт позицию первой строки относительно этого поля. Чтобы создать висячий отступ, установите положительное значение MarginLeft и отрицательное значение Indent.
Такое форматирование полезно для библиографий, ссылок, глоссариев и других абзацев, где перенесённые строки должны выравниваться под телом абзаца, а не под первым символом первой строки.
В следующем примере на C# значения IParagraphFormat.MarginLeft 40 и 60 пунктов сочетаются со значениями IParagraphFormat.Indent -20 и -30 пунктов. В каждом абзаце первая строка начинается левее перенесённых строк; второй абзац имеет более глубокий висячий отступ:
using System.Drawing;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 420, 220);
shape.FillFormat.FillType = FillType.NoFill;
shape.LineFormat.FillFormat.FillType = FillType.Solid;
shape.LineFormat.FillFormat.SolidFillColor.Color = Color.Gray;
var textFrame = shape.TextFrame;
textFrame.TextFrameFormat.AutofitType = TextAutofitType.Shape;
textFrame.Paragraphs.Clear();
var firstParagraph = new Paragraph { Text = "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.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
firstParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
firstParagraph.ParagraphFormat.MarginLeft = 40;
firstParagraph.ParagraphFormat.Indent = -20;
var secondParagraph = new Paragraph { Text = "This second example uses a deeper hanging indent so the difference between the first line and the wrapped lines is easier to compare." };
secondParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.FillType = FillType.Solid;
secondParagraph.ParagraphFormat.DefaultPortionFormat.FillFormat.SolidFillColor.Color = Color.Black;
secondParagraph.ParagraphFormat.MarginLeft = 60;
secondParagraph.ParagraphFormat.Indent = -30;
textFrame.Paragraphs.Add(firstParagraph);
textFrame.Paragraphs.Add(secondParagraph);
presentation.Save("hanging_indent.pptx", SaveFormat.Pptx);
Результат:

Установка свойств завершающего фрагмента абзаца
Свойство IParagraph.EndParagraphPortionFormat управляет форматированием знака окончания абзаца. В следующем примере создаётся PortionFormat с IBasePortionFormat.FontHeight , установленным в 48 пунктов, и IBasePortionFormat.LatinFont , установленным в Times New Roman. Этот формат применяется к знаку окончания второго абзаца, при этом видимые фрагменты текста остаются без изменений:
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation("Test.pptx");
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 10, 10, 200, 250);
var textFrame = shape.TextFrame;
textFrame.Paragraphs.Clear();
var firstParagraph = new Paragraph();
firstParagraph.Portions.Add(new Portion("Sample text"));
var secondParagraph = new Paragraph();
secondParagraph.Portions.Add(new Portion("Sample text 2"));
var endParagraphFormat = new PortionFormat();
endParagraphFormat.FontHeight = 48;
endParagraphFormat.LatinFont = new FontData("Times New Roman");
secondParagraph.EndParagraphPortionFormat = endParagraphFormat;
textFrame.Paragraphs.Add(firstParagraph);
textFrame.Paragraphs.Add(secondParagraph);
presentation.Save("end_paragraph_format.pptx", SaveFormat.Pptx);
Подсчёт отрисованных строк
Для правил абзаца, влияющих на автоматический перенос и пунктуацию в конце строк, см. Управление разрывом строк и Управление висячей пунктуацией.
Используйте IParagraph.GetLinesCount , чтобы подсчитать количество строк, занимаемых абзацем после расположения текста, включая автоматический перенос. Это полезно при проверке длины текста и макета в шаблонах презентаций.
Абзац — это один элемент в ITextFrame.Paragraphs , и он может занимать несколько отрисованных строк. Явный разрыв строки внутри абзаца принудительно создает новую строку без создания отдельного абзаца. Автоматический перенос формирует строки на основе доступной ширины без вставки явных разрывов строки в текст. Поэтому подсчёт абзацев или символов разрыва строк не дает количество отрисованных строк.
В следующем примере создаётся текстовая фигура, подсчитываются её строки, затем фигура сужается, и текст заменяется более короткой строкой. Пример включает ITextFrameFormat.WrapText и отключает ITextFrameFormat.AutofitType , чтобы ширина фигуры контролировала перенос без автоматического уменьшения текста или изменения размеров фигуры. Каждый замер использует IParagraph.GetLinesCount. Размеры фигуры указаны в пунктах. В конце пример добавляет ещё один абзац и суммирует количество строк по всему текстовому фрейму.
using System;
using Aspose.Slides;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 50, 50, 400, 200);
var textFrame = shape.TextFrame;
textFrame.TextFrameFormat.WrapText = NullableBool.True;
textFrame.TextFrameFormat.AutofitType = TextAutofitType.None;
var paragraph = textFrame.Paragraphs[0];
paragraph.ParagraphFormat.DefaultPortionFormat.FontHeight = 20;
paragraph.Text = "This text demonstrates how automatic wrapping changes the number of rendered lines.";
Console.WriteLine($"Original width: {paragraph.GetLinesCount()}");
shape.Width = 150;
Console.WriteLine($"Narrower shape: {paragraph.GetLinesCount()}");
paragraph.Text = "Short text.";
Console.WriteLine($"Shorter text: {paragraph.GetLinesCount()}");
var secondParagraph = new Paragraph { Text = "Another paragraph." };
secondParagraph.ParagraphFormat.DefaultPortionFormat.FontHeight = 20;
textFrame.Paragraphs.Add(secondParagraph);
var totalLineCount = 0;
foreach (var currentParagraph in textFrame.Paragraphs)
{
totalLineCount += currentParagraph.GetLinesCount();
}
Console.WriteLine($"Total lines in the text frame: {totalLineCount}");
При таком тексте и этих размерах сужение фигуры увеличивает количество строк, а замена текста короткой строкой уменьшает его. Точные подсчёты могут варьироваться в зависимости от доступности и подстановки шрифтов, размера шрифта, полей, отступов, переноса и настроек автоподгонки. При проверке шаблона используйте шрифты и настройки макета, предназначенные для целевой среды.
Только количество строк не определяет, выходит ли текст за пределы контейнера. Важны также доступная высота, высота строк, интервалы между абзацами и строками и поведение автоподгонки; даже одна строка может превышать доступную ширину, если перенос отключён.
Импорт и экспорт содержимого абзаца
Используйте HTML для импорта текста в презентацию или экспорта существующих абзацев для использования за её пределами. Этот раздел также показывает, как рендерить отдельные абзацы в виде изображений, включая абзацы в ячейках таблиц.
Импорт текста HTML в абзацы
Используйте ParagraphCollection.AddFromHtml для преобразования разметки HTML в абзацы и фрагменты в текстовом фрейме.
В этом примере на C# HTML читается из файла и передаётся в ParagraphCollection.AddFromHtml. Он очищает абзац по умолчанию в текстовом фрейме, чтобы фрейм содержал только импортированное содержимое. Прямоугольная фигура оставляет отступ в 10 пунктов по каждому краю слайда:
using System.IO;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shapeWidth = presentation.SlideSize.Size.Width - 20;
var shapeHeight = presentation.SlideSize.Size.Height - 20;
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 10, 10, shapeWidth, shapeHeight);
shape.FillFormat.FillType = FillType.NoFill;
shape.TextFrame.Paragraphs.Clear();
using var reader = new StreamReader("file.html");
var html = reader.ReadToEnd();
shape.TextFrame.Paragraphs.AddFromHtml(html);
presentation.Save("html_text.pptx", SaveFormat.Pptx);
Экспорт текста абзаца в HTML
Используйте ParagraphCollection.ExportToHtml для экспорта выбранного диапазона абзацев в HTML. При повторном использовании текста презентации на веб‑сайте вы можете захотеть сохранить локальное выделение без переноса шрифта, размера или стилей текстового поля презентации. Установите TextToHtmlConversionOptions.TextInheritanceLimit , чтобы контролировать, насколько глубоко экспортировщик следует наследованию форматирования.
Скачайте пример презентации и разместите его в рабочем каталоге приложения. Его первый слайд содержит одну текстовую фигуру с текстом “Inherited text; explicit red 18pt”. Ввод специально использует несколько уровней форматирования:
- Стиль текста по умолчанию в презентации задаёт Calibri размером 28 pt.
- Текстовый стиль первого уровня в текстовом фрейме задаёт синий цвет текста и курсив.
- Абзац явно задаёт полужирный текст.
- Второй фрагмент, “explicit red 18pt”, явно задаёт красный цвет текста и размер 18 pt.
В следующем полном примере те же абзацы экспортируются трижды. В метод экспорта передаётся TextToHtmlConversionOptions , и каждый результат записывается в отдельный файл HTML в кодировке UTF‑8:
using System.IO;
using System.Text;
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation("text-inheritance.pptx");
var textShape = (IAutoShape)presentation.Slides[0].Shapes[0];
var paragraphs = textShape.TextFrame.Paragraphs;
var modes = new[] { TextInheritanceLimit.All, TextInheritanceLimit.TextBox, TextInheritanceLimit.ParagraphOnly };
foreach (var mode in modes)
{
var options = new TextToHtmlConversionOptions { TextInheritanceLimit = mode };
var html = paragraphs.ExportToHtml(0, paragraphs.Count, options);
File.WriteAllText($"{mode}.html", html, Encoding.UTF8);
}
Сформированный HTML содержит следующий CSS для первого фрагмента, “Inherited text; “. Таблица перечисляет соответствующие объявления; другие сгенерированные свойства оп omitted for clarity.
| Вывод | Соответствующий 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.
Создание фрагмента HTML для буфера обмена
Установите AddClipboardFragmentHeader в false для обычного HTML или в true для включения заголовка буфера обмена. Оба вызова возвращают строку. Заголовок содержит смещения в байтах UTF‑8 окружающего HTML (StartHTML и EndHTML) и содержимого для вставки (StartFragment и EndFragment).
В этом примере два отформатированных абзаца экспортируются как обычный HTML (html) и как фрагмент HTML для буфера обмена (clipboardHtml). Запись фрагмента в системный буфер обмена — отдельный шаг приложения. API буфера обмена, принимающий необработанные байты HTML, требует UTF‑8 без BOM.
using Aspose.Slides;
using Aspose.Slides.Export;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var shape = slide.Shapes.AddAutoShape(ShapeType.Rectangle, 0, 0, 400, 100);
var paragraphs = shape.TextFrame.Paragraphs;
paragraphs.Clear();
paragraphs.AddFromHtml("<p>Status: <b>Ready</b></p><p><i>Next steps</i></p>");
var options = new TextToHtmlConversionOptions { AddClipboardFragmentHeader = false };
var html = paragraphs.ExportToHtml(0, paragraphs.Count, options);
options.AddClipboardFragmentHeader = true;
var clipboardHtml = paragraphs.ExportToHtml(0, paragraphs.Count, options);
Рендеринг абзаца в виде изображения
IParagraph.GetImage рендерит отдельный абзац напрямую и возвращает IImage. Сохраните результат в файл или поток с помощью IImage.Save. Нет необходимости рендерить содержащую фигуру или вручную обрезать bitmap.
IParagraph.GetImage может вернуть null, если абзац не найден в родительской коллекции, не имеет допустимых границ рендеринга или не может быть отрисован. Проверьте результат перед сохранением и освободите возвращённое изображение после использования.
Рендеринг абзаца в масштабе по умолчанию
В примере используется презентация с одним слайдом, первая фигура которого — текстовое поле, содержащее три абзаца.

В следующем примере выбирается второй абзац с индексом 1 и вызывается IParagraph.GetImage без параметров масштаба. Проверяется, что фигура содержит требуемый абзац и что рендеринг возвращает изображение, после чего вызывается IImage.Save для сохранения в формате PNG. Оператор using освобождает изображение после использования.
using System;
using Aspose.Slides;
using var presentation = new Presentation("sample.pptx");
var shape = presentation.Slides[0].Shapes[0];
if (shape is IAutoShape textShape &&
textShape.TextFrame != null &&
textShape.TextFrame.Paragraphs.Count > 1)
{
var paragraph = textShape.TextFrame.Paragraphs[1];
using var paragraphImage = paragraph.GetImage();
if (paragraphImage != null)
{
paragraphImage.Save("paragraph.png", ImageFormat.Png);
}
else
{
Console.WriteLine("The paragraph could not be rendered.");
}
}
else
{
Console.WriteLine("The expected text shape or paragraph was not found.");
}
Результат:

Рендеринг абзаца в ячейке таблицы с масштабированием
Используйте перегрузку IParagraph.GetImage , принимающую параметры float scaleX и float scaleY для задания горизонтального и вертикального коэффициентов масштабирования. В следующем примере создаётся таблица, абзац рендерится в первой её ячейке с двойной шириной и высотой относительно значения по умолчанию, и результат сохраняется как PNG‑изображение.
using System;
using Aspose.Slides;
var scaleX = 2f;
var scaleY = 2f;
using var presentation = new Presentation();
var slide = presentation.Slides[0];
var table = slide.Shapes.AddTable(50, 50, new[] { 300d }, new[] { 80d });
var paragraph = table[0, 0].TextFrame.Paragraphs[0];
paragraph.Text = "Text in a table cell";
using var paragraphImage = paragraph.GetImage(scaleX, scaleY);
if (paragraphImage != null)
{
paragraphImage.Save("table_paragraph.png", ImageFormat.Png);
}
else
{
Console.WriteLine("The paragraph could not be rendered.");
}
Коэффициент масштабирования 1 сохраняет ось с размером пикселя по умолчанию. Например, 2 для обоих коэффициентов даёт изображение, ширина и высота которого примерно вдвое больше стандартных размеров, что приводит к вчетвёро большему количеству пикселей. Большие коэффициенты обычно дают более чёткий текст при масштабировании или выводе в высоком разрешении, но также увеличивают расход памяти и размер файла. Коэффициенты ниже 1 создают более мелкие изображения с меньшим уровнем детализации. Используйте одинаковые коэффициенты, чтобы сохранить соотношение сторон абзаца; разные горизонтальные и вертикальные коэффициенты растягивают вывод независимо друг от друга.
Рендеринг всей фигуры с помощью IShape.GetImage остаётся полезным, когда необходимо включить заполнение, границу или другой визуальный контекст фигуры. Для изображения, содержащего только абзац, используйте IParagraph.GetImage.
Часто задаваемые вопросы
Могу ли я полностью отключить перенос строк внутри текстового фрейма?
Да. Установите ITextFrameFormat.WrapText , чтобы отключить перенос, и строки не будут разрываться у границ текстового фрейма.
Как получить точные границы конкретного абзаца на слайде?
Используйте IParagraph.GetRect , чтобы получить ограничивающий прямоугольник абзаца. IPortion.GetRect предоставляет границы отдельного фрагмента.
Где управляется выравнивание абзаца (по левому, правому краю, по центру или по ширине)?
IParagraphFormat.Alignment — это настройка уровня абзаца и применяется ко всему абзацу независимо от форматирования отдельных фрагментов. Чтобы вертикально выравнить фрагменты с разными размерами шрифтов в каждой строке, см. Выравнивание шрифтов в пределах строки.
Могу ли я задать язык проверки правописания для части абзаца?
Да. Установите IBasePortionFormat.LanguageId для отдельных фрагментов, чтобы один абзац мог содержать текст на нескольких языках.