使用 Excel JavaScript API 处理形状
Excel 将形状定义为位于 Excel 绘图层上的任何对象。 这意味着单元格外部的任何内容都是一个形状。 本文介绍如何将几何形状、线条和图像与 Shape 和 ShapeCollection API 结合使用。 图表 在自己的文章《 使用 Excel JavaScript API 处理图表》中进行了介绍。
下图显示了构成温度计的形状。
创建形状
形状通过 创建并存储在工作表的形状集合中, Worksheet.shapes
() 。 ShapeCollection
.add*
有多种方法可用于此目的。 所有形状在添加到集合时都有为其生成的名称和 ID。 这些分别是 name
和 id
属性。 name
可由加载项设置,以便使用 ShapeCollection.getItem(name)
方法轻松检索。
以下类型的形状是使用关联的 方法添加的。
形状 | Add 方法 | 签名 |
---|---|---|
几何形状 | addGeometricShape | addGeometricShape(geometricShapeType: Excel.GeometricShapeType): Excel.Shape |
图像 (JPEG 或 PNG) | addImage | addImage(base64ImageString: string): Excel.Shape |
折线图 | addLine | addLine(startLeft: number, startTop: number, endLeft: number, endTop: number, connectorType?: Excel.ConnectorType): Excel.Shape |
Svg | addSvg | addSvg(xml: string): Excel.Shape |
文本框 | addTextBox | addTextBox(text?: string): Excel.Shape |
几何形状
使用 ShapeCollection.addGeometricShape
创建几何形状。 该方法采用 GeometricShapeType 枚举作为参数。
下面的代码示例创建一个名为 “Square” 的 150x150 像素矩形,该矩形位于工作表的顶部和左侧 100 像素处。
// This sample creates a rectangle positioned 100 pixels from the top and left sides
// of the worksheet and is 150x150 pixels.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let rectangle = shapes.addGeometricShape(Excel.GeometricShapeType.rectangle);
rectangle.left = 100;
rectangle.top = 100;
rectangle.height = 150;
rectangle.width = 150;
rectangle.name = "Square";
await context.sync();
});
图像
JPEG、PNG 和 SVG 图像可以作为形状插入工作表中。 方法 ShapeCollection.addImage
采用 base64 编码的字符串作为参数。 这是字符串形式的 JPEG 或 PNG 图像。 ShapeCollection.addSvg
也采用字符串,但此参数是定义图形的 XML。
以下代码示例将 FileReader 加载的图像文件显示为字符串。 字符串具有元数据“base64”,在创建形状之前删除。
// This sample creates an image as a Shape object in the worksheet.
let myFile = document.getElementById("selectedFile");
let reader = new FileReader();
reader.onload = (event) => {
Excel.run(function (context) {
let startIndex = reader.result.toString().indexOf("base64,");
let myBase64 = reader.result.toString().substr(startIndex + 7);
let sheet = context.workbook.worksheets.getItem("MyWorksheet");
let image = sheet.shapes.addImage(myBase64);
image.name = "Image";
return context.sync();
}).catch(errorHandlerFunction);
};
// Read in the image file as a data URL.
reader.readAsDataURL(myFile.files[0]);
Lines
使用 ShapeCollection.addLine
创建行。 该方法需要线条起点和终点的左边距和上边距。 它还需要一个 ConnectorType 枚举来指定两个终结点之间的换行方式。 下面的代码示例在工作表上创建一条直线。
// This sample creates a straight line from [200,50] to [300,150] on the worksheet.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let line = shapes.addLine(200, 50, 300, 150, Excel.ConnectorType.straight);
line.name = "StraightLine";
await context.sync();
});
线条可以连接到其他 Shape 对象。 connectBeginShape
和 connectEndShape
方法将线条的起点和终点附加到指定连接点处的形状。 这些点的位置因形状而异,但 Shape.connectionSiteCount
可用于确保外接程序不会连接到超出边界的点。 使用 disconnectBeginShape
和 disconnectEndShape
方法断开线条与任何附加形状的连接。
下面的代码示例将 “MyLine” 线连接到名为 “LeftShape” 和 “RightShape”的两个形状。
// This sample connects a line between two shapes at connection points '0' and '3'.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let line = shapes.getItem("MyLine").line;
line.connectBeginShape(shapes.getItem("LeftShape"), 0);
line.connectEndShape(shapes.getItem("RightShape"), 3);
await context.sync();
});
移动形状和调整形状大小
形状位于工作表顶部。 其位置由 left
和 top
属性定义。 它们充当工作表各自边缘的边距,左上角为 [0, 0]。 可以直接设置这些值,也可以使用 和 incrementTop
方法从当前位置incrementLeft
进行调整。 形状从默认位置旋转多少也以这种方式建立,属性 rotation
为绝对量,方法 incrementRotation
调整现有旋转。
形状相对于其他形状的深度由 zorderPosition
属性定义。 这是使用 setZOrder
方法设置的,该方法采用 ShapeZOrder。 setZOrder
调整当前形状相对于其他形状的顺序。
加载项有几个选项可用于更改形状的高度和宽度。 height
设置 或 width
属性会更改指定的维度,而不会更改其他维度。 scaleHeight
和 scaleWidth
根据提供的 ShapeScaleType) 的值,调整形状相对于当前大小或原始大小 (的相应尺寸。 可选的 ShapeScaleFrom 参数指定形状从何处缩放 (左上角、中间或右下角) 。 lockAspectRatio
如果 属性为 true
,则缩放方法通过同时调整另一个维度来保持形状的当前纵横比。
注意
对 和 width
属性的直接更改height
只会影响该属性,而不管属性的值如何lockAspectRatio
。
下面的代码示例演示了一个形状被缩放到其原始大小的 1.25 倍,并旋转了 30 度。
// In this sample, the shape "Octagon" is rotated 30 degrees clockwise
// and scaled 25% larger, with the upper-left corner remaining in place.
await Excel.run(async (context) => {
let sheet = context.workbook.worksheets.getItem("MyWorksheet");
let shape = sheet.shapes.getItem("Octagon");
shape.incrementRotation(30);
shape.lockAspectRatio = true;
shape.scaleWidth(
1.25,
Excel.ShapeScaleType.currentSize,
Excel.ShapeScaleFrom.scaleFromTopLeft);
await context.sync();
});
形状中的文本
几何形状可以包含文本。 形状具有 textFrame
TextFrame 类型的属性。 对象 TextFrame
管理文本显示选项 (,例如边距和文本溢出) 。 TextFrame.textRange
是具有文本内容和字体设置的 TextRange 对象。
下面的代码示例创建一个名为“Wave”的几何形状,其文本为“形状文本”。 它还调整形状和文本颜色,并将文本的水平对齐方式设置为中心。
// This sample creates a light-blue wave shape and adds the purple text "Shape text" to the center.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let wave = shapes.addGeometricShape(Excel.GeometricShapeType.wave);
wave.left = 100;
wave.top = 400;
wave.height = 50;
wave.width = 150;
wave.name = "Wave";
wave.fill.setSolidColor("lightblue");
wave.textFrame.textRange.text = "Shape text";
wave.textFrame.textRange.font.color = "purple";
wave.textFrame.horizontalAlignment = Excel.ShapeTextHorizontalAlignment.center;
await context.sync();
});
addTextBox
方法ShapeCollection
创建GeometricShape
具有白色背景和黑色文本的 类型的 Rectangle
。 这与 Excel 的 “文本框” 按钮在“ 插入 ”选项卡上创建的相同。 addTextBox
采用字符串参数来设置 的文本 TextRange
。
下面的代码示例演示如何创建一个带有文本“Hello!”的文本框。
// This sample creates a text box with the text "Hello!" and sizes it appropriately.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let textbox = shapes.addTextBox("Hello!");
textbox.left = 100;
textbox.top = 100;
textbox.height = 20;
textbox.width = 45;
textbox.name = "Textbox";
await context.sync();
});
形状组
形状可以组合在一起。 这允许用户将它们视为用于定位、调整大小和其他相关任务的单个实体。 ShapeGroup 是 的一种Shape
类型,因此外接程序会将该组视为单个形状。
下面的代码示例显示了三个组合在一起的形状。 后续代码示例显示将形状组移动到右侧 50 像素。
// This sample takes three previously-created shapes ("Square", "Pentagon", and "Octagon")
// and groups them into a single ShapeGroup.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let square = shapes.getItem("Square");
let pentagon = shapes.getItem("Pentagon");
let octagon = shapes.getItem("Octagon");
let shapeGroup = shapes.addGroup([square, pentagon, octagon]);
shapeGroup.name = "Group";
console.log("Shapes grouped");
await context.sync();
});
// This sample moves the previously created shape group to the right by 50 pixels.
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let shapeGroup = shapes.getItem("Group");
shapeGroup.incrementLeft(50);
await context.sync();
});
重要
组中的各个形状通过 ShapeGroup.shapes
属性引用,该属性的类型为 GroupShapeCollection。 分组后,不再可通过工作表的形状集合访问它们。 例如,如果工作表有三个形状,并且它们全部组合在一起,则工作表的 shapes.getCount
方法将返回计数 1。
将形状导出为图像
任何 Shape
对象都可以转换为图像。 Shape.getAsImage 返回 base64 编码的字符串。 图像的格式指定为传递给 的 getAsImage
PictureFormat 枚举。
await Excel.run(async (context) => {
let shapes = context.workbook.worksheets.getItem("MyWorksheet").shapes;
let shape = shapes.getItem("Image");
let stringResult = shape.getAsImage(Excel.PictureFormat.png);
await context.sync();
console.log(stringResult.value);
// Instead of logging, your add-in may use the base64-encoded string to save the image as a file or insert it in HTML.
});
删除形状
使用 Shape
对象的 delete
方法从工作表中删除形状。 不需要其他元数据。
下面的代码示例从 MyWorksheet 中删除所有形状。
// This deletes all the shapes from "MyWorksheet".
await Excel.run(async (context) => {
let sheet = context.workbook.worksheets.getItem("MyWorksheet");
let shapes = sheet.shapes;
// We'll load all the shapes in the collection without loading their properties.
shapes.load("items/$none");
await context.sync();
shapes.items.forEach(function (shape) {
shape.delete();
});
await context.sync();
});