2013-05-28 84 views
1

美好的一天。如何用java中的數學公式生成docx/odt文件

我必須使用裏面的許多數學公式來生成docx或odt文件。 我嘗試在Apashe POI & ODFtoolkit中找到解決方案,但我無法使用。 谷歌沒有幫助。 (

可能有人能幫助我在這個任務的解決方案? (任何的例子嗎?)

感謝。

+0

我的東西它會幫助你,請參見[這] [1] [1]:http://stackoverflow.com/questions/1222951/how-to-create -doc-file-using-java –

+0

謝謝你的回答。你的意思是Open Office UNO?我無法找到如何在OO UNO中創建數學公式的信息。 (( –

回答

2

你可以使用docx4j庫。這裏是Getting started的文檔。

我建議你首先創建一個模板文件,其格式和結構儘可能多,然後你應該把內容控件放在你想要文本去的地方,內容控件可以包含其他內容,可以用來重複一些常見的結構即

在Word中,內容控件可以在主功能區上的開發人員標籤中找到。他們被命名爲富文本內容控制純文本內容控制。不過,您可能需要先啓用開發人員標籤。在選項中,在下自定義色帶,檢查開發人員

要更改內容控件的標籤,請單擊頁面上的其手柄將其選中,然後按功能區上的控件屬性按鈕。然後你會得到一個對話框,你可以設置標題和標籤。

在Java中,內容控件將在對象模型中表示爲SdtBlockSdtRun。在處理模板時,應該將其替換爲您想要的內容。

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文件內。它們存儲爲包含大量XML的zip文件。具體來說,你想看看word/document.xml文件。

+0

)我正在閱讀docx4j手冊,添加文本和表格非常簡單,但是我不能通過任何示例添加 docx對象到文檔中,我嘗試了org.docx4j.math類,但是我沒有成功。 可能你可以給我一些添加簡單公式對象的例子嗎? –

+0

感謝你的例子!你能說我怎麼可以添加到docx模板文件的內容控件,就像你的例子中?只有指定的內容控件(圖形,文本,格式文本...),但我可以找到這樣的,我可以設置名稱( –

+0

@AleksandrYudin閱讀我上面更新的答案。 –