When a Word document from another system is tidied up, its body often still holds explanatory paragraphs that are no longer used, and copy-paste and repeated line breaks leave a large number of blank paragraphs. Such content takes up space and affects the consistency and readability of the document. Removing the paragraphs one by one by hand requires repeated manual work and is hard to fit into a batch web workflow; handling it on the backend would mean uploading the document to a server.
This article uses Spire.Doc for JavaScript to remove paragraphs from a Word document in the browser. The document is loaded through the virtual file system (VFS); when removal is finished, it is saved and downloaded directly. The whole process runs on the client side with WebAssembly, with no Office installation and no backend service required.
This article covers three features:
- Remove a Specific Paragraph from a Word Document
- Remove Blank Paragraphs from a Word Document
- Remove All Paragraphs from a Word Document
For installation and project setup, refer to Integrating Spire.Doc for JavaScript in a React Project. The examples below assume that Spire.Doc is installed and the WebAssembly module is initialized.
Remove a Specific Paragraph from a Word Document
A section in a Word document consists of a number of body objects, and the paragraphs among them are managed by the Section.Paragraphs collection. Spire.Doc for JavaScript offers two ways to remove items from the collection:
| Method | Based on |
|---|---|
Paragraphs.RemoveAt(index) |
The position of the paragraph (zero-based index) |
Paragraphs.Remove(paragraph) |
The paragraph object itself |
The index starts at 0, so the first paragraph corresponds to index 0. Each removal shifts the indexes of the following paragraphs forward by one. The sample document contains 11 paragraphs in total; the 6th paragraph (index 5) is a note left over from the 2019 edition, and it has to be removed before the formal release.
The specific steps are as follows:
- Get the Spire.Doc WASM module and confirm that it is ready.
- Load the font, read the sample document into the VFS and load it as a
Document. - Get the first section and call
Section.Paragraphs.RemoveAt()to remove the paragraph at index 5. - Save the result file with
SaveToFile(). - Read the result file from the VFS and trigger a browser download.
The code for removing a specific paragraph from a Word document is as follows:
function App() {
const removeParagraph = async () => {
// Get the Spire.Doc WASM module
const wasmModule = window.wasmModule?.spiredoc;
// Check if the module is ready
if (!wasmModule) {
alert('Spire.Doc is not ready yet');
return;
}
// Load the document to be processed
await window.spire.FetchFileToVFS('Sample.docx', '', `${process.env.PUBLIC_URL}/data/`);
// Create a Document instance and load the document
const doc = new wasmModule.Document();
doc.LoadFromFile('Sample.docx');
// Get the first section
const section = doc.Sections.get_Item(0);
// Remove the paragraph at index 5, that is the 6th paragraph in the body
section.Paragraphs.RemoveAt(5);
// Save the result file
const outputFileName = 'RemoveParagraph.docx';
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013 });
doc.Dispose();
// Read the generated 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.wordprocessingml.document' });
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 a Specific Paragraph from a Word Document</h1>
<button onClick={removeParagraph}>
Remove Paragraph
</button>
</div>
);
}
export default App;
In the document after the paragraph has been removed, the original 6th paragraph is no longer in the body:

Remove a Specific Paragraph by Paragraph Object
Paragraphs.RemoveAt() removes by position, whereas Paragraphs.Remove() takes a paragraph object directly. To remove a particular paragraph, retrieve it first with Paragraphs.get_Item(index) and then pass it to Remove():
// Remove by object: retrieve the paragraph at index 5 first, then remove it
const section = doc.Sections.get_Item(0);
const paragraph = section.Paragraphs.get_Item(5);
section.Paragraphs.Remove(paragraph);
Both forms produce the same result. When the paragraph reference is already available and its position no longer matters, removal by object is the more direct option.
Remove Blank Paragraphs from a Word Document
A blank paragraph is a paragraph in the body that contains no text, and it is common in documents copied from web pages or edited with repeated line breaks. To determine whether a paragraph is blank, read its Text property: a paragraph is treated as blank when the text is an empty string after leading and trailing whitespace is removed, and a paragraph that contains spaces only is also a blank paragraph.
Section.Body.ChildObjects is the collection of child objects in the section body; it contains paragraphs as well as other body objects such as tables. When iterating, use the DocumentObjectType property to tell object types apart and process paragraphs only. The sample document has 6 blank paragraphs between the body paragraphs, two of which contain spaces only:

The specific steps are as follows:
- Get the Spire.Doc WASM module and confirm that it is ready.
- Load the font, read the sample document into the VFS and load it as a
Document. - Iterate over every section in the document and obtain the
Body.ChildObjectscollection of the section body. - Iterate over the collection backwards, and for each object whose
DocumentObjectTypeisDocumentObjectType.Paragraphand whoseTextis empty after trimming, remove it withChildObjects.Remove(). - Save the result file with
SaveToFile(), read it from the VFS and trigger a browser download.
The code for removing blank paragraphs from a Word document is as follows:
function App() {
const removeBlankParagraphs = async () => {
// Get the Spire.Doc WASM module
const wasmModule = window.wasmModule?.spiredoc;
// Check if the module is ready
if (!wasmModule) {
alert('Spire.Doc is not ready yet');
return;
}
// Load the document to be processed
await window.spire.FetchFileToVFS('SampleWithBlankLines.docx', '', `${process.env.PUBLIC_URL}/data/`);
// Create a Document instance and load the document
const doc = new wasmModule.Document();
doc.LoadFromFile('SampleWithBlankLines.docx');
// Process the sections one by one; the sample document has only one section
for (let s = 0; s < doc.Sections.Count; s++) {
const body = doc.Sections.get_Item(s).Body;
// Iterate backwards so that removal does not affect the indexes not yet processed
for (let i = body.ChildObjects.Count - 1; i >= 0; i--) {
const item = body.ChildObjects.get_Item(i);
// Process paragraphs only; other body objects such as tables stay untouched
if (item.DocumentObjectType !== wasmModule.DocumentObjectType.Paragraph) {
continue;
}
// Empty after trimming, so it is treated as a blank paragraph
if (item.Text.trim() === '') {
body.ChildObjects.Remove(item);
}
}
}
// Save the result file
const outputFileName = 'RemoveBlankParagraphs.docx';
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013 });
doc.Dispose();
// Read the generated 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.wordprocessingml.document' });
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 Blank Paragraphs from a Word Document</h1>
<button onClick={removeBlankParagraphs}>
Remove Blank Paragraphs
</button>
</div>
);
}
export default App;
In the document after the blank paragraphs have been removed, the body paragraphs follow one another directly:

