The same deck often needs more or fewer slides for different occasions: add two case-study pages for a client meeting, then drop the outdated ones after the previous version has been used. Doing this by hand in desktop software means someone babysitting the file, and it is hard to fold into a batch Web workflow; doing it server-side means uploading the file first, which takes it off the user's device.

This article shows how to add and delete PowerPoint slides directly in the browser with Spire.Presentation for JavaScript. Everything runs in the browser on WebAssembly — no Office install, no backend, and the file stays on the user's device.

The article covers three features:

For installation and project setup, see How to Integrate Spire.Presentation for JavaScript in a React Project. The examples below assume Spire.Presentation is installed and the WebAssembly module is initialized.


Add PowerPoint Slides at the End

Spire.Presentation for JavaScript adds a new slide at the end of a presentation with the Slides.Append() method. What gets added depends on the arguments:

Call What it appends
Slides.Append() A new slide with the default (blank) layout
Slides.Append({ template: <layout object> }) A new slide built from the given layout
Slides.Append({ slide }) A copy of an existing slide

To build a slide from a specific layout, get the layout object first: ppt.Masters.get_Item(0).Layouts.get_Item(i) — the i-th layout under the first slide master (i is 0-based).

The steps are as follows:

  1. Get the Spire.Presentation WASM module and confirm it is ready.
  2. Read the sample presentation and the font into the VFS, create a Presentation object, and load the file.
  3. Add slides at the end with Presentation.Slides.Append() (pass template or slide to choose the content).
  4. Save the result with Presentation.SaveToFile().
  5. Read the result back from the VFS and trigger a browser download.

The code for adding PowerPoint slides:

function App() {
  const addSlides = async () => {
    // Get the Spire.Presentation WASM module
    const pptModule = window.wasmModule?.spirepresentation;

    // Check whether the module is ready
    if (!pptModule) {
      alert('Spire.Presentation is not ready yet');
      return;
    }

    // Load the sample presentation and the font
    await window.spire.FetchFileToVFS('SamplePresentation.pptx', "", `${process.env.PUBLIC_URL}/data/`);
    await window.spire.FetchFileToVFS('ARIALUNI.TTF', "/Library/Fonts/", `${process.env.PUBLIC_URL}/font/`);

    // Create a Presentation instance and load the presentation
    const ppt = new pptModule.Presentation();
    ppt.LoadFromFile('SamplePresentation.pptx');

    // Append in turn: default layout, a chosen layout, a clone of the first slide
    ppt.Slides.Append();
    ppt.Slides.Append({ template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });
    ppt.Slides.Append({ slide: ppt.Slides.get_Item(0) });

    // Save the result
    const outputFileName = 'SlidesAdded.pptx';
    ppt.SaveToFile({ file: outputFileName, fileFormat: pptModule.FileFormat.Pptx2013 });
    ppt.Dispose();

    // Read the generated file from the VFS and trigger a download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add PowerPoint Slides</h1>
      <button onClick={addSlides}>
        Add Slides
      </button>
    </div>
  );
}

export default App;

After appending three slides to the end:

After appending three slides to the end


Insert PowerPoint Slides at a Specific Position

Slides.Insert() takes an index that sets where the slide goes: it is inserted at that index and the slides after it shift back. The content is again decided by the arguments:

Call What it inserts
Slides.Insert({ index, template: <layout object> }) A new slide built from the given layout, inserted at index
Slides.Insert({ index, slide }) A copy of an existing slide inserted at index

The layout object is obtained the same way as for Slides.Append().

The steps are as follows:

  1. Get the Spire.Presentation WASM module and confirm it is ready.
  2. Read the sample presentation and the font into the VFS, create a Presentation object, and load the file.
  3. Insert slides at the given positions with Presentation.Slides.Insert().
  4. Save the result with Presentation.SaveToFile().
  5. Read the result back from the VFS and trigger a browser download.

The code for inserting PowerPoint slides:

