当前位置: 首页 > 知识库问答 >
问题:

阅读方程式

林俊英
2023-03-14

我想读取word/docx文件的数据并保存到我的数据库中,需要时我可以从数据库中获取数据并在我的html页面上显示我使用ApachePOI读取docx文件中的数据,但它无法获取公式,请帮助我!

共有2个答案

胥宏义
2023-03-14

添加到@Axel Richter答案中,我发现很难找到所需的依赖集

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>

对于Office2019,我想他们不提供OMML2MML。XSL下面是它的链接https://github.com/Versal/word2markdown/blob/master/libs/omml2mml.xsl

赏逸春
2023-03-14

Word*。docx文件是包含XML文件的ZIP归档文件,这些文件是Office Open XML。包含在Word中的公式。docx文档是Office MathML(OMML)。

不幸的是,这种XML格式在microsoftoffice之外并不广为人知。因此,它不能直接用于HTML。但幸运的是,它是XML,因此可以使用XSLT转换XML数据。因此,我们可以将OMML转换为MathML,例如,它可以在更广泛的用例领域中使用。

通过XSLT的转换过程主要基于转换的XSL定义。不幸的是,创建这样一个系统也不是很容易。但幸运的是Microsoft已经这样做了,如果您安装了当前的Microsoft Office,您可以找到这个文件OMML2MML。%ProgramFiles%\中的Microsoft Office程序目录中的XSL。如果你没有找到它,做一个网络调查得到它。

因此,如果我们知道这一切,我们可以从XWPFDocument获取OMML,将其转换为MathML,然后将其保存以供以后使用。

我的示例将找到的公式存储为字符串的ArrayList中的MathML。您还应该能够在数据库中存储这些字符串。

该示例需要完整的ooxml-schemas-1.3。jar如中所述https://poi.apache.org/faq.html#faq-N10025。这是因为它使用的是CTOMath,而不是较小的poi ooxml模式jar

Word文档:

Java代码:

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

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.officeDocument.x2006.math.CTOMath;
import org.openxmlformats.schemas.officeDocument.x2006.math.CTOMathPara;

import org.w3c.dom.Node;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

import java.awt.Desktop;

import java.util.List;
import java.util.ArrayList;

/*
needs the full ooxml-schemas-1.3.jar as mentioned in https://poi.apache.org/faq.html#faq-N10025
*/

public class WordReadFormulas {

 static File stylesheet = new File("OMML2MML.XSL");
 static TransformerFactory tFactory = TransformerFactory.newInstance();
 static StreamSource stylesource = new StreamSource(stylesheet); 

