1

POI を使用して XPath でテキストを処理した後に docx ファイルを保存すると、ByteArrayOutputStream を新しい ByteArrayInputStream に渡し、それを dox​​4j にフィードします。

wordMLPackage = WordprocessingMLPackage.load(
    bis
);

私のテンプレートの 4 つのうち 3 つを使用すると、例外がスローされます。

  org.docx4j.openpackaging.exceptions.InvalidFormatException: Unexpected package (docx4j supports docx/docxm and pptx only
     at org.docx4j.openpackaging.contenttype.ContentTypeManager.createPackage(ContentTypeManager.java:834)

コードは次のようになります。

    /* Return a package of the appropriate type.  Used when loading an existing
 * Package, with an already populated [Content_Types].xml.  When 
 * creating a new Package, start with the new WordprocessingMLPackage constructor. */
public OpcPackage createPackage() throws InvalidFormatException { 

    /*
     * How do we know what type of Package this is?
     * 
     * In principle, either:
     * 
     * 1. We were told its file extension or mime type in the
     * constructor/method parameters, or
     * 
     * 2. Because [Content_Types].xml contains an override for PartName
     * /document.xml of content type
     * application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml
     * 
     * The latter approach is more reliable, so ..
     * 
     */
    OpcPackage p;

    if (getPartNameOverridenByContentType(ContentTypes.WORDPROCESSINGML_DOCUMENT) != null
            || getPartNameOverridenByContentType(ContentTypes.WORDPROCESSINGML_DOCUMENT_MACROENABLED) != null
            || getPartNameOverridenByContentType(ContentTypes.WORDPROCESSINGML_TEMPLATE ) != null
            || getPartNameOverridenByContentType(ContentTypes.WORDPROCESSINGML_TEMPLATE_MACROENABLED) != null ) { 
        log.info("Detected WordProcessingML package ");
        p = new WordprocessingMLPackage(this);
        return p;
    } else if (getPartNameOverridenByContentType(ContentTypes.PRESENTATIONML_MAIN) != null
            || getPartNameOverridenByContentType(ContentTypes.PRESENTATIONML_TEMPLATE) != null
            || getPartNameOverridenByContentType(ContentTypes.PRESENTATIONML_SLIDESHOW) != null) { 
        log.info("Detected PresentationMLPackage package ");
        p = new PresentationMLPackage(this);
        return p;
    } else if (getPartNameOverridenByContentType(ContentTypes.SPREADSHEETML_WORKBOOK) != null
            || getPartNameOverridenByContentType(ContentTypes.SPREADSHEETML_WORKBOOK_MACROENABLED) != null
            || getPartNameOverridenByContentType(ContentTypes.SPREADSHEETML_TEMPLATE) != null
            || getPartNameOverridenByContentType(ContentTypes.SPREADSHEETML_TEMPLATE_MACROENABLED) != null) {
        //  "xlam", "xlsb" ?
        log.info("Detected SpreadhseetMLPackage package ");
        p = new SpreadsheetMLPackage(this);
        return p;

    } else if (getPartNameOverridenByContentType(ContentTypes.DRAWINGML_DIAGRAM_LAYOUT) != null) {
        log.info("Detected Glox file ");
        p = new GloxPackage(this);
        return p;
    } else {
        throw new InvalidFormatException("Unexpected package (docx4j supports docx/docxm and pptx only");
        //return new Package(this);
    }
}

特定のコンテンツ タイプのオーバーライドとの一致に失敗しているようです。私の最初の docx テンプレートには、[Content_Types].xml ファイルがあります。

<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
    <Override PartName="/_rels/.rels"       ContentType="application/vnd.openxmlformats-package.relationships+xml" />
    <Override PartName="/word/fontTable.xml"        ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" />
    <Override PartName="/word/_rels/document.xml.rels"      ContentType="application/vnd.openxmlformats-package.relationships+xml" />
    <Override PartName="/word/media/image1.wmf"         ContentType="image/x-wmf" />
    <Override PartName="/word/comments.xml"         ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" />
    <Override PartName="/word/numbering.xml"        ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" />
    <Override PartName="/word/footer1.xml"      ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" />
    <Override PartName="/word/document.xml"         ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" />
    <Override PartName="/word/styles.xml"       ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" />
    <Override PartName="/docProps/app.xml"      ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
    <Override PartName="/docProps/core.xml"         ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
</Types>

POI で処理した後、[Content_Types].xml は次のようになります。

<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
  <Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
  <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
  <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
  <Override PartName="/word/_rels/document.xml.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
  <Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml"/>
  <Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/>
  <Override PartName="/word/footer1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml"/>
  <Override PartName="/word/media/image1.wmf" ContentType="image/x-wmf"/>
  <Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/>
  <Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>
</Types>

PartName="/word/document.xml" のオーバーライドがないことに注意してください。

これは、word/document.xml オーバーライドのないファイル コンテンツ タイプ ファイルとして許容されますか? LibreOffice で問題なく開きます。docx4j は、コンテンツ タイプに存在しない可能性のあるオーバーライド タグに依存していますか、または POI が一部のファイルのコンテンツ タイプを正しく記述していません (4 つのうち 3 つ)。

4

1 に答える 1

2

開示:私はdocx4jプロジェクトのリーダーです

POI が行っていることは、仕様上は合法であるように見えますが、理想的ではありません。

ECMA-376 パート 2、「パーツのコンテンツ タイプの取得」に従って、docx4j は、POI の方法で指定された場合、docx のコンテンツ タイプを検出する必要があります。

パート 1 の WordprocessingML の章では、「パッケージ構造」セクションで次のように述べています。

最初に、リレーションシップ パーツのコンテンツ タイプとメイン ドキュメント パーツ (唯一の必須パーツ) を定義する必要があります (物理的にはパッケージの /[Content_Types].xml にあります)。

<Types
 xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
 &lt;Default Extension="rels"
 ContentType="application/vnd.openxmlformatspackage.
 relationships+xml"/> 
<Override PartName="/document.xml"
 ContentType="application/vnd.openxmlformatsofficedocument.
 wordprocessingml.document.main+xml"/> </Types>

私が読んだことは、メイン ドキュメント パーツのコンテンツ タイプを定義する必要がある (POI が行う) ことであり、そのためにオーバーライドを使用することだけがヒントです。

ほとんどの部分が .xml であり、別のものを指定するためにオーバーライドが必要な場合に、1 つ (またはおそらく 2 つまたは 3 つの部分) に一致するものに .xml のデフォルトを使い果たすことは、私にはあまり意味がありません。なぜPOIがこのようにしたのだろうか-仕様の提案とは異なり、Wordが発行するものとは異なる。

とはいえ、https://github.com/plutext/docx4j/commit/1c1190fc3a2fc6e191c825a0e30fde2654cc997cはこれを修正する必要があります。

于 2013-02-21T21:29:20.307 に答える