Когда я сохранить DOCX файл после обработки какого-либо текста с XPath с помощью POI, я затем передать ByteArrayOutputStream нового ByteArrayInputStream и кормить его dox4j сdocx4j не может прочитать POI сохраненные файлы, кто виноват?
wordMLPackage = WordprocessingMLPackage.load(
bis
);
С 3 из 4 моих шаблонов это бросает исключение:
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 .xml в [Content_Types] выглядит следующим образом:
<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>
Обратите внимание, что для Override PartName = "/ word/document.xml" отсутствует!
Является ли это допустимым файлом типа содержимого файла без переопределения слова/document.xml? Он открывается в LibreOffice без жалоб. Является ли docx4j полагаться на теги Override, которые могут отсутствовать в типах контента, или POI неправильно записывает типы контента для некоторых моих файлов (3 из 4).
Я думаю, что это ошибка docx4j. POI устанавливает значение по умолчанию с правильным типом, который docx4j выглядит игнорирующим. – Gagravarr
Я согласен, я открыл проблему 46 в проекте github с некоторыми идеями кода, чтобы исправить это. Мне все еще интересно, что говорит спецификация в отношении меток Override. – chugadie