如何从Java使用数学公式生成docx/odt文件 [英] How generate docx/odt file with math formulas from java

查看:104
本文介绍了如何从Java使用数学公式生成docx/odt文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天.

我必须生成带有许多数学公式的docx或odt文件. 我尝试在Apashe POI&中找到解决方案ODFtoolkit,但我没有能力. 谷歌没有帮助. (

I must generete docx or odt file with many math formulas inside. i try to find solution in Apashe POI & ODFtoolkit but i am not was able. google doesn't help. (

也许有人可以帮助我解决此任务吗? (有什么例子吗?)

May be anybody can help me with solution in this task? (any example?)

谢谢.

推荐答案

您可以使用 docx4j 库.这是获得的文档开始.

我建议您首先创建一个模板文件,其中包含所有格式和尽可能多的结构.然后,您应该将内容控件放置在希望文本放到的位置.内容控件可以包含其他内容,您可以使用它们来重复一些通用的结构.

I recommend that you create a template file first, with all the formatting, and as much structure as you can. Then you should put in content-controls where you want your text to go. The content controls could contain other content, that you could use to repeat some common structure.

在Word中,内容控件可以在主功能区的开发人员选项卡中找到.它们分别命名为 Rich Text Content Control Plain Text Content Control .不过,您可能需要先启用开发人员"标签.在选项中的自定义功能区下,选中 Developer .

In Word, the Content Controls can be found in the Developer tab on the main ribbon. They are named Rich Text Content Control and Plain Text Content Control. You might need to enable the Developer Tab first though. In the options, under Customize ribbon, check Developer.

要更改内容控件的标签,请在页面上单击其手柄以将其选中,然后按功能区上的控件属性按钮.然后,您将看到一个对话框,您可以在其中设置标题和标签.

To change the tag of a Content Control, click its handle on the page to select it, and then press the Control Properties button on the ribbon. You will then get a dialog where you can set the title and the tag.

在Java中,内容控件将在对象模型中表示为

In Java, the content controls will be represented in the object model as SdtBlock or SdtRun. When you are processing the template, you should replace those with the content you want.

org.docx4j.math 程序包包含用于创建数学公式的类.

The org.docx4j.math package contains the classes for creating math formulas.

这里是一个例子:

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.

It will look for block-level content-controls named "MyEquation", and replace the math-expressions in them with 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文件.


You can make the equation in Word, and look inside the docx-file. They are stored as zip-files, containing a lot of XML. Specifically, you want to look in the word/document.xml file.

这篇关于如何从Java使用数学公式生成docx/odt文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