1
+ order : 5
2
+ id : powerpoint-slide-management-export-import-slide
3
+ name : Export and import slide
4
+ description : Shows how to export and import a slide.
5
+ host : POWERPOINT
6
+ api_set :
7
+ PowerPointApi : ' 1.8'
8
+ script :
9
+ content : |
10
+ document.getElementById("export-slide-button").addEventListener("click", () => tryCatch(exportSlide));
11
+ document.getElementById("clear-exported-slide-button").addEventListener("click", () => tryCatch(clearExportedSlide));
12
+ document.getElementById("import-slide-button").addEventListener("click", () => tryCatch(importSlide));
13
+ document.getElementById("slide-image-button").addEventListener("click", () => tryCatch(addSlideImageToNewSlide));
14
+ document.getElementById("setup").addEventListener("click", () => tryCatch(setup));
15
+
16
+ async function exportSlide() {
17
+ // Exports current slide.
18
+ await PowerPoint.run(async (context) => {
19
+ const slide = context.presentation.getSelectedSlides().getItemAt(0);
20
+ const slideBase64DataResult = slide.exportAsBase64();
21
+ const imageBase64DataResult = slide.getImageAsBase64({ height: 300 });
22
+ await context.sync();
23
+
24
+ localStorage.setItem("exportedSlide", slideBase64DataResult.value);
25
+ localStorage.setItem("exportedSlideImage", imageBase64DataResult.value);
26
+
27
+ updateSlideImage(imageBase64DataResult.value);
28
+
29
+ console.log("Slide was exported.");
30
+ });
31
+ }
32
+
33
+ function clearExportedSlide() {
34
+ // Clears exported slide.
35
+ localStorage.removeItem("exportedSlide");
36
+ localStorage.removeItem("exportedSlideImage");
37
+ updateSlideImage("");
38
+ console.log("Exported slide was cleared.");
39
+ }
40
+
41
+ async function importSlide() {
42
+ // Imports the slide that was most recently exported.
43
+ const slideBase64Data = localStorage.getItem("exportedSlide");
44
+ if (slideBase64Data === null) {
45
+ console.warn("Unable to import. You must first export a slide.");
46
+ return;
47
+ }
48
+
49
+ await PowerPoint.run(async (context) => {
50
+ const currentSlide = context.presentation.getSelectedSlides().getItemAt(0);
51
+ currentSlide.load("id");
52
+ await context.sync();
53
+
54
+ context.presentation.insertSlidesFromBase64(slideBase64Data, { targetSlideId: currentSlide.id });
55
+ });
56
+ }
57
+
58
+ async function getSlideImage(options?: PowerPoint.SlideGetImageOptions): Promise<string> {
59
+ // Gets slide image.
60
+ return PowerPoint.run(async (context) => {
61
+ const slide = context.presentation.getSelectedSlides().getItemAt(0);
62
+ const imageBase64Result = slide.getImageAsBase64(options);
63
+ await context.sync();
64
+
65
+ return imageBase64Result.value;
66
+ });
67
+ }
68
+
69
+ async function getImageDimensions(base64Data: string): Promise<{ width: number; height: number }> {
70
+ // Gets image dimensions.
71
+ return new Promise((resolve, reject) => {
72
+ const image = new Image();
73
+ image.onerror = () => {
74
+ reject();
75
+ };
76
+ image.onload = () => {
77
+ resolve({ width: image.width, height: image.height });
78
+ };
79
+ image.src = `data:image/png;base64,${base64Data}`;
80
+ });
81
+ }
82
+
83
+ async function addSlideWithImage(imageBase64): Promise<void> {
84
+ // Adds a new slide including an image.
85
+ return PowerPoint.run(async (context) => {
86
+ const presentation = context.presentation;
87
+ const currentSlide = presentation.getSelectedSlides().getItemAt(0);
88
+ const slideCountResult = context.presentation.slides.getCount();
89
+
90
+ currentSlide.layout.load();
91
+ await context.sync();
92
+
93
+ const slideCount = slideCountResult.value;
94
+
95
+ console.log(`Adding slide using layout ${currentSlide.layout.id}`);
96
+
97
+ // Add a new slide at the end of the presentation.
98
+ context.presentation.slides.add({ layoutId: currentSlide.layout.id });
99
+ try {
100
+ await context.sync();
101
+ } catch (err) {
102
+ console.error(`Unable to add slide (with layout from current slide). ${err}`);
103
+
104
+ // Try adding without specifying the layout.
105
+ context.presentation.slides.add();
106
+
107
+ try {
108
+ await context.sync();
109
+ } catch (err) {
110
+ console.error(`Unable to add slide. ${err}`);
111
+ throw err;
112
+ }
113
+ }
114
+
115
+ console.log("Slide added");
116
+
117
+ // Get added slide.
118
+ const slide = context.presentation.slides.getItemAt(slideCount);
119
+
120
+ slide.load(["id"]);
121
+
122
+ await context.sync();
123
+
124
+ console.log(`Added slide id: ${slide.id}`);
125
+
126
+ // Switch to the new slide.
127
+ context.presentation.setSelectedSlides([slide.id]);
128
+ try {
129
+ await context.sync();
130
+ } catch (err) {
131
+ console.error(`Unable to switch to the new slide. ${err}`);
132
+ throw err;
133
+ }
134
+
135
+ console.log("Switched to the added slide.");
136
+
137
+ const activeSlide = context.presentation.getSelectedSlides().getItemAt(0);
138
+ activeSlide.load(["id"]);
139
+ await context.sync();
140
+
141
+ console.log(`Active slide id: ${activeSlide.id}`);
142
+
143
+ const imageDimensions = await getImageDimensions(imageBase64);
144
+ const shapeAddOptions = {
145
+ height: imageDimensions.height,
146
+ width: imageDimensions.width
147
+ };
148
+
149
+ let shape;
150
+
151
+ shape = await addImageToCurrentSlide(imageBase64);
152
+ shape.load(["id"]);
153
+ await context.sync();
154
+
155
+ // Select the added image.
156
+ activeSlide.setSelectedShapes([shape.id]);
157
+ await context.sync();
158
+ });
159
+ }
160
+
161
+ async function addImageToCurrentSlide(
162
+ imageBase64: string,
163
+ options?: PowerPoint.ShapeAddOptions
164
+ ): Promise<PowerPoint.Shape> {
165
+ // Adds an image to the current slide.
166
+ const setSelectedDataOptions: Office.SetSelectedDataOptions = {
167
+ coercionType: Office.CoercionType.Image
168
+ };
169
+ if (options) {
170
+ if (options.height) {
171
+ setSelectedDataOptions.imageHeight = options.height;
172
+ }
173
+ if (options.left) {
174
+ setSelectedDataOptions.imageLeft = options.left;
175
+ }
176
+ if (options.top) {
177
+ setSelectedDataOptions.imageTop = options.top;
178
+ }
179
+ if (options.width) {
180
+ setSelectedDataOptions.imageWidth = options.width;
181
+ }
182
+ }
183
+
184
+ return new Promise((resolve, reject) => {
185
+ Office.context.document.setSelectedDataAsync(
186
+ imageBase64,
187
+ setSelectedDataOptions,
188
+ async (result: Office.AsyncResult<void>) => {
189
+ if (result.error) {
190
+ console.error(`ERROR in setSelectedDataAsync(): ${result.error}`);
191
+ reject(result.error);
192
+ } else {
193
+ const shape = await PowerPoint.run(async (context) => {
194
+ const slide = context.presentation.getSelectedSlides().getItemAt(0);
195
+ slide.shapes.load();
196
+ await context.sync();
197
+
198
+ return slide.shapes.items[slide.shapes.items.length - 1];
199
+ });
200
+ resolve(shape);
201
+ }
202
+ }
203
+ );
204
+ });
205
+ }
206
+
207
+ async function addSlideImageToNewSlide() {
208
+ // Adds an image of current slide to the new slide.
209
+ const imageBase64 = await getSlideImage({ height: 500 });
210
+
211
+ await addSlideWithImage(imageBase64);
212
+ }
213
+
214
+ function updateSlideImage(imageBase64: string) {
215
+ const slideImageElement = document.getElementById("slide-image") as HTMLImageElement;
216
+ slideImageElement.src = imageBase64 ? `data:image/png;base64,${imageBase64}` : "";
217
+ }
218
+
219
+ async function setup() {
220
+ await PowerPoint.run(async (context) => {
221
+ // Adds a new slide with some content.
222
+ const slideCountResult = context.presentation.slides.getCount();
223
+ context.presentation.slides.add();
224
+ await context.sync();
225
+
226
+ const newSlide = context.presentation.slides.getItemAt(slideCountResult.value);
227
+ newSlide.load("id");
228
+ newSlide.shapes.addGeometricShape(PowerPoint.GeometricShapeType.hexagon);
229
+ await context.sync();
230
+
231
+ console.log(`Added slide - ID: ${newSlide.id}`);
232
+
233
+ // Switch to the new slide.
234
+ context.presentation.setSelectedSlides([newSlide.id]);
235
+ await context.sync();
236
+ });
237
+ }
238
+
239
+ // Default helper for invoking an action and handling errors.
240
+ async function tryCatch(callback) {
241
+ try {
242
+ await callback();
243
+ } catch (error) {
244
+ // Note: In a production add-in, you'd want to notify the user through your add-in's UI.
245
+ console.error(error);
246
+ }
247
+ }
248
+ language : typescript
249
+ template :
250
+ content : |-
251
+ <section class="ms-Fabric ms-font-m">
252
+ This sample demonstrates how to export and import a slide.
253
+ </section>
254
+ <section class="ms-Fabric setup ms-font-m">
255
+ <h3>Set up</h3>
256
+ <button id="setup" class="ms-Button">
257
+ <span class="ms-Button-label">Set up</span>
258
+ </button>
259
+ </section>
260
+ <section class="ms-Fabric samples ms-font-m">
261
+ <h3>Try it out</h3>
262
+ <button id="export-slide-button" class="ms-Button">
263
+ <span class="ms-Button-label">Export current slide</span>
264
+ </button>
265
+ <button id="clear-exported-slide-button" class="ms-Button">
266
+ <span class="ms-Button-label">Clear exported slide</span>
267
+ </button>
268
+ <img id="slide-image" src=""/>
269
+ <p>Once a slide has been exported, click the <b>Import slide</b> button to insert into the presentation.</p>
270
+ <p>To add it to a different presentation, open that presentation and select a slide. It will be inserted after the
271
+ selected slide.</p>
272
+ <button id="import-slide-button" class="ms-Button">
273
+ <span class="ms-Button-label">Import slide</span>
274
+ </button><br>
275
+ <p>Click the following button to capture an image of the current slide and add it to a new slide at the end of the presentation.</p>
276
+ <button id="slide-image-button" class="ms-Button">
277
+ <span class="ms-Button-label">Put slide image on another slide</span>
278
+ </button>
279
+ </section>
280
+ language : html
281
+ style :
282
+ content : |-
283
+ section.samples {
284
+ margin-top: 20px;
285
+ }
286
+
287
+ section.samples .ms-Button, section.setup .ms-Button {
288
+ display: block;
289
+ margin-bottom: 5px;
290
+ margin-left: 20px;
291
+ min-width: 80px;
292
+ }
293
+
294
+ img {
295
+ border: 5px solid #555;
296
+ }
297
+ language : css
298
+ libraries : |-
299
+ https://appsforoffice.microsoft.com/lib/1/hosted/office.js
300
+ @types/office-js
301
+
302
+ [email protected] /dist/css/fabric.min.css
303
+ [email protected] /dist/css/fabric.components.min.css
304
+
305
+ [email protected] /client/core.min.js
306
+ @types/core-js
0 commit comments