function App() {
  const insertSlides = async () => {
    // Get the Spire.Presentation WASM module
    const pptModule = window.wasmModule?.spirepresentation;

    // Check whether the module is ready
    if (!pptModule) {
      alert('Spire.Presentation is not ready yet');
      return;
    }

    // Load the sample presentation and the font
    await window.spire.FetchFileToVFS('SamplePresentation.pptx', "", `${process.env.PUBLIC_URL}/data/`);
    await window.spire.FetchFileToVFS('ARIALUNI.TTF', "/Library/Fonts/", `${process.env.PUBLIC_URL}/font/`);

    // Create a Presentation instance and load the presentation
    const ppt = new pptModule.Presentation();
    ppt.LoadFromFile('SamplePresentation.pptx');

    // Insert in turn: a chosen layout, a clone of the first slide
    ppt.Slides.Insert({ index: 1, template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });
    ppt.Slides.Insert({ index: 2, slide: ppt.Slides.get_Item(0) });

    // Save the result
    const outputFileName = 'SlidesInserted.pptx';
    ppt.SaveToFile({ file: outputFileName, fileFormat: pptModule.FileFormat.Pptx2013 });
    ppt.Dispose();

    // Read the generated file from the VFS and trigger a download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Insert PowerPoint Slides</h1>
      <button onClick={insertSlides}>
        Insert Slides
      </button>
    </div>
  );
}

export default App;

After inserting two slides in the middle:

After inserting two slides in the middle


Delete PowerPoint Slides

Spire.Presentation for JavaScript can delete slides too, with Slides.RemoveAt() or Slides.Remove(). They target a slide differently:

Method Based on
Slides.RemoveAt(index) The position of the slide (0-based index)
Slides.Remove(slide) The slide object itself

Each removal shifts the index of every later slide back by one.

The steps are as follows:

  1. Get the Spire.Presentation WASM module and confirm it is ready.
  2. Read the sample presentation and the font into the VFS, create a Presentation object, and load the file.
  3. Delete a slide by index with Presentation.Slides.RemoveAt().
  4. Save the result with Presentation.SaveToFile().
  5. Read the result back from the VFS and trigger a browser download.

The code for deleting PowerPoint slides:

function App() {
  const removeSlides = async () => {
    // Get the Spire.Presentation WASM module
    const pptModule = window.wasmModule?.spirepresentation;

    // Check whether the module is ready
    if (!pptModule) {
      alert('Spire.Presentation is not ready yet');
      return;
    }

    // Load the sample presentation and the font
    await window.spire.FetchFileToVFS('SamplePresentation.pptx', "", `${process.env.PUBLIC_URL}/data/`);
    await window.spire.FetchFileToVFS('ARIALUNI.TTF', "/Library/Fonts/", `${process.env.PUBLIC_URL}/font/`);

    // Create a Presentation instance and load the presentation
    const ppt = new pptModule.Presentation();
    ppt.LoadFromFile('SamplePresentation.pptx');

    // RemoveAt deletes by index: once the first slide is gone, the slides after it shift back
    ppt.Slides.RemoveAt(0);

    // Save the result
    const outputFileName = 'SlidesRemoved.pptx';
    ppt.SaveToFile({ file: outputFileName, fileFormat: pptModule.FileFormat.Pptx2013 });
    ppt.Dispose();

    // Read the generated file from the VFS and trigger a download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Delete PowerPoint Slides</h1>
      <button onClick={removeSlides}>
        Remove Slides
      </button>
    </div>
  );
}

export default App;

After deleting a slide:

After deleting a slide

Delete a Slide by Object

Slides.RemoveAt() above deletes by index; Slides.Remove() takes a slide object instead. To point at a page, fetch it with Slides.get_Item(index) and hand it to Slides.Remove():

// Delete by object: fetch the second slide, then remove it
ppt.Slides.Remove(ppt.Slides.get_Item(1));

FAQ

Do the files need to be uploaded to a server

Not with the usage in this article. Spire.Presentation for JavaScript runs in the browser on WebAssembly, and presentations are read and written locally through a virtual file system (VFS) — adding, deleting, and saving all happen locally, and the library itself does not send files to a server. Whether a file leaves the device in the end depends on the other code you add to the page.

Can I add or delete several slides at once

Yes, just call in a loop: call Slides.Append() / Slides.Insert() several times to add or insert; when deleting several slides, handle the indices in order, or it is easy to delete the wrong slide or go out of range (see the last question).

Why does a new Presentation already contain a blank slide

Cause: A presentation created with new Presentation() already contains one blank slide; Append() only adds to the end and does not replace it.

Fix: To start from empty, remove it first, then append the slides you need:

let ppt = new pptModule.Presentation();

// Remove the blank slide it comes with
ppt.Slides.RemoveAt(0);

