In contracts, application forms, report templates, and other Word documents, you may need to prevent users from changing certain content while still leaving selected areas editable.
For example, a document can be made read-only, restricted to tracked changes or comments, or configured so that only form fields can be filled in. You can also protect most of the document while leaving specific ranges open for editing.
These restrictions are different from a document open password. An open password controls whether someone can access the file at all, while editing restrictions control what users can do after the document has been opened.
This article shows how to apply editing restrictions to Word documents in Java and how to define editable exceptions inside a protected document.
Add the Dependency
The examples below use Spire.Doc for Java to work with Word documents. For Maven projects, add its repository and dependency to pom.xml:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>14.7.4</version>
</dependency>
</dependencies>
Restrict Editing in a Word Document
Use Document.protect() to apply editing restrictions and ProtectionType to specify what users are still allowed to do.
Common protection types include:
| ProtectionType | Allowed Action |
|---|---|
Allow_Only_Reading | View the document without editing it |
Allow_Only_Revisions | Edit the document with changes recorded as revisions |
Allow_Only_Comments | Add or modify comments only |
Allow_Only_Form_Fields | Fill in form fields only |
No_Protection | No editing restriction |
The following example makes a Word document read-only:
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.ProtectionType;
public class RestrictWordEditing {
public static void main(String[] args) {
// Load the Word document
Document doc = new Document();
doc.loadFromFile("Contract.docx");
// Make the document read-only and set a password
// for removing the restriction
doc.protect(
ProtectionType.Allow_Only_Reading,
"123456"
);
// Save the document
doc.saveToFile(
"Contract_Protected.docx",
FileFormat.Docx_2019
);
doc.close();
}
}
To use another restriction mode, change the ProtectionType.
For example, to allow comments only:
doc.protect(
ProtectionType.Allow_Only_Comments,
"123456"
);
For documents that go through review, Allow_Only_Revisions is often more useful. Users can still edit the content, but their changes are recorded as revisions that can later be accepted or rejected.
For templates containing text form fields, check boxes, or similar controls, Allow_Only_Form_Fields can be used to limit editing to those fields.
The password passed to protect() is used to remove the editing restriction. It is not a password for opening the document. If the file itself should require a password before it can be opened, document encryption must be configured separately.
Allow a Specific Range to Remain Editable
Making the entire document read-only is not always enough. A common requirement is to lock standard contract clauses or instructions while leaving selected content editable.
Spire.Doc provides PermissionStart and PermissionEnd to mark a range that remains editable inside a protected document.
The following example protects the document while allowing the first six paragraphs to remain editable:
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.PermissionEnd;
import com.spire.doc.PermissionStart;
import com.spire.doc.ProtectionType;
import com.spire.doc.Section;
public class AllowEditingInSpecifiedRange {
public static void main(String[] args) {
// Load the Word document
Document doc = new Document();
doc.loadFromFile("ContractTemplate.docx");
// Create a pair of permission markers
PermissionStart start =
new PermissionStart(doc, "EditableRange1");
PermissionEnd end =
new PermissionEnd(doc, "EditableRange1");
// Get the target section
Section section = doc.getSections().get(0);
// Insert the start marker at the beginning
// of the first paragraph
section.getParagraphs()
.get(0)
.getChildObjects()
.insert(0, start);
// Insert the end marker at the end
// of the sixth paragraph
section.getParagraphs()
.get(5)
.getChildObjects()
.add(end);
// Make the rest of the document read-only
doc.protect(
ProtectionType.Allow_Only_Reading,
"123456"
);
// Save the result
doc.saveToFile(
"ContractTemplate_Protected.docx",
FileFormat.Docx_2019
);
doc.close();
}
}
PermissionStart and PermissionEnd must use the same permission ID:
new PermissionStart(doc, "EditableRange1");
new PermissionEnd(doc, "EditableRange1");
Word uses this matching ID to identify the content between the two markers as one editable range.
In the example above, the start marker is inserted before the first child object of the first paragraph, while the end marker is appended to the sixth paragraph. Everything between those markers remains editable.
If only part of a paragraph should be editable, the markers can be inserted around specific TextRange objects instead of using entire paragraphs as boundaries.
For templates that change regularly, it is usually better to locate the target content through bookmarks, placeholder text, or another stable marker rather than relying on fixed paragraph indexes.
Use Unique IDs for Multiple Editable Ranges
A document can contain several editable areas, for example:
CustomerInfo
ContractAmount
Remarks
Each range should use its own permission ID, and every PermissionStart must have a matching PermissionEnd.
If the IDs do not match, or if a start marker is inserted without the correct end marker, the editable range may not behave as expected.
When editable ranges are created dynamically from business configuration, use clear and unique IDs instead of reusing the same hard-coded value for every range.
Remove Editing Restrictions from a Word Document
To restore normal editing, set the protection type to No_Protection:
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.spire.doc.ProtectionType;
public class RemoveEditingRestriction {
public static void main(String[] args) {
// Load the protected Word document
Document doc = new Document();
doc.loadFromFile("Contract_Protected.docx");
// Remove the editing restriction
doc.protect(ProtectionType.No_Protection);
// Save the result
doc.saveToFile(
"Contract_Unprotected.docx",
FileFormat.Docx_2019
);
doc.close();
}
}
If the document only uses document-level protection, this is usually enough.
However, if PermissionStart and PermissionEnd were added to define editable exceptions, those markers remain part of the document structure.
If the output should be a fully cleaned document with no remaining permission markers, remove them as well:
import com.spire.doc.Document;
import com.spire.doc.DocumentObject;
import com.spire.doc.FileFormat;
import com.spire.doc.PermissionEnd;
import com.spire.doc.PermissionStart;
import com.spire.doc.ProtectionType;
import com.spire.doc.Section;
import com.spire.doc.documents.Paragraph;
public class RemoveEditingRestrictionAndPermissions {
public static void main(String[] args) {
Document doc = new Document();
doc.loadFromFile("ContractTemplate_Protected.docx");
// Remove document protection
doc.protect(ProtectionType.No_Protection);
// Remove permission markers
for (int s = 0; s < doc.getSections().getCount(); s++) {
Section section = doc.getSections().get(s);
for (int p = 0; p < section.getParagraphs().getCount(); p++) {
Paragraph paragraph = section.getParagraphs().get(p);
for (int i = 0;
i < paragraph.getChildObjects().getCount();) {
DocumentObject obj =
paragraph.getChildObjects().get(i);
if (obj instanceof PermissionStart
|| obj instanceof PermissionEnd) {
paragraph.getChildObjects().remove(obj);
} else {
i++;
}
}
}
}
doc.saveToFile(
"ContractTemplate_Unprotected.docx",
FileFormat.Docx_2019
);
doc.close();
}
}
Notice that i is not incremented after an object is removed. Once the current item is deleted, the next object shifts into the same index. Incrementing immediately would skip that object, which matters if two permission markers appear next to each other.
Editing Restrictions Are Not the Same as Document Encryption
Editing restrictions control what users can do after the document is opened:
doc.protect(
ProtectionType.Allow_Only_Reading,
"123456"
);
Encryption controls whether the document can be opened without a password.
So "users can open the file but cannot edit it" and "users cannot open the file without a password" are separate requirements. A document can use both, but protect() should not be treated as file-access control.
Editing restrictions are also intended to control normal Word editing behavior rather than provide strong data security. If the content itself must be protected from unauthorized access, encryption or another access-control mechanism should be used.
Practical Considerations
For fixed templates, editable ranges can be defined directly around paragraphs, table cells, or other document objects.
For templates that change often, hard-coded indexes such as:
section.getParagraphs().get(5)
can become fragile. Adding a title or instruction paragraph may shift the target content and place the editable range in the wrong location.
Bookmarks, placeholder text, or other stable document markers usually make better anchors for editable ranges.
It is also worth checking whether the document already contains editing restrictions or permission markers before applying new ones. Reprocessing the same template without checking its existing structure can result in duplicate or overlapping permission ranges.
Conclusion
For Word templates that need to be maintained over time, the most important part is not the paragraph number used in the code, but how reliably the application can locate the content that should remain editable.
Stable anchors such as bookmarks or placeholders make the protection logic much less dependent on layout changes and help keep the code working when the template evolves.
Comments
Post a Comment