本人找到俩原因...
一是docx文档中段落的样式可能来自四个地方
- 段落内嵌样式(样式写在document.xml中)
- 段落继承样式(样式写在styles.xml中,根据styleId区分,styles.xml中的样式也可以继承其他样式)
- 段落默认样式(当段落中没有内嵌样式和继承样式,就在styles.xml中找<w:name w:val="Normal"的样式
- 文档默认样式(前面都找不到,在这找)
获取不全就会为null,下面给出获取样式代码(以获取字号为例)
public int getFontSize(XWPFDocument doc,XWPFParagraph xwpfParagraph,XWPFRun run) throws Exception {
if ((run.getCTR()!= null && run.getCTR().getRPr()!=null && run.getCTR().getRPr().getSzArray().length>0 &&run.getCTR().getRPr().getSzArray(0)!=null) ){
return Integer.parseInt(run.getCTR().getRPr().getSzArray(0).getVal().toString())/2;
}else {
if (xwpfParagraph.getStyle() != null) {
String StyleId = xwpfParagraph.getStyle();
while (true){
CTRPr rPr = doc.getStyles().getStyle(StyleId).getCTStyle().getRPr();
if ((rPr!=null&& rPr.getSzArray().length>0 && rPr.getSzArray(0)!=null)){
return Integer.parseInt( rPr.getSzArray(0).getVal().toString())/2;
}
XWPFStyle baseOnStyle = this.getBaseOnStyle(StyleId,doc);
if (baseOnStyle==null){
break;
}
StyleId = this.getBaseOnStyle(StyleId,doc).getStyleId();
}
}
if (doc.getStyles().getStyleWithName("Normal").getCTStyle().getRPr()!=null){
CTRPr normal = doc.getStyles().getStyleWithName("Normal").getCTStyle().getRPr();
return normal.getSzArray(0) != null? Integer.parseInt(normal.getSzArray(0).getVal().toString())/2: Integer.parseInt(doc.getStyle().getDocDefaults().getRPrDefault().getRPr().getSzArray(0).getVal().toString())/2;
}
}
return Integer.parseInt(doc.getStyle().getDocDefaults().getRPrDefault().getRPr().getSzArray(0).getVal().toString())/2;
}
/***
* 获取样式 基于的 样式id
* @param StyleId
* @param doc
* @return
*/
public XWPFStyle getBaseOnStyle(String StyleId, XWPFDocument doc){
if (doc.getStyles().getStyle(StyleId)!=null&&doc.getStyles().getStyle(StyleId).getCTStyle()!=null&&doc.getStyles().getStyle(StyleId).getCTStyle().getBasedOn()!=null){
return doc.getStyles().getStyle(doc.getStyles().getStyle(StyleId).getCTStyle().getBasedOn().getVal());
}
return null;
}
第二个原因是段落中有特殊的符号,如下图,虽然长得像换行,但其实不是,比如下图中的符号就是防止在文档排版中出现孤行或孤行的符号,可以没有样式,所以也会获取样式不全..
遇到这些符号,我的做法是直接忽略(感觉忽略掉问题应该不大..)