// Then append as needed
ppt.Slides.Append({ template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });

Why is Append() without arguments a blank page

Cause: With no arguments it creates a slide with the default (blank) layout, so there are no ready-made title or body placeholders and it looks like an empty page.

Fix: To get ready-made placeholders, pass a layout that has them, or clone an existing slide; you can also add content yourself on the new page with Shapes.AppendShape():

// Build from a layout, so the page comes with title and content placeholders
ppt.Slides.Append({ template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });

// Clone the first slide, and its content comes along
ppt.Slides.Append({ slide: ppt.Slides.get_Item(0) });

Why do I delete the wrong slide, or hit an index-out-of-range error, when removing several slides

Cause: Slides is indexed by position, and every removal shifts the index of the slides after it back by one. When you delete "front to back" with fixed indices (RemoveAt(0), RemoveAt(1), …), the second step no longer deletes the slides you meant; and once an index goes past the current count (Slides.Count - 1), RemoveAt throws.

Fix: Do not use increasing fixed indices for several deletions; delete the current first slide (index 0) every time — the slides after it fill in automatically:

// Delete the first three slides: always remove index 0 and the following slides shift up
for (let i = 0; i < 3; i++) {
  ppt.Slides.RemoveAt(0);
}

Get a Free License

If you want to remove the evaluation message from the result document or lift the feature limits, contact sales for a temporary license valid for 30 days.

A chart makes a trend visible at a glance, yet it does not give the exact numbers: the height of a column has to be read against the value axis, and the estimate drifts as more series crowd in. A data table lists the category names, series names and values directly below the chart, so readers do not have to go back to the source cells or add a data label to every point. As part of the chart, the table scales and moves with it and stays in place when the chart is exported as an image or printed. Spire.XLS for JavaScript performs these operations in the browser through WebAssembly; the input and output files are managed by a virtual file system (VFS), with no backend service required.

This article covers two feature points:

For installation and project setup, see Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module has been initialized.


Add a data table to the chart

Adding a data table to a chart solves the problem of numbers living apart from the picture. A default column chart only draws the columns; the values stay in the source worksheet and the reader has to move between the two. With several series, a data table sits directly under the category axis, one row per series, its columns aligned with the categories and its rows matching the colours in the legend, so the trend and the figures appear in one place. The sample workbook already holds a quarterly sales table and a column chart; what it lacks is the table below the chart.

Turning the data table on:

Syntax Result
workbook.Worksheets.get(0) Takes the first worksheet of the workbook
sheet.Charts.get(0) Takes the first chart on the worksheet
chart.HasDataTable = true Shows a data table below the chart with the categories, series names and values
workbook.SaveToFile Saves the workbook with its data table into the VFS

The steps are:

  1. Load the font file and the test data file into the VFS with window.spire.FetchFileToVFS.
  2. Create a workbook with new Workbook(), load the input file with workbook.LoadFromFile, and take the first worksheet with workbook.Worksheets.get(0).
  3. Take the first chart on the worksheet with sheet.Charts.get(0).
  4. Set chart.HasDataTable to true, which adds the data table below the chart.
  5. Save the workbook with workbook.SaveToFile and dispose of it with workbook.Dispose to free resources.

The full code example below shows how to add a data table to an Excel chart in React:

function App() {
  const addDataTable = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font and the test data file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'ChartSales.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook and take the first worksheet and its chart
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });
    const sheet = workbook.Worksheets.get(0);
    const chart = sheet.Charts.get(0);

    // Turn on the chart's data table, which lists the categories and series values below the plot
    chart.HasDataTable = true;

    // Save the workbook
    const outputFileName = 'AddDataTable.xlsx';
    workbook.SaveToFile({ fileName: outputFileName });

    // Dispose of the workbook to release its resources
    workbook.Dispose();

    // Read the result back out of the VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add a Data Table to an Excel Chart</h1>
      <button id="add-data-table" onClick={addDataTable}>Add a Data Table to the Chart</button>
    </div>
  );
}

export default App;

The sales report after turning on the chart data table:

The sales report after turning on the chart data table


Adjust the data table borders, legend keys and text formatting

