如何使用Apache POI Word中的文本添加内嵌多个方程式?
问题描述:
我使用Apache POI将文本与乳胶风格方程转换为MS word文档。在一些帮助下,我能够成功实现它,但是如果该行有多个等式,那么它会产生不正确的结果。如何使用Apache POI Word中的文本添加内嵌多个方程式?
下面是我的代码:
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 javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import uk.ac.ed.ph.snuggletex.SnuggleInput;
import uk.ac.ed.ph.snuggletex.SnuggleEngine;
import uk.ac.ed.ph.snuggletex.SnuggleSession;
import java.io.IOException;
public class CreateWordFormulaFromMathML {
static File stylesheet = new File("MML2OMML.XSL");
static TransformerFactory tFactory = TransformerFactory.newInstance();
static StreamSource stylesource = new StreamSource(stylesheet);
static CTOMath getOMML(String mathML) throws Exception {
Transformer transformer = tFactory.newTransformer(stylesource);
StringReader stringreader = new StringReader(mathML);
StreamSource source = new StreamSource(stringreader);
StringWriter stringwriter = new StringWriter();
StreamResult result = new StreamResult(stringwriter);
transformer.transform(source, result);
String ooML = stringwriter.toString();
stringwriter.close();
CTOMath ctOMath = CTOMath.Factory.parse(ooML);
return ctOMath.getOMathArray(0);
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
String mstr = "The expression is as: $ax^2 + bx = c$ is easier to understand than $$ax^2 + \\frac{\\sin^{-1}\\theta}{\\cot{-1}} \\times y_1$$ or anything in \\[ ay^2 + b_2 \\theta\\]";
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
// run.setText("");
SnuggleEngine engine = new SnuggleEngine();
SnuggleSession session = engine.createSession();
SnuggleInput input = new SnuggleInput(mstr);
session.parseInput(input);
String mathML = session.buildXMLString();
System.out.println("Input " + input.getString() + " was converted to:\n" + mathML + "\n\n");
for(String s : mathML.split("\\s+(?=<math)|(?<=</math>)\\s+")){
if (s.startsWith("<math"))
{
CTOMath ctOMath = getOMML(s);
System.out.println(s);
CTP ctp = paragraph.getCTP();
ctp.setOMathArray(new CTOMath[]{ctOMath});
}
else
{
run.setText(s + " ");
System.out.println(s);
}
}
document.write(new FileOutputStream("CreateWordFormulaFromMathML.docx"));
document.close();
}
}
这种生产与
表达的文件是:比较容易理解比或在y^2 + B_2 \ THETA
注意什么:(ay^2 + b_2 \ theta)在字方程格式中是正确的。
我需要的是内联多行方程的文本。
答
如何解决创建Office OpenXML
文件如*.docx
的解决任务?
Office OpenXML
档案如*.docx
siply ZIP
档案。我们可以将它们解压缩并查看内部。在*.docx
中,我们找到/word/document.xml
,在那里我们找到描述文档结构的XML
。具有式直列段落中,我们发现这样的:
<w:p>
<w:r>
<w:t>text</w:t>
</w:r>
<m:oMath>... </m:oMath>
<w:r>
<w:t>text</w:t>
</w:r>
<m:oMath>... </m:oMath>
...
</w:p>
所以我们需要多次运行持文本和他们之间的多个。
这就是为什么段落有OMathArray
CTOMath[]
。并且您的代码覆盖此阵列有一个新的阵列一个CTOMath
每个时间一个额外的CTOMath
被发现。相反,需要将另外的CTOMath
添加到阵列中,每次找到附加的CTOMath
。
要知道我们可以用org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP
段落做什么,我们需要一个文档。我发现的最好的是grepcode.com。在那里我们找到CTP.addNewOMath()和CTP.setOMathArray(int, CTOMath)。
因此改变你的代码,如:
for(String s : mathML.split("\\s+(?=<math)|(?<=</math>)\\s+")){
if (s.startsWith("<math")) {
CTOMath ctOMath = getOMML(s);
System.out.println(s);
CTP ctp = paragraph.getCTP();
ctp.addNewOMath();
ctp.setOMathArray(ctp.sizeOfOMathArray()-1, ctOMath);
}
else {
run = paragraph.createRun();
run.setText(s + " ");
System.out.println(s);
}
}
应该工作。
它工作得很好!谢谢! –