我有一个 doxc 文档,其中有一些粗体文本。由于某种原因,尽管运行本身以粗体显示,但 run.isBold() 返回 false。这里可能存在什么问题?
我用来读取文件的代码:
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());
}
文件内容如下所示:
莫斯特
2.1。一些文字
2.1.1。 合并 - 一些文字
奇怪的是,文件开头的标题(HANKELEPINGU ÜLDTINGIMUSED)是粗体的,但之后就没有任何粗体了。
最佳答案
在检查了您的 test.docx
文件后,我可以告诉您以下内容:
文本“Üldosa”和“Mõisted”不是粗体,因为它们的格式是粗体,而是因为整个段落的样式为“Heading2”。并且文本“Pooled”也没有采用粗体格式,而是应用了特殊的字符样式“Paks”。所以有人用过Word Styles广泛地。一点也不差。正如 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();
}
}
关于java - Apache POI XWPFRun isBold 未检测到粗体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54516225/