In daily Excel document processing, textboxes are often used to add explanatory text, annotations, or tips to data — whether adding comments to reports or extracting annotation content from existing documents, the add/remove/modify operations on textboxes are essential. Spire.XLS for JavaScript completes these operations directly in the browser based on WebAssembly, managing input and output files through a virtual file system (VFS), with no backend service required.
This article covers three core features:
For installation and project configuration, refer to Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module is initialized.
Add TextBox
Adding textboxes to a worksheet provides supplementary explanations for data, such as operation guidance or notes. Spire.XLS for JavaScript inserts a textbox at a specified position with the Worksheet.TextBoxes.AddTextBox() method, after which you can set the text, alignment, font, and background color of the textbox, or fill it with a picture. The main steps are as follows:
- Create a
Workbookobject and use theLoadFromFile()method to load the Excel document. - Use the
Workbook.Worksheets.get()method to get a specific worksheet. - Use the
Worksheet.TextBoxes.AddTextBox()method to add the first textbox, and set its text, horizontal/vertical center alignment, font, and background color. - Use the
Worksheet.TextBoxes.AddTextBox()method to add a second textbox and fill it with a picture. - Use the
Workbook.SaveToFile()method to save the document to a specified path.
Here is a complete code example showing how to add two textboxes to a worksheet in React — one containing text and one filled with a picture:
function App() {
const addTextBox = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font, Excel file and picture into the VFS
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'TextBox.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
await window.spire.FetchFileToVFS('logo.png', '', `${process.env.PUBLIC_URL}data/`);
// Load the workbook
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// Get the first worksheet
const sheet = workbook.Worksheets.get(0);
// Add the first textbox and set its position and size
const textBox = sheet.TextBoxes.AddTextBox(3, 2, 50, 196);
// Set the text in the textbox
textBox.Text = 'Insert Excel TextBox';
// Set the text to be centered horizontally and vertically
textBox.HAlignment = xlsModule.CommentHAlignType.Center;
textBox.VAlignment = xlsModule.CommentVAlignType.Center;
// Set the font of the textbox (bold, white, 12pt)
const font = workbook.CreateFont();
font.FontName = 'Arial';
font.Size = 12;
font.IsBold = true;
font.Color = xlsModule.Color.get_White();
const rt = xlsModule.RichTextShape.Convert(textBox.RichText);
rt.SetFont(0, textBox.Text.length - 1, font);
// Set the background color of the textbox to blue-gray
textBox.Fill.FillType = xlsModule.ShapeFillType.SolidColor;
textBox.Fill.ForeKnownColor = xlsModule.ExcelColors.BlueGray;
// Add the second textbox and set its position and size
const textBox2 = sheet.TextBoxes.AddTextBox(6, 5, 90, 90);
// Load a picture and fill the textbox with it
textBox2.Fill.CustomPicture('logo.png');
textBox2.Fill.FillType = xlsModule.ShapeFillType.Picture;
// Set the border of the second textbox to 0
textBox2.Line.Weight = 0;
// Save the document
const outputFileName = 'AddTextBox_output.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the converted file from 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 TextBox</h1>
<button onClick={addTextBox}>
Start
</button>
</div>
);
}
export default App;
The result of adding the textboxes 
Extract Text and Image from TextBox
When you need to aggregate or reuse annotation information in existing documents, you can iterate through the textboxes and extract their text content and fill images. Spire.XLS for JavaScript gets the number of textboxes with Worksheet.TextBoxes.Count and iterates over each textbox with the Worksheet.TextBoxes.get() method: it reads the Text property to obtain the text content, checks the fill type through Fill.FillType, and extracts the fill image through the Fill.Picture property, finally saving the results as a txt file and a png image file respectively. The main steps are as follows:
- Create a
Workbookobject and use theLoadFromFile()method to load the Excel document. - Use the
Workbook.Worksheets.get()method to get a specific worksheet. - Iterate over each textbox in the
TextBoxescollection withWorksheet.TextBoxes.CountandWorksheet.TextBoxes.get(). - Read the
Textproperty of each textbox to collect the text content. - For a textbox filled with a picture, get its fill image through the
Fill.Pictureproperty and save it as a png file. - Write the collected text into a txt file.
Here is a complete code example showing how to extract text and images from a textbox in React:
function App() {
const extractTextAndImage = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font and Excel file into the VFS
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'TextBox.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// Load the workbook
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// Get the first worksheet
const sheet = workbook.Worksheets.get(0);
// Iterate over all textboxes in the worksheet and extract text and pictures
const textLines = [];
const pictureFiles = [];
for (let i = sheet.TextBoxes.Count - 1; i >= 0; i--) {
const shape = sheet.TextBoxes.get(i);
// Extract the text in the textbox
if (shape.Text) {
textLines.push(shape.Text);
}
// Extract the fill picture of the textbox
if (shape.Fill.FillType === xlsModule.ShapeFillType.Picture) {
const picture = shape.Fill.Picture;
const imageFile = 'ExtractedImage' + i + '.png';
picture.Save(imageFile);
pictureFiles.push(imageFile);
}
}
// Save the extracted text as a txt file
const textFile = 'ExtractedText.txt';
window.dotnetRuntime.Module.FS.writeFile(textFile, textLines.join('\r\n'));
// Release resources
workbook.Dispose();
// Read the extracted txt file from the VFS and trigger the download
const txtArray = window.dotnetRuntime.Module.FS.readFile(textFile);
const txtBlob = new Blob([txtArray], { type: 'text/plain' });
const txtUrl = URL.createObjectURL(txtBlob);
const txtAnchor = document.createElement('a');
txtAnchor.href = txtUrl;
txtAnchor.download = textFile;
txtAnchor.click();
URL.revokeObjectURL(txtUrl);
// Read the extracted picture files from the VFS and trigger the downloads
for (const imageFile of pictureFiles) {
const imageArray = window.dotnetRuntime.Module.FS.readFile(imageFile);
const imageBlob = new Blob([imageArray], { type: 'application/png' });
const imageUrl = URL.createObjectURL(imageBlob);
const imageAnchor = document.createElement('a');
imageAnchor.href = imageUrl;
imageAnchor.download = imageFile;
imageAnchor.click();
URL.revokeObjectURL(imageUrl);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Extract Text And Image From TextBox</h1>
<button onClick={extractTextAndImage}>
Start
</button>
</div>
);
}
export default App;
The result of extracting the text and image from the textbox 
Remove TextBox
When annotation information in a document is no longer needed, you can delete it to keep the worksheet tidy. Spire.XLS for JavaScript deletes a specified textbox by index with the Worksheet.TextBoxes.RemoveAt() method. The main steps are as follows:
- Create a
Workbookobject and use theLoadFromFile()method to load the Excel document. - Use the
Workbook.Worksheets.get()method to get a specific worksheet. - Use the
Worksheet.TextBoxes.RemoveAt()method to delete the textbox at a specified index. - Use the
Workbook.SaveToFile()method to save the document to a specified path.
Here is a complete code example showing how to remove a textbox from a worksheet in React:
function App() {
const removeTextBox = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font and Excel file into the VFS
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'TextBox.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// Load the workbook
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// Get the first worksheet
const sheet = workbook.Worksheets.get(0);
// Remove the first textbox
sheet.TextBoxes.RemoveAt(0);
// Save the document
const outputFileName = 'RemoveTextBox_output.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the converted file from 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>Remove TextBox</h1>
<button onClick={removeTextBox}>
Start
</button>
</div>
);
}
export default App;
The result of removing the textbox 
Frequently Asked Questions
The added textbox does not display in the result document
Cause: The row and column coordinates specified in the AddTextBox() method are out of range, or the font file was not loaded into the VFS, so the text in the textbox cannot be rendered properly.
Solution: Make sure the row and column coordinates are within the worksheet range, and ensure the required font has been loaded via FetchFileToVFS() before use, for example:
await window.spire.FetchFileToVFS(
'ARIAL.TTF', '/Library/Fonts/', '/'
);
An error occurs when extracting an image due to the fill type
Cause: Accessing the Fill.Picture property directly only works for textboxes filled with a picture. If no image fill is set on the textbox (for example, a solid-color fill), accessing this property throws an exception.
Solution: Check whether the Fill.FillType of the textbox is Picture before accessing Fill.Picture; only then get the picture and call the Save() method to save it.
Obtain 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.