Link XWPFPicture to XWPFRun, so that embedded pictures can be access from where they live in the text stream

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@996927 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2010-09-14 14:52:35 +00:00
parent 7fad16fd1b
commit 6c8a90d054
8 changed files with 96 additions and 45 deletions

View File

@ -34,6 +34,7 @@
<changes> <changes>
<release version="3.7-beta3" date="2010-??-??"> <release version="3.7-beta3" date="2010-??-??">
<action dev="poi-developers" type="add">Link XWPFPicture to XWPFRun, so that embedded pictures can be access from where they live in the text stream</action>
<action dev="poi-developers" type="fix">Improve handling of Hyperlinks inside XWPFParagraph objects through XWPFHyperlinkRun</action> <action dev="poi-developers" type="fix">Improve handling of Hyperlinks inside XWPFParagraph objects through XWPFHyperlinkRun</action>
<action dev="poi-developers" type="fix">Make XWPFParagraph make more use of XWPFRun, and less on internal StringBuffers</action> <action dev="poi-developers" type="fix">Make XWPFParagraph make more use of XWPFRun, and less on internal StringBuffers</action>
<action dev="poi-developers" type="add">Add a getBodyElements() method to XWPF IBody, to make access to embedded paragraphs and tables easier</action> <action dev="poi-developers" type="add">Add a getBodyElements() method to XWPF IBody, to make access to embedded paragraphs and tables easier</action>

View File

