java编程公式,java 数学公式解析
作者:吴石
链接:https://www.jianshu.com/p/ea7f62e3b23a
该公司生产教育产品。当我们遇到数学公式时,通常会使用Latex公式进行存储和渲染。
在我的一个项目中,我遇到了将问题内容从Office 文档(Word 或Excel)导入数据库的要求。问题内容可能包含数学公式,文档编辑者希望使用Office Math Plugin。写出表达式元素。
事实上,该公司之前的产品都是使用.net来实现这个功能的,但是现在他们已经完全转向Java,他们还需要开发一个Java友好的解决方案。
Office文档的公式编辑器
数学类型插件
mathtype 是一个第三方数学插件,可以在Office 文档中进行编辑并生成包含数学矢量图的OL 对象以插入到文档中。
最初的.net解决方案是使用这种方法,并使用mathtype提供的C#库包来解析ole对象并提取LaTeX表达式。
然而,这在纯Java环境中是无法完成的。
Office 附带方程式编辑器
从2007 版本开始,Office 还附带了公式编辑器。
2007版本的Word和Excel之间的区别在于,前者插入的公式对象是Office MathML节点,而后者插入的公式对象仍然是OLE。
从2010 版本开始,这两个产品中的公式编辑器都会插入Office MathML 节点,但它们以不同方式处理公式对象中的默认文本编码。
这些差异揭示了许多不一致之处,即使在同一Office 产品中也是如此。
公式
乳胶
LaTeX 是一个基于X 的排版系统,非常适合制作高打印质量的科学和数学文档。
例如,毕达哥拉斯定理用LaTeX 表达。
a^{2}+b^{2}=c^{2}常用的LaTeX渲染组件是MathJax。
由于项目使用LaTeX,我们将研究如何将Office数学对象转换为LaTeX公式。
数学
它的正式名称是数学标记语言,是一种基于XML 的标准,用于在Internet 上描述数学符号和公式。
例如,这样的表达式:
n p - 1==1 ( mod p )Office MathML (OMML)
在Office 2007及更高版本中编辑的公式对象是OMML。 OMML 是Office 开发的一种数学标记语言,用于与Office Open Xml 配合使用。
例如:
2 变换关系
项目中使用的三者之间的转换关系为:OMML - MathML - LaTex
Office在安装目录中提供了一个xsl工具用于将OMML转换为MathML:MML2OMML.XSL
要将MathML 转换为LaTex,请使用mmltex.xsl,这是另一个在线找到的xsl 工具。
Java分析Office文档
2007 及更早版本
使用过Office一段时间的同学都知道,Office文档有两种类型:Word和WordX,分别对应2007年之前和2007年之后的版本格式。
2007年之前版本使用的Office文档是二进制文件。在以后的版本中,x表示xml,表明新版本的Office文档使用Office Open Xml规范来定义文件格式。
将wordx 文件的扩展名更改为zip 通常允许您解压缩Word 文档中包含的所有内容。
兴趣点
如果您是使用Java 的信息系统的学生,您可能遇到过用于生成Excel 统计文档和分析导入到Excel 的数据的函数。目前最常用的开发库是Apache POI。
POI支持二进制文档和Office Open XML文档,可以满足大多数Office文档解析需求。
分析公式示例
首先,我需要解释一下功能限制。 Word 和Excel 仅适用于从Office 2010 开始的Office Open Xml 文档。其中,Excel公式字符必须转换为常规字符,否则会显示Java无法识别的字符。
我们以Excel文档为例来说明分析过程。
实现功能的思路
这个函数的重点是如何获取Office文档中的数学节点(OMML),获取OMML后,可以使用上面提到的两个工具将其转换为LaTeX。
获取OMML
由于我们知道Excel文档是XML,所以我们只需要使用XML解析工具读出OMML节点即可。
首先,使用POI 获取用于操作的XSSFSheet。
String basePath=\'f:\\\';FileInputStream fis=new FileInputStream(basePath + \'math.xlsx\');OPCPackage pack=OPCPackage.open(fis);XSSFWorkbook 工作簿=new XSSFWorkbook(pack);XSSFSheet 工作表=workbook.getSheetAt(0); 插入Excel 文档中的图像、公式和其他元素保存在称为绘图的单独XML 文件中,其中节点记录元素的位置信息。使用POI 获取绘图元素。
XSSFDrawing dr=sheet.getDrawingPatriarch();CTDrawing Drawing=dr.getCTDrawing();CTOneCellAnchor[] oneCells=Drawing.getOneCellAnchorArray(); //每个CTOneCellAnchor的xml中包含的所有图像、公式和其他元素的X坐标、Y坐标、行、列等,但更重要的是图像或表达式的描述节点。 OMML 节点名称为m:oMathPara。这里我们使用dom4j 的xpath 来检索OMML。
CTOneCellAnchor c=oneCells[0];String xml=c.xmlText(); //获取xml字符串//初始化dom4j解析器SAXReader Reader=Reader=new SAXReader(new DocumentFactory());Map map=new HashMap () ; map .put(\'xdr\',\'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\');map.put(\'m\',\'http://schemas.openxmlformats.org/officeDocument/2006/math \ ');reader.getDocumentFactory().setXPathNamespaceURIs(map); //xml命名空间设置documentInputSource source=new InputSource(new StringReader(xml));source.setEncoding(\'utf-8\') ;Document doc=Reader. read(source);Element root=doc.getRootElement();Element e=(Element)root.selectSingleNode(\'//m:oMathPara\'); //使用xpath获取OMML节点String omml=e.asXML (); //转换为xml 将OMML转换为Mathml和LaTeX
成功获取OMML后,您可以使用xsl转换工具获取Mathml和LaTeX。
首先我们来写一下xsl转换工具的方法,这些方法是使用javax.xml.transform工具包实现的。
/** * 描述: xsl转换器
*/public static String xslConvert(String s, String xslpath, URIResolver uriResolver){ TransformerFactory tFac=TransformerFactory.newInstance(); if(uriResolver !=null) tFac.setURIResolver(uriResolver); StreamSource xslSource=new StreamSource(MathmlUtils.class. getResourceAsStream(xslpath)); StringWriter Writer=new StringWriter(); try { Transformer t=tFac.newTransformer(xslSource); Source Source=new StreamSource(new StringReader(s)); 结果结果=new StreamResult(writer); t. transform(source, result); } catch (TransformerException e) { logger.error(e.getMessage(), e); } return Writer.getBuffer().toString();}/** * 描述: mathml 到latx 转换
* @param mml * @return */public static String ConvertMML2Latex(String mml){ mml=mml.substring(mml.indexOf(\' \')+2, mml.length()); //下一个头节点删除xml URIResolver r=new URIResolver(){ //设置xls依赖文件路径@Override public Sourcesolve(String href, String Base) throws TransformerException { InputStream inputStream=MathmlUtils.class.getResourceAsStream(\'/conventer/mml2tex/\ ' + href) ; 返回new StreamSource(inputStream); } }; String Latex=xslConvert(mml, \'/converter/mml2tex/mmltex.xsl\', r); if(latex !=null Latex.length() 1 ){ Latex=Latex.substring(1, Latex.length() - 1); } return Latex;}/** * description: 将Office mathml 转换为mml
* @param xml * @return */public static String ConvertOMML2MML(String xml){ String result=xslConvert(xml, \'/converter/OMML2MML.XSL\', null); return result;} 此时,转换OMML能。转换为Mathml 和LaTeX 表达式:
String mml=ConvertOMML2MML(oml);String Latex=ConvertMML2Latex(mml);一些经验
在实现这个功能的时候,没有太多可以直接参考的资料,所以我就走了弯路,在网上找了很多资料,要么是过时的,要么是半真半假的。
经过与同事的交流,采用不同的想法,查阅大量的API文档,不断尝试,我们才能够完成这个不切实际的功能。
即使您自己的能力还不够,成为优秀团队的一员也会帮助您不断前进。一个人能走多远,最终取决于与他同行的人。
天地劫幽城再临归真4-5攻略:第四章归真4-5八回合图文通关教学[多图],天地劫幽城再临归真4-5怎么样八回合内通
2024-04-15