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