 static String getMathML(CTOMath ctomath) throws Exception {
  Transformer transformer = tFactory.newTransformer(stylesource);

  Node node = ctomath.getDomNode();

  DOMSource source = new DOMSource(node);
  StringWriter stringwriter = new StringWriter();
  StreamResult result = new StreamResult(stringwriter);
  transformer.setOutputProperty("omit-xml-declaration", "yes");
  transformer.transform(source, result);

  String mathML = stringwriter.toString();
  stringwriter.close();

  //The native OMML2MML.XSL transforms OMML into MathML as XML having special name spaces.
  //We don't need this since we want using the MathML in HTML, not in XML.
  //So ideally we should changing the OMML2MML.XSL to not do so.
  //But to take this example as simple as possible, we are using replace to get rid of the XML specialities.
  mathML = mathML.replaceAll("xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"", "");
  mathML = mathML.replaceAll("xmlns:mml", "xmlns");
  mathML = mathML.replaceAll("mml:", "");

  return mathML;
 }

 public static void main(String[] args) throws Exception {
    
  XWPFDocument document = new XWPFDocument(new FileInputStream("Formula.docx"));

  //storing the found MathML in a AllayList of strings
  List<String> mathMLList = new ArrayList<String>();

  //getting the formulas out of all body elements
  for (IBodyElement ibodyelement : document.getBodyElements()) {
   if (ibodyelement.getElementType().equals(BodyElementType.PARAGRAPH)) {
    XWPFParagraph paragraph = (XWPFParagraph)ibodyelement;
    for (CTOMath ctomath : paragraph.getCTP().getOMathList()) {
     mathMLList.add(getMathML(ctomath));
    }
    for (CTOMathPara ctomathpara : paragraph.getCTP().getOMathParaList()) {
     for (CTOMath ctomath : ctomathpara.getOMathList()) {
      mathMLList.add(getMathML(ctomath));
     }
    }
   } else if (ibodyelement.getElementType().equals(BodyElementType.TABLE)) {
    XWPFTable table = (XWPFTable)ibodyelement; 
    for (XWPFTableRow row : table.getRows()) {
     for (XWPFTableCell cell : row.getTableCells()) {
      for (XWPFParagraph paragraph : cell.getParagraphs()) {
       for (CTOMath ctomath : paragraph.getCTP().getOMathList()) {
        mathMLList.add(getMathML(ctomath));
       }
       for (CTOMathPara ctomathpara : paragraph.getCTP().getOMathParaList()) {
        for (CTOMath ctomath : ctomathpara.getOMathList()) {
         mathMLList.add(getMathML(ctomath));
        }
       }
      }
     }
    }
   }
  }

  document.close();

  //creating a sample HTML file 
  String encoding = "UTF-8";
  FileOutputStream fos = new FileOutputStream("result.html");
  OutputStreamWriter writer = new OutputStreamWriter(fos, encoding);
  writer.write("<!DOCTYPE html>\n");
  writer.write("<html lang=\"en\">");
  writer.write("<head>");
  writer.write("<meta charset=\"utf-8\"/>");

  //using MathJax for helping all browsers to interpret MathML
  writer.write("<script type=\"text/javascript\"");
  writer.write(" async src=\"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=MML_CHTML\"");
  writer.write(">");
  writer.write("</script>");

  writer.write("</head>");
  writer.write("<body>");
  writer.write("<p>Following formulas was found in Word document: </p>");

  int i = 1;
  for (String mathML : mathMLList) {
   writer.write("<p>Formula" + i++ + ":</p>");
   writer.write(mathML);
   writer.write("<p/>");
  }

  writer.write("</body>");
  writer.write("</html>");
  writer.close();

  Desktop.getDesktop().browse(new File("result.html").toURI());

 }
}

结果:

刚刚使用ApachePOI5.0.0对这段代码进行了测试,它运行正常。您需要poi-ooxml-full-5.0.0。jar用于apache poi 5.0.0。请阅读https://poi.apache.org/help/faq.html#faq-N10025 for whatooxml库对于whatapache poi版本是必需的。

 类似资料:
  • 我是新来的,我正在学习使用方法等等,我在方法中有我的代码,但在代码中有一个控制台。ReadLine();这是我不想要的。基本上,我需要做的是一个包含10个方法的大作业,作为输入,你必须调用哪个方法,然后调用实际的输入,但是当我的方法中有一个readline时,我必须给出3个,而不是2个。如果有人知道如何帮助noob,我的代码如下 基本上是int.parse(consolereadline);我需要

  • 我有以下类,它从/到包裹读取和写入对象数组: 在上面的代码中,我在读取< code>readParcelableArray时得到一个< code>ClassCastException: 错误/AndroidRuntime(5880):原因:Java . lang . classcastexception:[land roid . OS . parcelable; 上面的代码有什么错误?在编写对象数

  • 从BigQuery读取和过滤数据,我有两种方法 > 从 Dataflow 中的 BigQuery 读取(使用 BigqueryIO.readTableRow.from(ValueProvider)))整个数据,然后根据条件(如最大日期)进行筛选 使用NestedValueProvider通过生成仅获取所需数据的查询从数据流中的BigQuery读取要慢得多。 因为如果我读取整个数据并且我的表处于追加

  • 在问题[1]中,我了解到如果您想在Android下使用NFC标签,则不必采用NDEF格式。我想在Win 8.1 in. Net下执行此操作。我的情况是这样的: 我有一个RFID卡Mifare Classic 1K,其中存储了一个ID。(由制造商记录)该ID由我们的考勤系统通过通常的RFID读取器(例如Gigatek的PROMAG MFR120)读取。我们不在卡上写任何东西,我们只需要读取ID。但是

  • 我正在创建一个应用程序,在其中我想阅读所有电子邮件并希望在列表视图中显示。我一直在寻找,但找不到任何合适的方法。我试过下面的代码: 但它返回电子邮件地址,如果我想阅读实际的电子邮件怎么办?有什么办法吗?Android API会公开这一点吗?还有一件事,在下面的一个地方我发现了获取电子邮件的方法 但游标返回 null。我相信没有办法从Android设备读取电子邮件。可能是电子邮件被保存在该应用程序(

  • 问题内容: 背景 开发一个简单的Web应用程序(Eclipse + JBoss + Apache Tomcat)以生成XML文件。 问题 “业务区域”列表针对数据库查询,而“列集群”列表使用所选的“业务区域”项目查询数据库。这两个都是存储外部文本文件的唯一查询。 这些文件当前存储在以下位置: WebContent / META-INF / business-areas.sql WebContent