Ваш предоставленный XML
показывает, что ваш Word
документ использует альтернативное содержимое, которое было введено после публикации Office Open XML
в 2007 году. Таким образом, apache poi
не предоставляет методов для получения этого содержимого, поскольку он предоставляет методы только для Office Open XML
по стандарту ECMA-376
. Это потому, что базовый ooxml-schemas
был создан только из этого ECMA-376
стандарта.
Таким образом, элементы drawing
в элементах AlternateContent
можно получить только с помощью методов XML
(XPath
)
Это может выглядеть так:
import java.io.FileInputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlCursor;
import java.util.List;
import java.util.ArrayList;
public class WordGetAllDrawingsFromRuns {
private static List<CTDrawing> getAllDrawings(XWPFRun run) throws Exception {
CTR ctR = run.getCTR();
XmlCursor cursor = ctR.newCursor();
cursor.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//*/w:drawing");
List<CTDrawing> drawings = new ArrayList<CTDrawing>();
while (cursor.hasNextSelection()) {
cursor.toNextSelection();
XmlObject obj = cursor.getObject();
CTDrawing drawing = CTDrawing.Factory.parse(obj.newInputStream());
drawings.add(drawing);
}
return drawings;
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("WordDocument.docx"));
for (IBodyElement bodyElement : document.getBodyElements()) {
if (bodyElement instanceof XWPFParagraph) {
XWPFParagraph paragraph = (XWPFParagraph) bodyElement;
for(IRunElement runElement : paragraph.getIRuns()) {
if (runElement instanceof XWPFRun) {
XWPFRun run = (XWPFRun) runElement;
List<CTDrawing> drawings = getAllDrawings(run);
System.out.println(drawings);
}
}
}
}
document.close();
}
}
Но следующая проблема будет заключаться в том, как получить содержимое из элементов drawing
, тогда как <wps:wsp><wps:txbx>
также не является частью Office Open XML
согласно стандарту ECMA-376
. Так что ooxml-schemas
методы CTDrawing
также не могут их получить. Поэтому, если необходимо затем получить содержимое текстового поля из чертежа, это также возможно только с использованием методов XML
(XPath
) напрямую.
Тогда это может выглядеть так:
private static CTTxbxContent getTextBoxContent(CTDrawing drawing) throws Exception {
XmlCursor cursor = drawing.newCursor();
cursor.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//*/w:txbxContent");
List<CTTxbxContent> txbxContents = new ArrayList<CTTxbxContent>();
while (cursor.hasNextSelection()) {
cursor.toNextSelection();
XmlObject obj = cursor.getObject();
CTTxbxContent txbxContent = CTTxbxContent.Factory.parse(obj.newInputStream());
txbxContents.add(txbxContent);
break;
}
CTTxbxContent txbxContent = null;
if (txbxContents.size() > 0) {
txbxContent = txbxContents.get(0);
}
return txbxContent;
}