使用 Java 管理演示文稿中的文本框
介绍
在 Aspose.Slides for Java 中,幻灯片文本存储在属于形状的文本框中。 IAutoShape 接口表示最常见的承载文本的形状,并通过 IAutoShape.getTextFrame 方法公开其文本。
在幻灯片上创建文本框
要创建文本框,需要向幻灯片添加一个自动形状,在其文本框中添加文本,然后保存演示文稿。下面的示例创建了一个矩形文本框:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape textBox = slide.getShapes().addAutoShape(ShapeType.Rectangle, 150, 75, 300, 50);
textBox.addTextFrame("Aspose TextBox");
presentation.save("TextBox.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
传递给 IShapeCollection.addAutoShape 的坐标和尺寸使用点 (point) 为单位。 IAutoShape.addTextFrame 使用提供的文本初始化文本框。
检查文本框形状
使用 IAutoShape.isTextBox 方法可确定自动形状是否被视为文本框。当演示文稿同时包含承载文本的自动形状和纯图形自动形状时,这非常有用。

下面的示例检查演示文稿中的每个自动形状:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape textBox = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, 120, 40);
textBox.addTextFrame("Text box");
slide.getShapes().addAutoShape(ShapeType.Ellipse, 150, 10, 40, 40);
for (ISlide currentSlide : presentation.getSlides()) {
for (IShape shape : currentSlide.getShapes()) {
if (shape instanceof IAutoShape) {
IAutoShape autoShape = (IAutoShape) shape;
System.out.println(autoShape.isTextBox() ? "The shape is a text box." : "The shape is not a text box.");
}
}
}
} finally {
presentation.dispose();
}
新添加的自动形状在包含非空文本之前不被视为文本框。可以通过 IAutoShape.addTextFrame 或 ITextFrame.setText 提供该文本。将空字符串添加或赋值会使 IAutoShape.isTextBox 返回 false:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape1 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 10, 100, 40);
shape1.addTextFrame("Shape 1");
System.out.println(shape1.isTextBox());
IAutoShape shape2 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 70, 100, 40);
shape2.getTextFrame().setText("Shape 2");
System.out.println(shape2.isTextBox());
IAutoShape shape3 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 130, 100, 40);
shape3.addTextFrame("");
System.out.println(shape3.isTextBox());
IAutoShape shape4 = slide.getShapes().addAutoShape(ShapeType.Rectangle, 10, 190, 100, 40);
shape4.getTextFrame().setText("");
System.out.println(shape4.isTextBox());
} finally {
presentation.dispose();
}
前两个调用打印 true,后两个打印 false。
查找拥有文本框的形状
通用的文本处理代码可能只收到一个 ITextFrame,而不知道它属于哪个演示对象。使用只读的 ITextFrame.getParentShape 方法可回溯到拥有它的 IShape。
对于由自动形状或其他承载文本的形状拥有的文本框, ITextFrame.getParentShape 返回拥有者,而 ITextFrame.getParentCell 返回 null。在访问前请检查返回值。若需识别形状和表格单元格的拥有者(包括与 SmartArt 节点关联的形状),请参阅 搜索并替换文本。
向文本框添加列
ITextFrameFormat.setColumnCount 方法将文本框划分为多列,而 ITextFrameFormat.setColumnSpacing 方法设置列间距(单位为点)。这两个设置均属于 ITextFrameFormat,可通过现有文本框的文本框进行更改。列内文本在同一形状内重新流动,不会继续到其他形状。
下面的示例创建了一个三列文本框,列间距为 10 点,保存演示文稿后再从输出文件读取存储的设置:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape textBox = slide.getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 300, 200);
textBox.addTextFrame("This text is distributed automatically across all columns in the text box.");
ITextFrameFormat textFrameFormat = textBox.getTextFrame().getTextFrameFormat();
textFrameFormat.setColumnCount(3);
textFrameFormat.setColumnSpacing(10);
presentation.save("TextBoxColumns.pptx", SaveFormat.Pptx);
Presentation savedPresentation = new Presentation("TextBoxColumns.pptx");
try {
IAutoShape savedTextBox = (IAutoShape) savedPresentation.getSlides().get_Item(0).getShapes().get_Item(0);
ITextFrameFormat savedFormat = savedTextBox.getTextFrame().getTextFrameFormat();
System.out.println("Columns: " + savedFormat.getColumnCount() + "; spacing: " + savedFormat.getColumnSpacing() + " points");
} finally {
savedPresentation.dispose();
}
} finally {
presentation.dispose();
}
从各列中提取文本
使用 ITextFrame.splitTextByColumns 可以获取现有文本框中每个可视列分配的文本。该方法按列的阅读顺序返回每列的字符串。单列文本框返回仅包含一个元素的数组,空列则用空字符串表示。返回的字符串仅包含纯文本,不保留段落级别的格式。
这在以下场景中非常有用:
- 在保持列顺序的同时提取文本。
- 为多列幻灯片建立索引或比较内容。
- 将每列导出到单独的文件、数据库字段或其他目标。
- 检查在使用 ITextFrameFormat.setColumnCount 更改列数、使用 ITextFrameFormat.setColumnSpacing 更改间距、修改字体或文本框大小后文本的重新分布情况。
该方法仅报告当前 ITextFrame 中的文本分布;它不会自动在不同形状或文本框之间流动文本。列的分布可能受可用字体和其他排版设置影响,因此在对结果一致性有要求时请确保所需字体已就绪。
下面的示例加载演示文稿,找到第一个具有多列文本框的自动形状,读取其配置的列数,并将每列的文本写入单独的文件。没有文本框的形状将被跳过。
import com.aspose.slides.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Presentation presentation = new Presentation("MultiColumnText.pptx");
try {
IAutoShape textBox = null;
for (IShape shape : presentation.getSlides().get_Item(0).getShapes()) {
if (shape instanceof IAutoShape) {
IAutoShape autoShape = (IAutoShape) shape;
if (autoShape.getTextFrame() != null) {
int columnCount = autoShape.getTextFrame().getTextFrameFormat().getColumnCount();
if (columnCount > 1) {
textBox = autoShape;
break;
}
}
}
}
if (textBox == null) {
System.out.println("No multi-column text frame was found.");
} else {
ITextFrame textFrame = textBox.getTextFrame();
int configuredColumnCount = textFrame.getTextFrameFormat().getColumnCount();
String[] columnTexts = textFrame.splitTextByColumns();
System.out.println("Configured columns: " + configuredColumnCount);
for (int columnIndex = 0; columnIndex < columnTexts.length; columnIndex++) {
int columnNumber = columnIndex + 1;
String columnText = columnTexts[columnIndex];
System.out.println("Column " + columnNumber + ": " + columnText);
Path outputPath = Paths.get("Column-" + columnNumber + ".txt");
byte[] textBytes = columnText.getBytes(StandardCharsets.UTF_8);
try {
Files.write(outputPath, textBytes);
} catch (IOException exception) {
System.out.println("Could not write column " + columnNumber + ": " + exception.getMessage());
}
}
}
} finally {
presentation.dispose();
}
更新文本
要在整个演示文稿中更新文本,请遍历幻灯片和形状,挑选自动形状,然后编辑其文本段落。在段落层面进行操作可同时更改文本和字符格式。
下面的示例将自动形状文本中所有 years 替换为 months,并将受影响的段落加粗:
import com.aspose.slides.*;
Presentation presentation = new Presentation("Text.pptx");
try {
for (ISlide slide : presentation.getSlides()) {
for (IShape shape : slide.getShapes()) {
if (!(shape instanceof IAutoShape)) {
continue;
}
IAutoShape autoShape = (IAutoShape) shape;
ITextFrame textFrame = autoShape.getTextFrame();
if (textFrame == null) {
continue;
}
for (IParagraph paragraph : textFrame.getParagraphs()) {
for (IPortion portion : paragraph.getPortions()) {
String text = portion.getText();
if (text != null && text.contains("years")) {
portion.setText(text.replace("years", "months"));
portion.getPortionFormat().setFontBold(NullableBool.True);
}
}
}
}
}
presentation.save("TextChanged.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
此遍历仅更新自动形状中的文本。表格、图表、SmartArt 或组合形状中的文本需要遍历这些对象各自的集合。
添加带超链接的文本框
超链接可以分配给特定的文本段落,仅该段落会作为可点击链接。使用 IHyperlinkManager.setExternalHyperlinkClick 将段落与外部 URL 关联。
下面的示例创建了带链接的文本并将其保存到演示文稿中:
import com.aspose.slides.*;
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape textBox = slide.getShapes().addAutoShape(ShapeType.Rectangle, 150, 150, 200, 50);
textBox.addTextFrame("Aspose.Slides");
IPortion textPortion = textBox.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(0);
textPortion.getPortionFormat().getHyperlinkManager().setExternalHyperlinkClick("https://www.aspose.com/");
presentation.save("Hyperlink.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
常见问题
文本框与母版或布局幻灯片上的文本占位符有何区别?
占位符 可以从 母版幻灯片或 布局幻灯片 继承位置和格式。普通文本框是创建所在幻灯片上的独立形状,布局变化时不会获得占位符的行为。
如何在不更改图表、表格或 SmartArt 中的文本的情况下替换文本?
如 “更新文本” 示例所示,仅遍历实现了 IAutoShape 的形状。图表、表格和 SmartArt 将文本存储在各自的对象模型中,因而不会被该循环修改。