Adjusting the data table borders, legend keys and text formatting keeps the table readable when there are many series and lets it blend into the layout of a report. A newly opened data table carries an outer frame and both horizontal and vertical separators; with three rows of values stacked together it looks like a dense grid. Dropping the outer frame and the vertical lines leaves only the horizontal ones, so the eye follows a row straight to its numbers without being cut off by vertical rules. Turning on the legend keys then puts a colour swatch of the matching series in front of every series name, so readers no longer have to compare each row with the legend. By default the text draws on the chart's own settings -- ten points, black, not bold -- which does not stand out against dark columns and gridlines; dropping the size to nine points fits more numbers on a line, while bolding the text and switching it to a deeper blue ties it to the title and the header row. These settings apply to the data table alone; the chart title, axis labels and legend keep their own fonts.

Borders, legend keys and text formatting:

Syntax Result
chart.DataTable Takes the data table object of the chart
table.HasBorders = false Removes the outer frame of the data table
table.HasVertBorder = false Removes the vertical separators between columns
table.HasHorzBorder = true Keeps the horizontal separators between rows
table.ShowSeriesKeys = true Shows a legend key in front of every series name
table.FontName = 'Arial' Sets the data table text to Arial
table.Size = 9 Sets the data table text to 9 points
table.IsBold = true Bolds the data table text
table.Color = xlsModule.Color.FromArgb(255, 28, 68, 118) Sets the data table text to a deep blue

The steps are:

  1. Load the font and the test data file into the VFS with window.spire.FetchFileToVFS, then load the workbook with workbook.LoadFromFile.
  2. Take the first worksheet with workbook.Worksheets.get(0) and the first chart with sheet.Charts.get(0).
  3. Set chart.HasDataTable to true to open the data table, then take the object with chart.DataTable.
  4. Set table.HasBorders and table.HasVertBorder to false and table.HasHorzBorder to true, so only the horizontal lines remain.
  5. Set table.ShowSeriesKeys to true to show the legend key before each series name.
  6. Set table.FontName, table.Size and table.IsBold to choose the typeface, the size and the bold weight.
  7. Build a deep blue with xlsModule.Color.FromArgb and assign it to table.Color.
  8. Save the workbook with workbook.SaveToFile and dispose of it with workbook.Dispose to free resources.

The full code example below shows how to adjust the data table borders, legend keys and text formatting in React:

function App() {
  const customizeDataTable = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font and the test data file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'ChartSales.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook and take the first worksheet and its chart
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });
    const sheet = workbook.Worksheets.get(0);
    const chart = sheet.Charts.get(0);

    // Turn on the data table and take its object
    chart.HasDataTable = true;
    const table = chart.DataTable;

    // Drop the outer frame and the vertical lines, keeping only the horizontal ones
    table.HasBorders = false;
    table.HasVertBorder = false;
    table.HasHorzBorder = true;

    // Show the legend key in front of each series name
    table.ShowSeriesKeys = true;

    // Set the data table font, size, bold weight and text colour
    table.FontName = 'Arial';
    table.Size = 9;
    table.IsBold = true;
    table.Color = xlsModule.Color.FromArgb(255, 28, 68, 118);

    // Save the workbook
    const outputFileName = 'DataTableFormatting.xlsx';
    workbook.SaveToFile({ fileName: outputFileName });

    // Dispose of the workbook to release its resources
    workbook.Dispose();

    // Read the result back out of the VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add a Data Table to an Excel Chart</h1>
      <button id="data-table-formatting" onClick={customizeDataTable}>Adjust the Borders, Legend Keys and Text</button>
    </div>
  );
}

export default App;

The data table after adjusting the borders, legend keys and text formatting:

The data table after adjusting the borders, legend keys and text formatting


FAQ

What is the difference between a data table and data labels?

Cause: Data labels sit next to each data point and show only that point's value. A data table sits below the chart, one row per series, and gives the category names and all the values together.

Solution: Use data labels when each point needs a callout without a table taking up space; use a data table when readers should take in a whole set of values at once. Both can be present on the same chart and turned on or off as needed.

How do I remove the data table from a chart?

Cause: The data table is controlled by a single switch on the chart; once it is on, it does not disappear with a change of source data or chart type.

Solution: Set chart.HasDataTable to false and save the workbook; the data table below the chart is removed.

How can the data table use a different font from the rest of the chart?

Cause: The data table carries its own text formatting. Until it is set, it follows the rest of the chart's text; once set, only the data table changes.

Solution: Set FontName, Size, IsBold and Color on chart.DataTable. These properties act on the data table only and leave the chart title, axis labels and legend untouched.

