Skip to main content
Glama
PowerPointAPI.ts6.07 kB
import { IDocumentAdapter } from '../types'; /** * PowerPoint API封装 */ export class PowerPointAPI implements IDocumentAdapter { /** * 获取文档内容(所有幻灯片的文本) */ async getContent(): Promise<string> { return PowerPoint.run(async (context) => { const slides = context.presentation.slides; slides.load('items'); await context.sync(); const slideContents: string[] = []; for (let i = 0; i < slides.items.length; i++) { const slide = slides.items[i]; const shapes = slide.shapes; shapes.load('items'); await context.sync(); const textItems: string[] = []; shapes.items.forEach((shape) => { if (shape.textFrame) { textItems.push(shape.textFrame.textRange.text); } }); slideContents.push(`Slide ${i + 1}: ${textItems.join(' ')}`); } return slideContents.join('\n'); }); } /** * 设置文档内容(不推荐,PPT应该操作特定幻灯片) */ async setContent(content: string): Promise<void> { throw new Error('PowerPoint不支持setContent,请使用addSlide或updateShape'); } /** * 获取选中的内容(当前选中的形状) */ async getSelection(): Promise<string> { return PowerPoint.run(async (context) => { const selection = context.presentation.getSelectedShapes(); selection.load('items'); await context.sync(); const textItems: string[] = []; selection.items.forEach((shape) => { if (shape.textFrame) { textItems.push(shape.textFrame.textRange.text); } }); return textItems.join(' '); }); } /** * 插入内容(在当前幻灯片添加文本框) */ async insertContent(content: string): Promise<void> { return PowerPoint.run(async (context) => { const slides = context.presentation.slides; const slide = slides.getItemAt(0); // 获取第一张幻灯片 const textBox = slide.shapes.addTextBox(content); textBox.left = 100; textBox.top = 100; textBox.height = 200; textBox.width = 400; await context.sync(); }); } /** * 添加新幻灯片 */ async addSlide(layoutType: PowerPoint.SlideLayoutType = PowerPoint.SlideLayoutType.blank): Promise<void> { return PowerPoint.run(async (context) => { context.presentation.slides.add(layoutType); await context.sync(); }); } /** * 在幻灯片添加标题 */ async addTitle(slideIndex: number, title: string): Promise<void> { return PowerPoint.run(async (context) => { const slides = context.presentation.slides; const slide = slides.getItemAt(slideIndex); const textBox = slide.shapes.addTextBox(title); // 设置标题样式 textBox.left = 50; textBox.top = 50; textBox.height = 80; textBox.width = 600; textBox.textFrame.textRange.font.size = 32; textBox.textFrame.textRange.font.bold = true; await context.sync(); }); } /** * 添加文本框 */ async addTextBox( slideIndex: number, text: string, options?: { left?: number; top?: number; width?: number; height?: number; } ): Promise<void> { return PowerPoint.run(async (context) => { const slides = context.presentation.slides; const slide = slides.getItemAt(slideIndex); const textBox = slide.shapes.addTextBox(text); textBox.left = options?.left ?? 100; textBox.top = options?.top ?? 100; textBox.height = options?.height ?? 100; textBox.width = options?.width ?? 400; await context.sync(); }); } /** * 创建形状高亮(添加半透明覆盖形状) */ async createHighlight( slideIndex: number, shapeId: string, color: string ): Promise<void> { return PowerPoint.run(async (context) => { const slides = context.presentation.slides; const slide = slides.getItemAt(slideIndex); const targetShape = slide.shapes.getItem(shapeId); targetShape.load('left, top, height, width'); await context.sync(); // 创建半透明矩形覆盖 const highlight = slide.shapes.addGeometricShape(PowerPoint.GeometricShapeType.rectangle); highlight.left = targetShape.left; highlight.top = targetShape.top; highlight.height = targetShape.height; highlight.width = targetShape.width; highlight.fill.setSolidColor(color); highlight.fill.transparency = 0.5; await context.sync(); }); } /** * 获取演示文稿文件 */ async getDocumentFile(): Promise<Blob> { return new Promise((resolve, reject) => { Office.context.document.getFileAsync( Office.FileType.Compressed, { sliceSize: 4194304 }, (result) => { if (result.status === Office.AsyncResultStatus.Succeeded) { const file = result.value; const sliceCount = file.sliceCount; const slices: any[] = []; const getSlice = (sliceIndex: number) => { file.getSliceAsync(sliceIndex, (sliceResult) => { if (sliceResult.status === Office.AsyncResultStatus.Succeeded) { slices[sliceIndex] = sliceResult.value.data; if (sliceIndex < sliceCount - 1) { getSlice(sliceIndex + 1); } else { file.closeAsync(); const blob = new Blob(slices, { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', }); resolve(blob); } } else { file.closeAsync(); reject(new Error(sliceResult.error.message)); } }); }; getSlice(0); } else { reject(new Error(result.error.message)); } } ); }); } } export default new PowerPointAPI();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/walkingzzzy/office-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server