再会。
我必须生成包含许多数学公式的 docx 或 odt 文件。我尝试在 Apashe POI 和 ODFtoolkit 中找到解决方案,但我无法做到。谷歌没有帮助。(
可能有人可以帮助我解决此任务吗?(有什么例子吗?)
谢谢。
我建议您首先创建一个模板文件,其中包含所有格式和尽可能多的结构。然后你应该把内容控件放在你想要你的文本去的地方。内容控件可以包含其他内容,您可以使用这些内容来重复某些常见结构。
在 Word 中,可以在主功能区的“开发人员”选项卡中找到“内容控件”。它们被命名为富文本内容控件和纯文本内容控件。不过,您可能需要先启用开发人员选项卡。在选项中,在自定义功能区下,选中开发人员。
要更改内容控件的标记,请在页面上单击其句柄以将其选中,然后按功能区上的控件属性按钮。然后,您将看到一个对话框,您可以在其中设置标题和标签。
在 Java 中,内容控件将在对象模型中表示为SdtBlock
或SdtRun
。处理模板时,应将其替换为所需的内容。
该org.docx4j.math
包包含用于创建数学公式的类。
这是一个例子:
import java.*;
import java.io.*;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.namespace.*;
import org.docx4j.wml.*;
import org.docx4j.math.*;
import org.docx4j.openpackaging.packages.*;
import org.docx4j.openpackaging.parts.WordprocessingML.*;
public class Processor
{
public static void main(String[] args) throws Exception
{
File inFile = new File(args[0]);
File outFile = new File(args[1]);
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(inFile);
MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();
Processor processor = new Processor();
processor.processContent(mdp.getContent());
wordMLPackage.save(outFile);
}
private Stack<String> tags = new Stack<String>();
private void pushTag(String tag)
{
tags.push(tag);
}
private String getTag()
{
return tags.peek();
}
private void popTag()
{
tags.pop();
}
private static final org.docx4j.wml.ObjectFactory wmlFactory = new org.docx4j.wml.ObjectFactory();
private static final org.docx4j.math.ObjectFactory mathFactory = new org.docx4j.math.ObjectFactory();
public void processContent(List<Object> content)
{
for (Object child : content)
{
if (child instanceof SdtBlock)
{
processBlock((SdtBlock) child);
}
else if (child instanceof P)
{
processP((P) child);
}
else if (child instanceof JAXBElement)
{
JAXBElement<?> elem = (JAXBElement<?>) child;
Class<?> elemType = elem.getDeclaredType();
if (elemType.equals(CTOMath.class))
{
processOMath((CTOMath) elem.getValue());
}
}
}
}
public void processP(P p)
{
processContent(p.getContent());
}
public void processBlock(SdtBlock block)
{
String tag = block.getSdtPr().getTag().getVal();
pushTag(tag);
processContent(block.getSdtContent().getContent());
popTag();
}
public void processOMath(CTOMath oMath)
{
String tag = getTag(); // tag of innermost <w:sdt>
if (getTag().equals("MyEquation"))
{
List<Object> content = oMath.getEGOMathElements();
content.clear();
content.add(makeRun("A=\u03c0"));
content.add(makeSSup(makeRun("r"), makeRun("2")));
}
}
private JAXBElement<CTR> makeRun(String text)
{
// <m:r>
CTR run = mathFactory.createCTR();
List<Object> content = run.getContent();
// <w:rPr><w:rFonts>
RPr pr = wmlFactory.createRPr();
RFonts rFonts = wmlFactory.createRFonts();
rFonts.setAscii("Cambria Math");
rFonts.setHAnsi("Cambria Math");
pr.setRFonts(rFonts);
content.add(wmlFactory.createSdtPrRPr(pr));
// <m:t>
CTText ctText = mathFactory.createCTText();
ctText.setValue(text);
content.add(mathFactory.createCTRTMath(ctText));
return mathFactory.createCTOMathArgR(run);
}
private JAXBElement<CTSSup> makeSSup(Object expr, Object exp)
{
// <m:ssup>
CTSSup ssup = mathFactory.createCTSSup();
// <m:e>
CTOMathArg eArg = mathFactory.createCTOMathArg();
eArg.getEGOMathElements().add(expr);
ssup.setE(eArg);
// <m:sup>
CTOMathArg supArg = mathFactory.createCTOMathArg();
supArg.getEGOMathElements().add(exp);
ssup.setSup(supArg);
return mathFactory.createCTOMathArgSSup(ssup);
}
}
它将查找名为“MyEquation”的块级内容控件,并将其中的数学表达式替换为.A=πr2
具体来说,它将寻找
<w:sdt>
<w:sdtPr>
<w:tag w:val="MyEquation"/>
</w:sdtPr>
<w:sdtContent>
<w:p>
<m:oMath>
</m:oMath>
</w:p>
</w:sdtContent>
</w:sdt>
并将其替换为
<w:p>
<m:oMath>
<m:r>
<w:rPr>
<w:rFonts w:ascii="Cambria Math" w:hAnsi="Cambria Math"/>
</w:rPr>
<m:t>A=π</m:t>
</m:r>
<m:sSup>
<m:sSupPr>
<m:ctrlPr>
<w:rPr>
<w:rFonts w:ascii="Cambria Math" w:hAnsi="Cambria Math"/>
</w:rPr>
</m:ctrlPr>
</m:sSupPr>
<m:e>
<m:r>
<w:rPr>
<w:rFonts w:ascii="Cambria Math" w:hAnsi="Cambria Math"/>
</w:rPr>
<m:t>r</m:t>
</m:r>
</m:e>
<m:sup>
<m:r>
<w:rPr>
<w:rFonts w:ascii="Cambria Math" w:hAnsi="Cambria Math"/>
</w:rPr>
<m:t>2</m:t>
</m:r>
</m:sup>
</m:sSup>
</m:oMath>
</w:p>
您可以在 Word 中制作方程式,然后查看 docx 文件。它们以 zip 文件的形式存储,其中包含大量 XML。具体来说,您要查看word/document.xml
文件。
您也可以使用 Fmath 库生成 OOXML 代码,然后通过 doc4j 库将其推送到 docx 文件。
这里有一些很好的例子。