What is the legend key in a data table?

Cause: A legend key is the small colour swatch shown in front of a series name, matching the series' marker in the legend. It is off by default, so the data table shows plain text.

Solution: Set table.ShowSeriesKeys to true; a swatch then appears in front of every series name, so a reader can match a row of the data table with the legend directly.


Get a Free License

Spire.XLS for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.

Text boxes in a worksheet carry notices, reminders or a single conclusion, yet their default look is plain: small black text on white, framed by a thin border that blends into the grid. Enlarging and bolding the font and laying down a light fill make the text rise above the table; inner margins and text wrapping keep long sentences off the border and inside the box; removing the border lets a text box read as a quiet annotation. These changes can be applied in code in one pass instead of one box at a time. Spire.XLS for JavaScript runs in the browser on WebAssembly and handles the input and output files through a virtual file system (VFS), with no backend service required.

This article covers two core feature points:

For installation and project setup, see Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module has been initialised.


Adjust the Font, Background and Border of Text Boxes

The default 11-point black text on a white background lacks contrast against the sheet. A larger size, a bold weight, another color and a pale fill lift a notice above the grid; clearing a border that competes with the cell lines makes the text read as if written straight on the page, which suits footnotes and corner notes. The same two kinds of change can be applied to one text box or split across different boxes, and this feature point adjusts the font, background and border of text boxes.

Syntax Result
workbook.CreateFont() Creates a font object for the text of a text box
font.FontName, font.Size, font.IsBold, font.Color Set the font name, size, bold weight and text color
xlsModule.RichTextShape.Convert(textBox.RichText) Returns the rich text object of the text box
richText.SetFont(0, textBox.Text.length - 1, font) Applies the font to the whole text of the text box
textBox.Fill.FillType = xlsModule.ShapeFillType.SolidColor Switches the text box background to a solid fill
textBox.Fill.ForeColor Sets the color of the solid fill
textBox.Line.Weight = 0 Sets the border weight to zero, so no outline is drawn

The steps are:

  1. Take the first text box with sheet.TextBoxes.get(0).
  2. Create a font object with workbook.CreateFont() and set its name, size, bold weight and color through FontName, Size, IsBold and Color.
  3. Get the rich text object with xlsModule.RichTextShape.Convert(textBox.RichText), then call SetFont(0, textBox.Text.length - 1, font) to apply the font to the whole text.
  4. Set textBox.Fill.FillType to xlsModule.ShapeFillType.SolidColor, then name the fill color with textBox.Fill.ForeColor.
  5. Take the fourth text box with sheet.TextBoxes.get(3) and set textBox.Line.Weight to 0 to remove its border.
  6. Save the workbook with workbook.SaveToFile.

The code below is the complete example of adjusting the font, background and border of a text box:

function App() {
  const adjustTextAppearance = async () => {
    // get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // load the font and the test data file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'TextBoxSample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // load the workbook and take the first worksheet
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });
    const sheet = workbook.Worksheets.get(0);

    // take the first text box and create a font with its name, size, bold weight and color
    const textBox = sheet.TextBoxes.get(0);
    const font = workbook.CreateFont();
    font.FontName = 'Arial';
    font.Size = 14;
    font.IsBold = true;
    font.Color = xlsModule.Color.FromArgb(255, 28, 68, 118);

    // apply the font to all the text in the text box
    const richText = xlsModule.RichTextShape.Convert(textBox.RichText);
    richText.SetFont(0, textBox.Text.length - 1, font);

    // fill the text box background with a solid color
    textBox.Fill.FillType = xlsModule.ShapeFillType.SolidColor;
    textBox.Fill.ForeColor = xlsModule.Color.FromArgb(255, 232, 240, 250);

    // take the fourth text box and set the border weight to 0, which removes the border
    const borderBox = sheet.TextBoxes.get(3);
    borderBox.Line.Weight = 0;

    // save the workbook
    const outputFileName = 'TextAppearance.xlsx';
    workbook.SaveToFile({ fileName: outputFileName });

    // dispose of the workbook to release its resources
    workbook.Dispose();

    // read the result back out of the VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Format Excel Text Boxes</h1>
      <button onClick={adjustTextAppearance}>Adjust the Font, Background and Border of a Text Box</button>
    </div>
  );
}

export default App;

