This is an automated email from the ASF dual-hosted git repository.
pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
The following commit(s) were added to refs/heads/trunk by this push:
new ca8abb4364 Support mc:AlternateContent for XWPFRun.getPictureText().
(#1091)
ca8abb4364 is described below
commit ca8abb43646e36cd5f1f3c0a502d712adb92a7b4
Author: Jacobo Aragunde Pérez <[email protected]>
AuthorDate: Wed May 27 14:39:35 2026 +0200
Support mc:AlternateContent for XWPFRun.getPictureText(). (#1091)
Modern Word versions create shapes inside blocks like these:
<mc:AlternateContent>
<mc:Choice Requires="wps">
<w:drawing>...</w:drawing>
</mc:Choice>
<mc:Fallback>
<w:pict>...</w:pict>
</mc:Fallback>
</mc:AlternateContent>
The existing implementation of XWPFRun.getPictureText() only searched
through drawing or pict items that are direct children of the run,
ignoring whatever was inside an <mc:AlternateContent> block. We add
code to include any <w:drawing> items inside these blocks.
We also modify XWPFParagraph.getPictureText() to insert line jumps
between different picture texts, following the mold from
XWPFRun.getPictureText().
---
.../org/apache/poi/xwpf/usermodel/XWPFParagraph.java | 6 +++++-
.../java/org/apache/poi/xwpf/usermodel/XWPFRun.java | 5 +++++
.../apache/poi/xwpf/usermodel/TestXWPFParagraph.java | 12 ++++++++++++
test-data/document/shapes-with-text.docx | Bin 0 -> 27520 bytes
4 files changed, 22 insertions(+), 1 deletion(-)
diff --git
a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
index 0fb903ab44..7ba7e404bf 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
@@ -464,7 +464,11 @@ public class XWPFParagraph implements IBodyElement,
IRunBody, ISDTContents, Para
public String getPictureText() {
StringBuilder out = new StringBuilder(64);
for (XWPFRun run : runs) {
- out.append(run.getPictureText());
+ String pictureText = run.getPictureText();
+ if (out.length() > 0 && pictureText.length() > 0) {
+ out.append("\n");
+ }
+ out.append(pictureText);
}
return out.toString();
}
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
index b3507fbce4..1d51c10f78 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
@@ -37,6 +37,7 @@ import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.POIXMLUnits;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.PackageNamespaces;
import org.apache.poi.util.*;
import org.apache.poi.wp.usermodel.CharacterRun;
import org.apache.poi.xssf.usermodel.XSSFRelation;
@@ -110,6 +111,10 @@ public class XWPFRun implements ISDTContents, IRunElement,
CharacterRun {
List<XmlObject> pictTextObjs = new ArrayList<>();
pictTextObjs.addAll(Arrays.asList(r.getPictArray()));
pictTextObjs.addAll(Arrays.asList(r.getDrawingArray()));
+ pictTextObjs.addAll(Arrays.asList(r.selectPath(
+ "declare namespace w='" + XSSFRelation.NS_WORDPROCESSINGML +
"' " +
+ "declare namespace mc='" +
PackageNamespaces.MARKUP_COMPATIBILITY + "' " +
+ "./mc:AlternateContent/mc:Choice/w:drawing")));
for (XmlObject o : pictTextObjs) {
XmlObject[] ts = o.selectPath("declare namespace w='" +
XSSFRelation.NS_WORDPROCESSINGML + "' .//w:t");
for (XmlObject t : ts) {
diff --git
a/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
b/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
index 5ef646a77c..e29ae8c0d2 100644
---
a/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
+++
b/poi-ooxml/src/test/java/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
@@ -975,4 +975,16 @@ public final class TestXWPFParagraph {
assertEquals(beginChar, result.getBeginChar(), "beginChar");
assertEquals(endChar, result.getEndChar(), "endChar");
}
+
+ @Test
+ void testGetPictureText() throws IOException {
+ try (XWPFDocument doc =
XWPFTestDataSamples.openSampleDocument("shapes-with-text.docx")) {
+ XWPFParagraph p = doc.getParagraphArray(0);
+
+ assertEquals("Floating text box\n" +
+ "A square shape with text inside\n" +
+ "An ellipse with text inside\n" +
+ "A group of shapes\nWhere some contain text",
p.getPictureText());
+ }
+ }
}
diff --git a/test-data/document/shapes-with-text.docx
b/test-data/document/shapes-with-text.docx
new file mode 100644
index 0000000000..87ecf6dcec
Binary files /dev/null and b/test-data/document/shapes-with-text.docx differ
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]