2016-05-26 10 views
1

Apache POI XWPFコンポーネントとjavaを使用して、.xmlファイルからデータをワードドキュメントに抽出しています。これまでのところとても良いですが、私は目次を作成するのに苦労しています。メソッドの開始時に目次を作成し、最後にすべての新しいヘッダーを取得するために更新する必要があります。現在、私はdoc.createTOC()を使用しています。ここでdocはXWPFDocumentから作成された変数で、最初にテーブルを作成してからdoc.enforceUpdateFields()を使用してドキュメントの最後にあるすべてを更新します。しかし、プログラムを実行した後に文書を開くと、目次は空ですが、ナビゲーションパネルには指定したヘッダーがいくつか含まれています。Apache POI目次が更新されない

コメントにはコードを含めることをおすすめします。

XWPFParagraph documentControlHeading = doc.createParagraph(); 
documentControlHeading.setPageBreak(true); 
documentControlHeading.setAlignment(ParagraphAlignment.LEFT); 
documentControlHeading.setStyle("Tier1Header"); 
:私は文書にヘッダを追加する方法を通じてその後

doc.createTOC(); 

:私はその後、目次を作成

XWPFDocument doc = new XWPFDocument(new FileInputStream("D://Template.docx")); 

:だから私は、テンプレートから文書を作成することでスタートを切りました

すべてのヘッダーが追加されたら、すべての新しいヘッダーが目次に表示されるように文書を更新します。うーん...私はcreateTOC()メソッドのコードを探していますし、Heading #ように見えるスタイルを探すことが表示されます

doc.enforceUpdateFields(); 
+1

問題を示すコードを削除してください。おそらく誰かが助けてくれるかもしれません。 – jmarkmurphy

+0

こんにちは。最初の質問にいくつかのコードを追加しました。 – Hendrien

答えて

0

:私はこれは、次のコマンドを使用して購入します。だからTier1Headerが見つかりません。まずテキストを作成し、見出しにはHeading 1のようなスタイルを使用してください。次に、createTOC()を使用してTOCを追加します。目次が作成されるときには、すべての見出しを見つける必要があります。私はenforceUpdateFields()がTOCに影響するかどうかわかりません。

+0

こんにちは。ご意見ありがとうございます。それは動作しますが、TOCはドキュメントの最後にあります。TOCの生成場所を指定する方法はありますか? enforceUpdateFields()は目次のために機能しましたが、ナビゲーションパネルでのみ更新され、文書自体は更新されませんでした。 – Hendrien

+0

申し訳ありませんが、ここの答えは分かりませんが、それは雑草の中にあり、私はソースを掘り起こして見つけ出す時間がありません。 Word文書はPOIで一種のものです。そして、私は、現在コミッターがいるかどうかは分かりません。 HWPFにはTOCを行う方法さえありません。 'createToc()'メソッドがTOCを返すと、必要に応じて行を自分自身で追加できるようになります。それは自動ではありません。 – jmarkmurphy

0

// docxテンプレートには、次のようなテキストが含まれている必要があります。//これは、検索され、WORD TOCで置き換えられます。

// $ {TOC}

public static void main(String[] args) throws IOException, OpenXML4JException { 
     XWPFDocument docTemplate = null; 
     try { 
      File file = new File(PATH_TO_FILE); //"C:\\Reports\\Template.docx"; 
      FileInputStream fis = new FileInputStream(file); 
      docTemplate = new XWPFDocument(fis); 
      generateTOC(docTemplate); 
      saveDocument(docTemplate); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (docTemplate != null) { 
       docTemplate.close(); 
      } 
     } 
    } 

private static void saveDocument(XWPFDocument docTemplate) throws FileNotFoundException, IOException { 
    FileOutputStream outputFile = null; 
    try { 
     outputFile = new FileOutputStream(OUTFILENAME); 
     docTemplate.write(outputFile); 
    } finally { 
     if (outputFile != null) { 
      outputFile.close(); 
     } 
    } 
} 


public static void generateTOC(XWPFDocument document) throws InvalidFormatException, FileNotFoundException, IOException { 
     String findText = "${TOC}"; 
     String replaceText = ""; 
     for (XWPFParagraph p : document.getParagraphs()) { 
      for (XWPFRun r : p.getRuns()) { 
       int pos = r.getTextPosition(); 
       String text = r.getText(pos); 
       if (text != null && text.contains(findText)) { 
        text = text.replace(findText, replaceText); 
        r.setText(text, 0); 
        addField(p, "TOC \\o \"1-3\" \\h \\z \\u"); 
        break; 
       } 
      } 
     } 
    } 

private static void addField(XWPFParagraph paragraph, String fieldName) { 
    CTSimpleField ctSimpleField = paragraph.getCTP().addNewFldSimple(); 
    // ctSimpleField.setInstr(fieldName + " \\* MERGEFORMAT "); 
    ctSimpleField.setInstr(fieldName); 
    ctSimpleField.addNewR().addNewT().setStringValue("<<fieldName>>"); 
} 
+0

更新:保存メソッドの直前に次の行を追加してください: docTemplate.enforceUpdateFields(); – Programmer

0

これはXWPFDocument.classを調べることによって得られ、createTOC()のコードです:あなたが見ることができるように

public void createTOC() { 
    CTSdtBlock block = getDocument().getBody().addNewSdt(); 
    TOC toc = new TOC(block); 
    for (XWPFParagraph par : this.paragraphs) { 
     String parStyle = par.getStyle(); 
     if ((parStyle != null) && (parStyle.startsWith("Heading"))) try { 
      int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue(); 
      toc.addRow(level, par.getText(), 1, "112723803"); 
     } catch (NumberFormatException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

、それがスタイルを持つTOCへのすべての段落を追加します「HeadingX」という名前であり、Xは数字である。しかし、残念ながら、それは十分ではありません。このメソッドは、実際には実装上の不具合があります。

addRow()に渡されたページ番号は常に1です。計算されていません。 最後に、すべての段落と適切なインデントを与える後続のドットを含む目次がありますが、ページは常に「1」に等しくなります。


EDIT ...しかし、解決策hereがあります。

関連する問題