The notice board after adjusting the font, background and border:

The notice board after adjusting the font, background and border


Set the Inner Margins and Text Wrapping of Text Boxes

Text pressed against the border is hard to read, especially on a dark fill. Inner margins hold the text away from each edge and can be set separately for the four sides. A long sentence in a narrow box stays on one line by default and runs past the border, while text wrapping folds it onto the next line. The sample leaves about 1 cm on the left and right and 0.4 cm at the top and bottom, and aligns the text to the top left so the shift caused by the margins is visible. This feature point sets the inner margins and text wrapping of text boxes.

Syntax Result
textBox.InnerLeftMargin, InnerRightMargin, InnerTopMargin, InnerBottomMargin Set the distance between the text and the left, right, top and bottom border
xlsModule.CommentHAlignType.Left Aligns the text to the left inside the box
xlsModule.CommentVAlignType.Top Aligns the text to the top inside the box
textBox.IsWrapText = true Folds the text onto the next line when it reaches the box width

The steps are:

  1. Take the second text box with sheet.TextBoxes.get(1).
  2. Set InnerLeftMargin, InnerRightMargin, InnerTopMargin and InnerBottomMargin in turn to leave room on all four sides.
  3. Set HAlignment to xlsModule.CommentHAlignType.Left and VAlignment to xlsModule.CommentVAlignType.Top, so the text starts from the top-left corner.
  4. Take the third text box with sheet.TextBoxes.get(2) and set IsWrapText to true to turn on text wrapping.
  5. Save the workbook with workbook.SaveToFile.

The code below is the complete example of setting the inner margins and text wrapping of a text box:

function App() {
  const setTextLayout = async () => {
    // get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // load the font and the test data file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'TextBoxSample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // load the workbook and take the first worksheet
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });
    const sheet = workbook.Worksheets.get(0);

    // take the second text box and set the space between the text and its four borders
    const textBox = sheet.TextBoxes.get(1);
    textBox.InnerLeftMargin = 1;
    textBox.InnerRightMargin = 1;
    textBox.InnerTopMargin = 0.4;
    textBox.InnerBottomMargin = 0.4;

    // align the text to the top left so the effect of the margins is visible
    textBox.HAlignment = xlsModule.CommentHAlignType.Left;
    textBox.VAlignment = xlsModule.CommentVAlignType.Top;

    // take the third text box and turn on wrapping, so text folds at the box width
    const wrapBox = sheet.TextBoxes.get(2);
    wrapBox.IsWrapText = true;

    // save the workbook
    const outputFileName = 'TextLayout.xlsx';
    workbook.SaveToFile({ fileName: outputFileName });

    // dispose of the workbook to release its resources
    workbook.Dispose();

    // read the result back out of the VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Format Excel Text Boxes</h1>
      <button onClick={setTextLayout}>Set the Inner Margins and Text Wrapping of a Text Box</button>
    </div>
  );
}

export default App;

The notice board after setting the inner margins and text wrapping:

The notice board after setting the inner margins and text wrapping


FAQ

How do I get a text box by name?

Cause: Getting text boxes by index means remembering their order in the collection, and inserting or removing a text box changes that order.

Solution: Use sheet.TextBoxes.get("TextBox 2") to get a text box by name.

How do I format only part of the text in a text box?

Cause: The text of a text box is stored as rich text, and SetFont applies to a character range; anything outside the range keeps its original format.

Solution: Get the rich text object with xlsModule.RichTextShape.Convert(textBox.RichText), then call richText.SetFont(startIndex, endIndex, font) with the range you want. For example, SetFont(0, 3, font) applies to the first four characters only.

Can the border of a text box have another color or a dashed style?

Cause: Besides its weight, the Line object also provides color and dash style settings.

Solution: Set the border color with textBox.Line.ForeColor, the weight with textBox.Line.Weight, and the dash style with textBox.Line.DashStyle, whose value is a member of xlsModule.ShapeDashLineStyleType, such as Dashed for a dashed line.

What if the text does not wrap as expected?

Cause: Text only wraps when IsWrapText is true, and when the text box is wide enough for the whole sentence no line break appears either.

Solution: Confirm that textBox.IsWrapText = true has been set, and check that the width of the text box is smaller than the length of the sentence. When several lines are needed, leave enough height in the text box as well.


Get a Free License

Spire.XLS for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.

Page 5 of 371
page 5