If the table is in an editable region (between PermStart
and PermEnd
) then it will be editable including adding rows.
The PermStart
and PermEnd
can be inserted in document body using
// CTPermStart marking the start of unprotected range
CTPermStart ctPermStart = document.getDocument().getBody().addNewPermStart();
ctPermStart.setEdGrp(STEdGrp.EVERYONE);
ctPermStart.setId("123456"); //note the Id
and
// CTPerm marking the end of unprotected range
document.getDocument().getBody().addNewPermEnd().setId("123456"); //note the same Id
All body elements between this PermStart
and PermEnd
are editable in a protected document. That is true also for tables between this PermStart
and PermEnd
.
If only parts of tables shall be editable, then PermStart
and PermEnd
also can be inserted within the table. For example if only the last row of a table shall be editable and new rows shall be insertable, then:
XWPFTable table = ...;
...
// CTPermStart marking the start of unprotected range
ctPermStart = table.getCTTbl().addNewPermStart();
ctPermStart.setEdGrp(STEdGrp.EVERYONE);
ctPermStart.setId("789012"); //note the Id
XWPFTableRow row = table.createRow();
// CTPerm marking the end of unprotected range
table.getCTTbl().addNewPermEnd().setId("789012"); //note the same Id
...
Complete example:
import java.io.*;
import org.apache.poi.wp.usermodel.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPermStart;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STEdGrp;
public class CreateWordPartialProtected {
public static void main(String[] args) throws Exception {
XWPFDocument document= new XWPFDocument();
// create header
XWPFHeader header = document.createHeader(HeaderFooterType.DEFAULT);
XWPFParagraph paragraph = header.createParagraph();
paragraph.setAlignment(ParagraphAlignment.LEFT);
XWPFRun run = paragraph.createRun();
run.setText("The page header:");
// create footer
XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);
paragraph = footer.createParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
run = paragraph.createRun();
run.setText("Page ");
paragraph.getCTP().addNewFldSimple().setInstr("PAGE \\* MERGEFORMAT");
run = paragraph.createRun();
run.setText(" of ");
paragraph.getCTP().addNewFldSimple().setInstr("NUMPAGES \\* MERGEFORMAT");
// the body content
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("This body part is protected.");
paragraph = document.createParagraph();
// CTPermStart marking the start of unprotected range
CTPermStart ctPermStart = document.getDocument().getBody().addNewPermStart();
ctPermStart.setEdGrp(STEdGrp.EVERYONE);
ctPermStart.setId("123456"); //note the Id
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("This body part is not protected.");
// CTPerm marking the end of unprotected range
document.getDocument().getBody().addNewPermEnd().setId("123456"); //note the same Id
paragraph = document.createParagraph();
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("This body part is protected again.");
paragraph = document.createParagraph();
XWPFTable table = document.createTable(1, 3);
table.setWidth("100%");
table.getRow(0).getCell(0).setText("Column 1");
table.getRow(0).getCell(1).setText("Column 2");
table.getRow(0).getCell(2).setText("Column 3");
// CTPermStart marking the start of unprotected range
ctPermStart = table.getCTTbl().addNewPermStart();
ctPermStart.setEdGrp(STEdGrp.EVERYONE);
ctPermStart.setId("789012"); //note the Id
XWPFTableRow row = table.createRow();
// CTPerm marking the end of unprotected range
table.getCTTbl().addNewPermEnd().setId("789012"); //note the same Id
paragraph = document.createParagraph();
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("This body part is protected again.");
paragraph = document.createParagraph();
document.enforceReadonlyProtection("passwd", org.apache.poi.poifs.crypt.HashAlgorithm.sha1); //enforce readonly protection
FileOutputStream out = new FileOutputStream("CreateWordPartialProtected.docx");
document.write(out);
out.close();
document.close();
}
}
This code is tested and works using apache poi 5.2.2
. It produces a Word document having two editable regions. The second is in a table after the title row. So that title row is protected. The last row is in that editable region. So this row is editable and new rows can be inserted above and below that row. All this tested in Microsoft Word 2017
and Microsoft Word 365
. Other text-processing applications, which are able to handle *.docx
files, might not respect editable regions.