美好的一天。
我必须在内部使用许多数学公式生成docx或odt文件。 我试图在Apashe POI& amp; ODFtoolkit但我不能。 谷歌没有帮助。 (
任何人都可以帮我解决这个问题吗? (任何一个例子?)
感谢。
答案 0 :(得分:3)
您可以使用docx4j库。以下是Getting started的文档。
我建议您首先创建一个模板文件,包含所有格式,以及尽可能多的结构。然后,您应该将内容控件放在您希望文本移动的位置。内容控件可以包含其他内容,您可以使用这些内容重复一些常见的结构。
在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
文件。
答案 1 :(得分:0)
此外,您可以使用Fmath库生成OOXML代码,然后通过doc4j库将其推送到docx文件。
以下是一些很好的例子。