@ -120,13 +120,10 @@ public class XWPFWordExtractor extends POIXMLTextExtractor {
XWPFCommentsDecorator decorator = new XWPFCommentsDecorator(paragraph, null); XWPFCommentsDecorator decorator = new XWPFCommentsDecorator(paragraph, null);
text.append(decorator.getCommentText()).append('\n'); text.append(decorator.getCommentText()).append('\n');
// Do endnotes, footnotes and pictures // Do endnotes and footnotes
for(String str : new String[] { String footnameText = paragraph.getFootnoteText();
paragraph.getFootnoteText(), paragraph.getPictureText() if(footnameText != null && footnameText.length() > 0) {
}) { text.append(footnameText + "\n");
if(str != null && str.length() > 0) {
text.append(str + "\n");
}
} }
if (ctSectPr!=null) { if (ctSectPr!=null) {

View File

@ -17,7 +17,6 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import org.apache.poi.POIXMLDocumentPart;
/** /**
* 9 Jan 2010 * 9 Jan 2010

View File

@ -17,16 +17,16 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import org.apache.poi.POIXMLFactory; import java.lang.reflect.Constructor;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLFactory;
import org.apache.poi.POIXMLRelation; import org.apache.poi.POIXMLRelation;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import java.lang.reflect.Constructor; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
/** /**
* @author Yegor Kozlov * @author Yegor Kozlov

View File

@ -64,10 +64,8 @@ public class XWPFParagraph implements IBodyElement{
protected XWPFDocument document; protected XWPFDocument document;
protected List<XWPFRun> runs; protected List<XWPFRun> runs;
private StringBuffer pictureText = new StringBuffer();
private StringBuffer footnoteText = new StringBuffer(); private StringBuffer footnoteText = new StringBuffer();
public XWPFParagraph(CTP prgrph) { public XWPFParagraph(CTP prgrph) {
this(prgrph, null); this(prgrph, null);
} }
@ -125,6 +123,7 @@ public class XWPFParagraph implements IBodyElement{
// Check for bits that only apply when // Check for bits that only apply when
// attached to a core document // attached to a core document
// TODO Make this nicer by tracking the XWPFFootnotes directly
if(document != null) { if(document != null) {
c = r.newCursor(); c = r.newCursor();
c.selectPath("child::*"); c.selectPath("child::*");
@ -151,22 +150,6 @@ public class XWPFParagraph implements IBodyElement{
} }
} }
} }
// Loop over pictures inside our
// paragraph, looking for text in them
for(CTPicture pict : r.getPictList()) {
XmlObject[] t = pict
.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
for (int m = 0; m < t.length; m++) {
NodeList kids = t[m].getDomNode().getChildNodes();
for (int n = 0; n < kids.getLength(); n++) {
if (kids.item(n) instanceof Text) {
pictureText.append("\n");
pictureText.append(kids.item(n).getNodeValue());
}
}
}
}
} }
} }
@ -196,7 +179,7 @@ public class XWPFParagraph implements IBodyElement{
for(XWPFRun run : runs) { for(XWPFRun run : runs) {
out.append(run.toString()); out.append(run.toString());
} }
out.append(footnoteText).append(pictureText); out.append(footnoteText);
return out.toString(); return out.toString();
} }
@ -261,7 +244,11 @@ public class XWPFParagraph implements IBodyElement{
* Returns any text from any suitable pictures in the paragraph * Returns any text from any suitable pictures in the paragraph
*/ */
public String getPictureText() { public String getPictureText() {
return pictureText.toString(); StringBuffer out = new StringBuffer();
for(XWPFRun run : runs) {
out.append(run.getPictureText());
}
return out.toString();
} }
/** /**

View File

@ -25,14 +25,13 @@ import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
/** /**
* @author Philipp Epp * @author Philipp Epp
*
*/ */
public class XWPFPicture { public class XWPFPicture {
private static final POILogger logger = POILogFactory.getLogger(XWPFPicture.class); private static final POILogger logger = POILogFactory.getLogger(XWPFPicture.class);
protected XWPFParagraph paragraph; protected XWPFParagraph paragraph;
private CTPicture ctPic; private CTPicture ctPic;
public XWPFParagraph getParagraph(){ public XWPFParagraph getParagraph(){
return paragraph; return paragraph;
} }
@ -41,6 +40,7 @@ public class XWPFPicture {
this.paragraph = paragraph; this.paragraph = paragraph;
this.ctPic = ctPic; this.ctPic = ctPic;
} }
/** /**
* Link Picture with PictureData * Link Picture with PictureData
* @param rel * @param rel
@ -57,9 +57,10 @@ public class XWPFPicture {
public CTPicture getCTPicture(){ public CTPicture getCTPicture(){
return ctPic; return ctPic;
} }
/** /**
* Get the PictureData of the Picture * Get the PictureData of the Picture, if present.
* @return * Note - not all kinds of picture have data
*/ */
public XWPFPictureData getPictureData(){ public XWPFPictureData getPictureData(){
String blipId = ctPic.getBlipFill().getBlip().getEmbed(); String blipId = ctPic.getBlipFill().getBlip().getEmbed();
@ -71,4 +72,4 @@ public class XWPFPicture {
return null; return null;
} }
}//end class }

View File

@ -17,11 +17,15 @@
package org.apache.poi.xwpf.usermodel; package org.apache.poi.xwpf.usermodel;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlString; import org.apache.xmlbeans.XmlString;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
@ -39,8 +43,8 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrType;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun;
import org.w3c.dom.NodeList;
import javax.xml.namespace.QName; import org.w3c.dom.Text;
/** /**
* XWPFRun object defines a region of text with a common set of properties * XWPFRun object defines a region of text with a common set of properties
@ -49,7 +53,9 @@ import javax.xml.namespace.QName;
*/ */
public class XWPFRun { public class XWPFRun {
private CTR run; private CTR run;
private String pictureText;
private XWPFParagraph paragraph; private XWPFParagraph paragraph;
private List<XWPFPicture> pictures;
/** /**
* @param r the CTR bean which holds the run attributes * @param r the CTR bean which holds the run attributes
@ -58,6 +64,42 @@ public class XWPFRun {
public XWPFRun(CTR r, XWPFParagraph p) { public XWPFRun(CTR r, XWPFParagraph p) {
this.run = r; this.run = r;
this.paragraph = p; this.paragraph = p;
// Look for any text in any of our pictures or drawings
StringBuffer text = new StringBuffer();
List<XmlObject> pictTextObjs = new ArrayList<XmlObject>();
pictTextObjs.addAll(r.getPictList());
pictTextObjs.addAll(r.getDrawingList());
for(XmlObject o : pictTextObjs) {
XmlObject[] t = o
.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
for (int m = 0; m < t.length; m++) {
NodeList kids = t[m].getDomNode().getChildNodes();
for (int n = 0; n < kids.getLength(); n++) {
if (kids.item(n) instanceof Text) {
if(text.length() > 0)
text.append("\n");
text.append(kids.item(n).getNodeValue());
}
}
}
}
pictureText = text.toString();
// Do we have any embedded pictures?
// (They're a different CTPicture, under the drawingml namespace)
pictures = new ArrayList<XWPFPicture>();
for(XmlObject o : pictTextObjs) {
XmlObject[] picts = o
.selectPath("declare namespace pic='http://schemas.openxmlformats.org/drawingml/2006/picture' .//pic:pic");
for(XmlObject pict : picts) {
if(pict instanceof org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture) {
pictures.add(new XWPFPicture(
(org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture)pict, p
));
}
}
}
} }
/** /**
@ -128,6 +170,13 @@ public class XWPFRun {
.getStringValue(); .getStringValue();
} }
/**
* Returns text embedded in pictures
*/
public String getPictureText() {
return pictureText;
}
/** /**
* Sets the text of this text run * Sets the text of this text run
* *
@ -480,6 +529,15 @@ public class XWPFRun {
//TODO //TODO
} }
/**
* Returns the embedded pictures of the run. These
* are pictures which reference an external,
* embedded picture image such as a .png or .jpg
*/
public List<XWPFPicture> getEmbeddedPictures() {
return pictures;
}
/** /**
* Add the xml:spaces="preserve" attribute if the string has leading or trailing white spaces * Add the xml:spaces="preserve" attribute if the string has leading or trailing white spaces
* *
@ -534,6 +592,11 @@ public class XWPFRun {
} }
} }
// Any picture text?
if(pictureText != null && pictureText.length() > 0) {
text.append("\n").append(pictureText);
}
return text.toString(); return text.toString();
} }
} }

View File

@ -249,4 +249,7 @@ public final class TestXWPFParagraph extends TestCase {
assertEquals("10", p.getNumID().toString()); assertEquals("10", p.getNumID().toString());
} }
public void testPictures() throws Exception {
// TODO
}
} }