apache poi xwpfrun isbold未检测到粗体

li9yvcax  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(392)

我有一个doxc文档,它有一些粗体文本。由于某些原因,run.isbold()返回false,尽管run itsel是粗体的。这里可能有什么问题?
我用来读取文件的代码:

XWPFDocument document = new XWPFDocument(fis);
        for(XWPFParagraph paragraphs: document.getParagraphs()){

            for(XWPFRun run: paragraphs.getRuns()){
                System.out.println(run.isBold());

                System.out.println(run.text());
        }

文件内容如下所示:
米õisted公司
2.1. 一些文字
2.1.1. 汇集-一些文本
奇怪的是这个头衔(汉克勒平古)üldtingimused)在文件的开头是粗体的,但是在那之后就没有粗体了。

odopli94

odopli941#

在我检查了你的 test.docx 我可以告诉你:
“文本”üldosa“和”mõ“isted”不是粗体,因为它们的格式是粗体的,而是因为整个段落的样式是“heading2”。文本“pooled”也不是粗体格式,而是应用了特殊的字符样式“paks”。所以有人广泛地使用了词汇风格。一点也不坏。正如html应该使用css样式表而不是直接格式化一样,在word中也应该首选使用样式表。当然,解析时的问题也是一样的。如果不对样式表进行额外的分析,就无法确定文本应该如何呈现。不幸的是 apache poi 直到现在才开始关注款式。
一个人怎么能有这样的洞察力呢?一 *.docx 文件只是一个 ZIP 档案文件。所以我们可以解压它并找到: /word/document.xml :

<w:r ...>
 <w:rPr>
  ...
  <w:b/>
  ...
 </w:rPr>
 <w:t>HANKELEPINGU ÜLDTINGIMUSED</w:t>
</w:r>

这是一个文本运行真正的粗体格式直接。
但是

<w:p ...>
 <w:pPr>
  <w:pStyle w:val="Heading2"/>
  <w:numPr><w:ilvl w:val="0"/><w:numId w:val="2"/></w:numPr> 
  ...
 </w:pPr>
 <w:r ...>
  <w:t>Üldosa</w:t>
 </w:r>
</w:p>

这是一个具有“heading2”样式的段落,并且自动编号。
那么为什么这段文字是粗体的呢?在 /word/styles.xml 我们发现:

<w:style w:type="paragraph" w:styleId="Heading2">
 <w:name w:val="heading 2"/>
 <w:basedOn w:val="Normal"/>
 ...
 <w:link w:val="Heading2Char"/>
 ...
</w:style>

这是链接到字符样式“heading2char”的段落样式“heading2”。

<w:style w:type="character" w:customStyle="1" w:styleId="Heading2Char">
 <w:name w:val="Heading 2 Char"/>
 ...
 <w:link w:val="Heading2"/>
 ...
 <w:rPr>
  ...
  <w:b/>
  ...
 </w:rPr>
</w:style>

这是设置为粗体的字符样式“heading2char”。
回答如何使用 apache poi 必须知道这一点
apache poi XWPF 基于 org.openxmlformats.schemas.wordprocessingml.x2006.main.* 来自 ooxml-schemas.*.jar . 所以我们需要这方面的信息。不幸的是没有 API 公开文件。所以我们需要下载源代码 javadoc 我们自己。
那么接下来该怎么办呢?重复段落和运行。但是每一段都要增加一些内容,以获得这一段的风格。如果有,得到它和它的字符样式,并检查它提供了什么设置。同样,对于每次跑步,尝试获取此跑步的角色样式。如果有,获取它并检查它提供了什么设置。
下面的代码正在执行此操作,但仅用于检查样式是否提供粗体设置。因此,它确实是不完整的,使它完整将是非常昂贵的。

import java.io.FileInputStream;

import org.apache.poi.xwpf.usermodel.*;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

public class ReadWordHavingStyles {

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument(new FileInputStream("test.docx"));

  XWPFStyles styles = document.getStyles();
  XWPFStyle style = null;
  boolean isPBold = false;
  boolean isRBold = false;
  String boldReasonP = "";
  String boldReasonR = "";
  CTRPr cTRPr = null;

  for(XWPFParagraph paragraph : document.getParagraphs()) {
   isPBold = false;
   boldReasonP = "";
   String pStyleId = paragraph.getStyleID();
   if (pStyleId != null) {
    style = styles.getStyle(pStyleId);
    if (style != null) {
     String linkStyleId = style.getLinkStyleID();
     style = styles.getStyle(linkStyleId);
     if (style != null) {
      cTRPr = style.getCTStyle().getRPr();
      if (cTRPr != null) {
       if (!cTRPr.isSetB()) {
        isPBold = false;
       } else {
        STOnOff.Enum val = cTRPr.getB().getVal();
        isPBold = !((STOnOff.FALSE == val) || (STOnOff.X_0 == val) || (STOnOff.OFF == val));
       }
      }
      boldReasonP = " whole P is " + ((isPBold)?"":"not ") + "bold because of style " + linkStyleId;
     }
    }
   }

   if (!isPBold) boldReasonP = " P is not bold";

   for(XWPFRun run : paragraph.getRuns()){
    isRBold = isPBold;
    boldReasonR = "";
    cTRPr = run.getCTR().getRPr();
    if (cTRPr != null) {
     CTString rStyle = cTRPr.getRStyle();
     if (rStyle != null) {
      String rStyleId = rStyle.getVal();
      style = styles.getStyle(rStyleId);
      if (style != null) {
       cTRPr = style.getCTStyle().getRPr();
       if (cTRPr != null) {
        if (!cTRPr.isSetB()) {
         isRBold = false;
        } else {
         STOnOff.Enum val = cTRPr.getB().getVal();
         isRBold = !((STOnOff.FALSE == val) || (STOnOff.X_0 == val) || (STOnOff.OFF == val));
        }      
       }
       boldReasonR = " run is " + ((isRBold)?"":"not ") + "bold because of style " + rStyleId;
      }
     }
    }

    if (!isRBold) boldReasonR = " run is not bold";

    cTRPr = run.getCTR().getRPr();
    if (cTRPr != null) {
     if (cTRPr.isSetB()) {
      STOnOff.Enum val = cTRPr.getB().getVal();
      isRBold = !((STOnOff.FALSE == val) || (STOnOff.X_0 == val) || (STOnOff.OFF == val));
      boldReasonR = " run is " + ((isRBold)?"":"not ") + "bold because of direct formatting";
     }      
    }

    System.out.println(run.text() + " isBold:" + isRBold + ":" + boldReasonP + boldReasonR);

   }
  }

  document.close();
 }
}

相关问题