I was using STOnOff.X_0 Enum to set value as 0(i.e false) for some elements in Apache POI 3.14 when constructing docx file. But now currently in latest version 5.2.2, I could this class has been changed & also new class named as STOnOff1 is being introduced with On & Off enums. Based on below stackoverflow thread I could see that it is suggested to use true or false.
Why is STOnOff class removed & an another class like STOnOff1 is introduced without having STOnOff1.X_0 & STOnOff1.X_1 enums but just STOnOff1.OFF & STOnOff1.ON ? Can I use STTrueFalse.True/STTrueFalse.False in place of just boolean true/false ? Any detailed clarification/solution reg these changes will be really helpful.
Concrete Examples:
1)For setEqualWidth(STOnOff value) of Section's column Layout, we could see that previously in POI 3.14 we need to set STOnOff value as STOnOff.X_1, etc.. But in Apache POI 5.2.2 it is now accepting any Object value, so can we set STTrueFalse.True/boolean true (or) false instead of STOnOff.X_1 in setEqualWidth() API now ?
Also could see that any CT API's like setEqualWidth(STOnOff value) which previously accepted STOnOff.Enum values had now changed to accept Object param for which can we pass STTrueFalse.True/STTrueFalse.False instead of plain boolean true(or) false ?
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STOnOff;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTrueFalse;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
public class STOnOffValuesTesting {
public static void main(String[] args) {
try {
byte[] docbytes = FileUtil.read("anysimpleDocxFile.docx"); //No i18n
InputStream documentStream = GeneralUtils.getStreamFromArray( docbytes );
XWPFDocument document = new XWPFDocument( documentStream );
List<CTSectPr> documentSections = document.docSections;
int length = documentSections.size();
for(int i=0; i <length; i ){
CTSectPr sectPr = documentSections.get(i);
//In Apache POI 3.14
sectPr.getCols().setEqualWidth(STOnOff.X_1);
//But in Apache POI 5.2.2
sectPr.getCols().setEqualWidth(true);
sectPr.getCols().setEqualWidth(STTrueFalse.TRUE); //Is this correct ?
}
}catch(Exception e) {
System.out.println(e)
}
}
}```
CodePudding user response:
When using the low level Office Open XML
-schemas classes, a programmer needs to know in detail what those classes are doing. That's the aim of apache poi
: To provide a high level layer to use those low level classes.
Where are the Office Open XML
-schemas classes coming from?
Those classes are generated form XSD
files which are published in ECMA-376. They are contained in download part 4. The XSD
s contain definitions for the XML
which gets used in Office Open XML
. XMLBeans from Apache provides methods to auto-generate Java
classes from this XSD
s. So the low-level low level Office Open XML
-schemas classes of ooxml-schemas
or poi-ooxml-lite
or poi-ooxml-full
do fully translate the given XSD
definitions to Java
.
So the general answer to your question about the reason of changes in this Office Open XML
-schemas classes is that the published XSD
s have changed from 1st edition in 2006 up to 4th edition in 2012. Or the used XMLBeans
version has changed and does the XSD
- Java
- translation a little bit different.
STOnOff
versus STTrueFalse
The XML
type ST_OnOff
was defined in 1st edition of wml.xsd
as an enumeration of "true", "false", "on", "off", "1", "0". Now in 4th edition it is defined in shared-commonSimpleTypes.xsd
as xsd:boolean and ST_OnOff1
, where ST_OnOff1
is an enumeration of "on", "off". This is probably done because xsd:boolean
contains "true", "false", "1", "0" already. So it can replace the former used enumeration.
The The XML
type ST_TrueFalse
was defined in 1th edition of vml-main.xsd
as an enumeration of "t", "f", "true", "false". Now in 4th edition it is defined in shared-commonSimpleTypes.xsd
also as an enumeration of "t", "f", "true", "false". But it only gets used in VML
.
So STTrueFalse
and STOnOff
are not the same. The one cannot be used in place of the other. Whether the one or the other needs to be used is determined by the context. It is defined by XML
types which use either the ST_TrueFalse
or the ST_OnOff
type. For example the type CT_OnOff
in wordprocessing which uses ST_OnOff
or multiple VML
types which use ST_TrueFalse
.
In terms of Java
and CTSectPr
- CTColumns.setEqualWidth
one can simply test this using following code using apache poi 5.2.2
:
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColumns;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTrueFalse;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STOnOff1;
class STOnOffValuesTesting {
public static void main(String[] args) throws Exception {
CTSectPr sectPr = CTSectPr.Factory.newInstance();
CTColumns cols = sectPr.addNewCols();
cols.setEqualWidth(true); //cols.setEqualWidth(false); // works and gets used by Apache POI by default
System.out.println(sectPr);
cols.setEqualWidth("1"); //cols.setEqualWidth("0"); // works and gets used by Microsoft by default
System.out.println(sectPr);
cols.setEqualWidth(STOnOff1.ON); //cols.setEqualWidth(STOnOff1.OFF); // works but never gets used by Microsoft instead of boolean
System.out.println(sectPr);
//cols.setEqualWidth(STTrueFalse.TRUE); //cols.setEqualWidth(STTrueFalse.FALSE); // will not work as STTrueFalse only gets used in VML
}
}
The cols.setEqualWidth(STTrueFalse.TRUE)
throws an exception. The cols.setEqualWidth(STOnOff1.ON)
works per definition. But I would not use this because Microsoft Word itself never uses "on"/"off" in this context.