使用Apache POI读取Word(docx)中带上下文的MathML公式问题求助
问题根因&解决方案
- 转换XSL文件用反了
你现在用的MML2OMML.XSL是负责把MathML转换为Office内置OMML公式格式的,你的需求是把OMML转成MathML,必须使用OMML2MML.XSL文件,文件用反会直接导致转换无输出。
- 转换XSL文件用反了
- 依赖不全
Apache POI默认自带的poi-ooxml-schemas是精简包,缺少CTOMath相关的完整类定义,需要补充完整的ooxml依赖:
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-full</artifactId> <version>5.0.0</version> </dependency>- 依赖不全
- 公式节点提取逻辑遗漏
遍历文档段落时不能只提取普通文本Run节点,需要主动从段落的CTP对象中提取公式节点,参考提取逻辑:
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; import org.openxmlformats.schemas.officeDocument.x2006.math.CTOMath; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.FileInputStream; import java.io.StringWriter; import java.util.List; import java.util.stream.Collectors; public class DocxMathReader { public static void main(String[] args) throws Exception { XWPFDocument doc = new XWPFDocument(new FileInputStream("test.docx")); // 加载正确的OMML2MML转换文件 TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource("path/to/OMML2MML.xsl")); for (XWPFParagraph para : doc.getParagraphs()) { CTP ctp = para.getCTP(); // 提取行内公式 List<CTOMath> omathList = ctp.getOMathList(); for (CTOMath math : omathList) { StringWriter writer = new StringWriter(); transformer.transform(new DOMSource(math.getDomNode()), new StreamResult(writer)); System.out.println("公式MathML:" + writer); } // 提取块级公式 List<CTOMath> paraMathList = ctp.getOMathParaList().stream() .flatMap(p -> p.getOMathList().stream()) .collect(Collectors.toList()); for (CTOMath math : paraMathList) { StringWriter writer = new StringWriter(); transformer.transform(new DOMSource(math.getDomNode()), new StreamResult(writer)); System.out.println("块级公式MathML:" + writer); } } doc.close(); } }- 公式节点提取逻辑遗漏
- 转换参数校验
确认使用的OMML2MML.XSL文件支持OMML命名空间http://schemas.openxmlformats.org/officeDocument/2006/math,命名空间不匹配会导致XSLT无法匹配节点,输出为空。
- 转换参数校验
内容的提问来源于stack exchange,提问作者Nikhil Cherian
相关产品推荐
相关产品推荐