Remove All Paragraphs from a Word Document
To empty the body of the whole document, call Section.Paragraphs.Clear() on each section. The method removes every paragraph in the body of that section, with no need to work out the indexes one by one:
| Method | Scope |
|---|---|
Section.Paragraphs.Clear() |
All paragraphs in the body of that section |
Section.Paragraphs.RemoveAt(index) |
The paragraph at the specified position in the body of that section |
A document with several sections has to be cleared section by section. Tables are not part of the paragraph collection, so they remain after the paragraphs have been cleared.
The specific steps are as follows:
- Get the Spire.Doc WASM module and confirm that it is ready.
- Load the font, read the sample document into the VFS and load it as a
Document. - Iterate over every section in the document and call
Section.Paragraphs.Clear()on the paragraph collection of each section. - Save the result file with
SaveToFile(). - Read the result file from the VFS and trigger a browser download.
The code for removing all paragraphs from a Word document is as follows:
function App() {
const removeAllParagraphs = async () => {
// Get the Spire.Doc WASM module
const wasmModule = window.wasmModule?.spiredoc;
// Check if the module is ready
if (!wasmModule) {
alert('Spire.Doc is not ready yet');
return;
}
// Load the document to be processed
await window.spire.FetchFileToVFS('Sample.docx', '', `${process.env.PUBLIC_URL}/data/`);
// Create a Document instance and load the document
const doc = new wasmModule.Document();
doc.LoadFromFile('Sample.docx');
// Clear the body paragraphs of every section one by one
for (let s = 0; s < doc.Sections.Count; s++) {
doc.Sections.get_Item(s).Paragraphs.Clear();
}
// Save the result file
const outputFileName = 'RemoveAllParagraphs.docx';
doc.SaveToFile({ fileName: outputFileName, fileFormat: wasmModule.FileFormat.Docx2013 });
doc.Dispose();
// Read the generated 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.wordprocessingml.document' });
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 All Paragraphs from a Word Document</h1>
<button onClick={removeAllParagraphs}>
Remove All Paragraphs
</button>
</div>
);
}
export default App;
In the document after all paragraphs have been removed, no body content remains on the page:

FAQ
Why is a paragraph other than the expected one removed
Section.Paragraphs indexes by position, the index starts at 0, and blank paragraphs in the body are counted as well. The index at the same position usually points to different paragraphs in different documents: the sample document removes the 6th paragraph, but with another document index 5 may well be something else. Before removing, iterate over the collection and read the Text of each paragraph to confirm the position; alternatively, locate the target paragraph by its content and remove it with Paragraphs.Remove().
Why is there still a gap between paragraphs after the blank paragraphs have been removed
Gaps between paragraphs come from two sources: the blank paragraphs themselves, and the paragraph's own space before, space after and line spacing. Removing the blank paragraphs only removes the first source; the body paragraphs of the sample document have a 6-point space after, so gaps remain between them. For a tighter layout, adjust the spacing in the paragraph format instead, for example by setting the space after of every body paragraph to 0:
// Set the space after of every body paragraph to 0; the unit is points
const paragraphs = doc.Sections.get_Item(0).Paragraphs;
for (let i = 0; i < paragraphs.Count; i++) {
paragraphs.get_Item(i).Format.AfterSpacing = 0;
}
Are tables in the document removed as well
No. Clear() acts on Section.Paragraphs, and that collection holds body paragraphs only; a table is another kind of body object and is not included in the collection, so it remains after the paragraphs have been cleared. Paragraphs inside table cells are likewise outside Section.Paragraphs, so iterating over the section body objects to remove blank paragraphs does not reach inside tables either.
Why does an index-out-of-range error occur when several paragraphs are removed at once
Each removal shifts the indexes of the following paragraphs forward by one, and the total count drops as well. When fixed indexes are removed in increasing order, the second removal is usually no longer the paragraph intended; once an index exceeds Paragraphs.Count - 1, RemoveAt() throws ArgumentOutOfRange_IndexMustBeLess. To remove several paragraphs, iterate from the end, always remove index 0, or adjust the index after each removal, as in the body-object walk.
Why does the saved document contain an extra English notice
When the document is saved with the evaluation version, Spire.Doc inserts an evaluation notice into the body (Evaluation Warning: The document was created with Spire.Doc for JavaScript.), and it is unrelated to the paragraph removal logic. After a temporary license is applied for or a commercial license is used, the paragraph no longer appears in the saved result.
Get a Free License
Spire.Doc for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.