]> source.dussan.org Git - poi.git/commitdiff
[Bug 61972] Adding chart in Document of MS-Word File without reading Temp MS-Word...
authorPJ Fanning <fanningpj@apache.org>
Sat, 20 Jan 2018 23:01:18 +0000 (23:01 +0000)
committerPJ Fanning <fanningpj@apache.org>
Sat, 20 Jan 2018 23:01:18 +0000 (23:01 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1821764 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/xddf/usermodel/chart/XDDFChart.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFChart.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFChart.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFChart.java

index 6c1bba3796d25998748fa893dae1726f13dc28bf..e977e6ea398efa4e2a351186b2791674506e2f3e 100644 (file)
@@ -39,11 +39,12 @@ import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.xddf.usermodel.chart.XDDFChart;
 import org.apache.poi.xssf.usermodel.XSSFRelation;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * Represents an entry of a OOXML package.
- *
  * <p>
  * Each POIXMLDocumentPart keeps a reference to the underlying a {@link org.apache.poi.openxml4j.opc.PackagePart}.
  * </p>
@@ -54,7 +55,26 @@ public class POIXMLDocumentPart {
     private String coreDocumentRel = PackageRelationshipTypes.CORE_DOCUMENT;
     private PackagePart packagePart;
     private POIXMLDocumentPart parent;
-    private Map<String,RelationPart> relations = new LinkedHashMap<>();
+    private Map<String, RelationPart> relations = new LinkedHashMap<>();
+    private boolean isCommited = false;
+
+    /**
+     * to check whether embedded part is already committed
+     *
+     * @return return true if embedded part is committed
+     */
+    public boolean isCommited() {
+        return isCommited;
+    }
+
+    /**
+     * setter method to set embedded part is committed
+     *
+     * @param isCommited boolean value
+     */
+    public void setCommited(boolean isCommited) {
+        this.isCommited = isCommited;
+    }
 
     /**
      * The RelationPart is a cached relationship between the document, which contains the RelationPart,
@@ -65,27 +85,26 @@ public class POIXMLDocumentPart {
     public static class RelationPart {
         private final PackageRelationship relationship;
         private final POIXMLDocumentPart documentPart;
-        
+
         RelationPart(PackageRelationship relationship, POIXMLDocumentPart documentPart) {
             this.relationship = relationship;
             this.documentPart = documentPart;
         }
-        
+
         /**
-         * @return the cached relationship, which uniquely identifies this child document part within the parent 
+         * @return the cached relationship, which uniquely identifies this child document part within the parent
          */
         public PackageRelationship getRelationship() {
             return relationship;
         }
-        
+
         /**
          * @param <T> the cast of the caller to a document sub class
-         * 
          * @return the child document part
          */
         @SuppressWarnings("unchecked")
         public <T extends POIXMLDocumentPart> T getDocumentPart() {
-            return (T)documentPart;
+            return (T) documentPart;
         }
     }
 
@@ -111,7 +130,7 @@ public class POIXMLDocumentPart {
 
     /**
      * Construct POIXMLDocumentPart representing a "core document" package part.
-     * 
+     *
      * @param pkg the OPCPackage containing this document
      */
     public POIXMLDocumentPart(OPCPackage pkg) {
@@ -120,15 +139,15 @@ public class POIXMLDocumentPart {
 
     /**
      * Construct POIXMLDocumentPart representing a custom "core document" package part.
-     * 
-     * @param pkg the OPCPackage containing this document
-     * @param coreDocumentRel the relation type of this document 
+     *
+     * @param pkg             the OPCPackage containing this document
+     * @param coreDocumentRel the relation type of this document
      */
     public POIXMLDocumentPart(OPCPackage pkg, String coreDocumentRel) {
         this(getPartFromOPCPackage(pkg, coreDocumentRel));
         this.coreDocumentRel = coreDocumentRel;
     }
-    
+
     /**
      * Creates new POIXMLDocumentPart   - called by client code to create new parts from scratch.
      *
@@ -143,7 +162,6 @@ public class POIXMLDocumentPart {
      *
      * @param part - The package part that holds xml data representing this sheet.
      * @see #read(POIXMLFactory, java.util.Map)
-     *
      * @since POI 3.14-Beta1
      */
     public POIXMLDocumentPart(PackagePart part) {
@@ -155,9 +173,8 @@ public class POIXMLDocumentPart {
      * Called by {@link #read(POIXMLFactory, java.util.Map)} when reading in an existing file.
      *
      * @param parent - Parent part
-     * @param part - The package part that holds xml data representing this sheet.
+     * @param part   - The package part that holds xml data representing this sheet.
      * @see #read(POIXMLFactory, java.util.Map)
-     *
      * @since POI 3.14-Beta1
      */
     public POIXMLDocumentPart(POIXMLDocumentPart parent, PackagePart part) {
@@ -167,21 +184,20 @@ public class POIXMLDocumentPart {
 
     /**
      * When you open something like a theme, call this to
-     *  re-base the XML Document onto the core child of the
-     *  current core document
-     * 
+     * re-base the XML Document onto the core child of the
+     * current core document
+     *
      * @param pkg the package to be rebased
-     * 
-     * @throws InvalidFormatException if there was an error in the core document relation 
-     * @throws IllegalStateException if there are more than one core document relations
+     * @throws InvalidFormatException if there was an error in the core document relation
+     * @throws IllegalStateException  if there are more than one core document relations
      */
     protected final void rebase(OPCPackage pkg) throws InvalidFormatException {
         PackageRelationshipCollection cores =
-            packagePart.getRelationshipsByType(coreDocumentRel);
-        if(cores.size() != 1) {
+                packagePart.getRelationshipsByType(coreDocumentRel);
+        if (cores.size() != 1) {
             throw new IllegalStateException(
-                "Tried to rebase using " + coreDocumentRel +
-                " but found " + cores.size() + " parts of the right type"
+                    "Tried to rebase using " + coreDocumentRel +
+                            " but found " + cores.size() + " parts of the right type"
             );
         }
         packagePart = packagePart.getRelatedPart(cores.getRelationship(0));
@@ -192,7 +208,7 @@ public class POIXMLDocumentPart {
      *
      * @return the underlying PackagePart
      */
-    public final PackagePart getPackagePart(){
+    public final PackagePart getPackagePart() {
         return packagePart;
     }
 
@@ -201,7 +217,7 @@ public class POIXMLDocumentPart {
      *
      * @return child relations
      */
-    public final List<POIXMLDocumentPart> getRelations(){
+    public final List<POIXMLDocumentPart> getRelations() {
         List<POIXMLDocumentPart> l = new ArrayList<>();
         for (RelationPart rp : relations.values()) {
             l.add(rp.getDocumentPart());
@@ -226,8 +242,7 @@ public class POIXMLDocumentPart {
      * {@link POIXMLDocumentPart} with a {@link PackageRelationship#getId()}
      * matching the given parameter value.
      *
-     * @param id
-     *            The relation id to look for
+     * @param id The relation id to look for
      * @return the target part of the relation, or null, if none exists
      */
     public final POIXMLDocumentPart getRelationById(String id) {
@@ -242,10 +257,8 @@ public class POIXMLDocumentPart {
      * {@link POIXMLDocumentPart} with a {@link PackageRelationship#getId()}
      * matching the given parameter value.
      *
-     * @param id
-     *            The relation id to look for
+     * @param id The relation id to look for
      * @return the target relation part, or null, if none exists
-     * 
      * @since 4.0.0
      */
     public final RelationPart getRelationPartById(String id) {
@@ -257,15 +270,14 @@ public class POIXMLDocumentPart {
      * {@link PackageRelationship}, that sources from the {@link PackagePart} of
      * this {@link POIXMLDocumentPart} to the {@link PackagePart} of the given
      * parameter value.<p>
-     * 
+     * <p>
      * There can be multiple references to the given {@link POIXMLDocumentPart}
      * and only the first in the order of creation is returned.
      *
-     * @param part
-     *            The {@link POIXMLDocumentPart} for which the according
-     *            relation-id shall be found.
+     * @param part The {@link POIXMLDocumentPart} for which the according
+     *             relation-id shall be found.
      * @return The value of the {@link PackageRelationship#getId()} or null, if
-     *         parts are not related.
+     * parts are not related.
      */
     public final String getRelationId(POIXMLDocumentPart part) {
         for (RelationPart rp : relations.values()) {
@@ -279,12 +291,10 @@ public class POIXMLDocumentPart {
     /**
      * Add a new child POIXMLDocumentPart
      *
-     * @param relId the preferred relation id, when null the next free relation id will be used
+     * @param relId            the preferred relation id, when null the next free relation id will be used
      * @param relationshipType the package relationship type
-     * @param part the child to add
-     * 
+     * @param part             the child to add
      * @return the new RelationPart
-     *
      * @since 3.14-Beta1
      */
     public final RelationPart addRelation(String relId, POIXMLRelation relationshipType, POIXMLDocumentPart part) {
@@ -301,11 +311,11 @@ public class POIXMLDocumentPart {
     /**
      * Add a new child POIXMLDocumentPart
      *
-     * @param pr the relationship of the child
+     * @param pr   the relationship of the child
      * @param part the child to add
      */
     private void addRelation(PackageRelationship pr, POIXMLDocumentPart part) {
-        relations.put(pr.getId(), new RelationPart(pr,part));
+        relations.put(pr.getId(), new RelationPart(pr, part));
         part.incrementRelationCounter();
 
     }
@@ -313,30 +323,28 @@ public class POIXMLDocumentPart {
     /**
      * Remove the relation to the specified part in this package and remove the
      * part, if it is no longer needed.<p>
-     * 
+     * <p>
      * If there are multiple relationships to the same part, this will only
      * remove the first relationship in the order of creation. The removal
      * via the part id ({@link #removeRelation(String)} is preferred.
-     * 
+     *
      * @param part the part which relation is to be removed from this document
      */
-    protected final void removeRelation(POIXMLDocumentPart part){
-        removeRelation(part,true);
+    protected final void removeRelation(POIXMLDocumentPart part) {
+        removeRelation(part, true);
     }
 
     /**
      * Remove the relation to the specified part in this package and remove the
      * part, if it is no longer needed and flag is set to true.<p>
-     *
+     * <p>
      * If there are multiple relationships to the same part, this will only
      * remove the first relationship in the order of creation. The removal
-     * via the part id ({@link #removeRelation(String,boolean)} is preferred.
+     * via the part id ({@link #removeRelation(String, boolean)} is preferred.
      *
-     * @param part
-     *            The related part, to which the relation shall be removed.
-     * @param removeUnusedParts
-     *            true, if the part shall be removed from the package if not
-     *            needed any longer.
+     * @param part              The related part, to which the relation shall be removed.
+     * @param removeUnusedParts true, if the part shall be removed from the package if not
+     *                          needed any longer.
      * @return true, if the relation was removed
      */
     protected final boolean removeRelation(POIXMLDocumentPart part, boolean removeUnusedParts) {
@@ -347,13 +355,12 @@ public class POIXMLDocumentPart {
     /**
      * Remove the relation to the specified part in this package and remove the
      * part, if it is no longer needed.<p>
-     * 
+     * <p>
      * If there are multiple relationships to the same part, this will only
      * remove the first relationship in the order of creation. The removal
      * via the part id ({@link #removeRelation(String)} is preferred.
-     * 
+     *
      * @param partId the part id which relation is to be removed from this document
-     * 
      * @since 4.0.0
      */
     protected final void removeRelation(String partId) {
@@ -364,13 +371,10 @@ public class POIXMLDocumentPart {
      * Remove the relation to the specified part in this package and remove the
      * part, if it is no longer needed and flag is set to true.<p>
      *
-     * @param partId
-     *            The related part id, to which the relation shall be removed.
-     * @param removeUnusedParts
-     *            true, if the part shall be removed from the package if not
-     *            needed any longer.
+     * @param partId            The related part id, to which the relation shall be removed.
+     * @param removeUnusedParts true, if the part shall be removed from the package if not
+     *                          needed any longer.
      * @return true, if the relation was removed
-     * 
      * @since 4.0.0
      */
     private final boolean removeRelation(String partId, boolean removeUnusedParts) {
@@ -401,28 +405,27 @@ public class POIXMLDocumentPart {
         return true;
     }
 
-    
-    
+
     /**
      * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent.
      *
      * @return the parent POIXMLDocumentPart or <code>null</code> for the root element.
      */
-    public final POIXMLDocumentPart getParent(){
+    public final POIXMLDocumentPart getParent() {
         return parent;
     }
 
     @Override
-    public String toString(){
+    public String toString() {
         return packagePart == null ? "" : packagePart.toString();
     }
 
     /**
      * Save the content in the underlying package part.
      * Default implementation is empty meaning that the package part is left unmodified.
-     *
+     * <p>
      * Sub-classes should override and add logic to marshal the "model" into Ooxml4J.
-     *
+     * <p>
      * For example, the code saving a generic XML entry may look as follows:
      * <pre>
      * protected void commit() throws IOException {
@@ -433,7 +436,7 @@ public class POIXMLDocumentPart {
      *   out.close();
      * }
      * </pre>
-     * 
+     *
      * @throws IOException a subclass may throw an IOException if the changes can't be committed
      */
     protected void commit() throws IOException {
@@ -444,17 +447,21 @@ public class POIXMLDocumentPart {
      * Save changes in the underlying OOXML package.
      * Recursively fires {@link #commit()} for each package part
      *
-     * @param alreadySaved    context set containing already visited nodes
-     * 
+     * @param alreadySaved context set containing already visited nodes
      * @throws IOException a related part may throw an IOException if the changes can't be saved
      */
-    protected final void onSave(Set<PackagePart> alreadySaved) throws IOException{
+    protected final void onSave(Set<PackagePart> alreadySaved) throws IOException {
+        //if part is already committed then return
+        if (this.isCommited) {
+            return;
+        }
+
         // this usually clears out previous content in the part...
         prepareForCommit();
 
         commit();
         alreadySaved.add(this.getPackagePart());
-        for(RelationPart rp : relations.values()){
+        for (RelationPart rp : relations.values()) {
             POIXMLDocumentPart p = rp.getDocumentPart();
             if (!alreadySaved.contains(p.getPackagePart())) {
                 p.onSave(alreadySaved);
@@ -465,13 +472,13 @@ public class POIXMLDocumentPart {
     /**
      * Ensure that a memory based package part does not have lingering data from previous
      * commit() calls.
-     *
+     * <p>
      * Note: This is overwritten for some objects, as *PictureData seem to store the actual content
      * in the part directly without keeping a copy like all others therefore we need to handle them differently.
      */
     protected void prepareForCommit() {
         PackagePart part = this.getPackagePart();
-        if(part != null) {
+        if (part != null) {
             part.clear();
         }
     }
@@ -480,14 +487,13 @@ public class POIXMLDocumentPart {
      * Create a new child POIXMLDocumentPart
      *
      * @param descriptor the part descriptor
-     * @param factory the factory that will create an instance of the requested relation
+     * @param factory    the factory that will create an instance of the requested relation
      * @return the created child POIXMLDocumentPart
-     * @throws PartAlreadyExistsException
-     *             If rule M1.12 is not verified : Packages shall not contain
-     *             equivalent part names and package implementers shall neither
-     *             create nor recognize packages with equivalent part names.
+     * @throws PartAlreadyExistsException If rule M1.12 is not verified : Packages shall not contain
+     *                                    equivalent part names and package implementers shall neither
+     *                                    create nor recognize packages with equivalent part names.
      */
-    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
+    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory) {
         return createRelationship(descriptor, factory, -1, false).getDocumentPart();
     }
 
@@ -495,37 +501,36 @@ public class POIXMLDocumentPart {
      * Create a new child POIXMLDocumentPart
      *
      * @param descriptor the part descriptor
-     * @param factory the factory that will create an instance of the requested relation
-     * @param idx part number
+     * @param factory    the factory that will create an instance of the requested relation
+     * @param idx        part number
      * @return the created child POIXMLDocumentPart
-     * @throws PartAlreadyExistsException
-     *             If rule M1.12 is not verified : Packages shall not contain
-     *             equivalent part names and package implementers shall neither
-     *             create nor recognize packages with equivalent part names.
+     * @throws PartAlreadyExistsException If rule M1.12 is not verified : Packages shall not contain
+     *                                    equivalent part names and package implementers shall neither
+     *                                    create nor recognize packages with equivalent part names.
      */
-    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
+    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx) {
         return createRelationship(descriptor, factory, idx, false).getDocumentPart();
     }
-    
+
     /**
      * Identifies the next available part number for a part of the given type,
-     *  if possible, otherwise -1 if none are available.
+     * if possible, otherwise -1 if none are available.
      * The found (valid) index can then be safely given to
-     *  {@link #createRelationship(POIXMLRelation, POIXMLFactory, int)} or
-     *  {@link #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)}
-     *  without naming clashes.
+     * {@link #createRelationship(POIXMLRelation, POIXMLFactory, int)} or
+     * {@link #createRelationship(POIXMLRelation, POIXMLFactory, int, boolean)}
+     * without naming clashes.
      * If parts with other types are already claiming a name for this relationship
-     *  type (eg a {@link XSSFRelation#CHART} using the drawing part namespace 
-     *  normally used by {@link XSSFRelation#DRAWINGS}), those will be considered
-     *  when finding the next spare number.
+     * type (eg a {@link XSSFRelation#CHART} using the drawing part namespace
+     * normally used by {@link XSSFRelation#DRAWINGS}), those will be considered
+     * when finding the next spare number.
      *
      * @param descriptor The relationship type to find the part number for
-     * @param minIdx The minimum free index to assign, use -1 for any
+     * @param minIdx     The minimum free index to assign, use -1 for any
      * @return The next free part number, or -1 if none available
      */
     protected final int getNextPartNumber(POIXMLRelation descriptor, int minIdx) {
         OPCPackage pkg = packagePart.getPackage();
-        
+
         try {
             String name = descriptor.getDefaultFileName();
             if (name.equals(descriptor.getFileName(9999))) {
@@ -539,7 +544,7 @@ public class POIXMLDocumentPart {
                     return 0;
                 }
             }
-            
+
             // Default to searching from 1, unless they asked for 0+
             int idx = (minIdx < 0) ? 1 : minIdx;
             int maxIdx = minIdx + pkg.getParts().size();
@@ -562,21 +567,20 @@ public class POIXMLDocumentPart {
      * Create a new child POIXMLDocumentPart
      *
      * @param descriptor the part descriptor
-     * @param factory the factory that will create an instance of the requested relation
-     * @param idx part number
+     * @param factory    the factory that will create an instance of the requested relation
+     * @param idx        part number
      * @param noRelation if true, then no relationship is added.
      * @return the created child POIXMLDocumentPart
-     * @throws PartAlreadyExistsException
-     *             If rule M1.12 is not verified : Packages shall not contain
-     *             equivalent part names and package implementers shall neither
-     *             create nor recognize packages with equivalent part names.
+     * @throws PartAlreadyExistsException If rule M1.12 is not verified : Packages shall not contain
+     *                                    equivalent part names and package implementers shall neither
+     *                                    create nor recognize packages with equivalent part names.
      */
-    public final RelationPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){
+    public final RelationPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation) {
         try {
             PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
             PackageRelationship rel = null;
             PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
-            if(!noRelation) {
+            if (!noRelation) {
                 /* only add to relations, if according relationship is being created. */
                 rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
             }
@@ -585,17 +589,17 @@ public class POIXMLDocumentPart {
             doc.parent = this;
             if (!noRelation) {
                 /* only add to relations, if according relationship is being created. */
-                addRelation(rel,doc);
+                addRelation(rel, doc);
             }
 
-            return new RelationPart(rel,doc);
+            return new RelationPart(rel, doc);
         } catch (PartAlreadyExistsException pae) {
-           // Return the specific exception so the user knows
-           //  that the name is already taken
-           throw pae;
-        } catch (Exception e){
-           // Give a general wrapped exception for the problem
-           throw new POIXMLException(e);
+            // Return the specific exception so the user knows
+            //  that the name is already taken
+            throw pae;
+        } catch (Exception e) {
+            // Give a general wrapped exception for the problem
+            throw new POIXMLException(e);
         }
     }
 
@@ -603,9 +607,8 @@ public class POIXMLDocumentPart {
      * Iterate through the underlying PackagePart and create child POIXMLFactory instances
      * using the specified factory
      *
-     * @param factory   the factory object that creates POIXMLFactory instances
-     * @param context   context map containing already visited noted keyed by targetURI
-     * 
+     * @param factory the factory object that creates POIXMLFactory instances
+     * @param context context map containing already visited noted keyed by targetURI
      * @throws OpenXML4JException thrown when a related part can't be read
      */
     protected void read(POIXMLFactory factory, Map<PackagePart, POIXMLDocumentPart> context) throws OpenXML4JException {
@@ -623,12 +626,12 @@ public class POIXMLDocumentPart {
 
         // scan breadth-first, so parent-relations are hopefully the shallowest element
         for (PackageRelationship rel : rels) {
-            if(rel.getTargetMode() == TargetMode.INTERNAL){
+            if (rel.getTargetMode() == TargetMode.INTERNAL) {
                 URI uri = rel.getTargetURI();
 
                 // check for internal references (e.g. '#Sheet1!A1')
                 PackagePartName relName;
-                if(uri.getRawFragment() != null) {
+                if (uri.getRawFragment() != null) {
                     relName = PackagingURIHelper.createPartName(uri.getPath());
                 } else {
                     relName = PackagingURIHelper.createPartName(uri);
@@ -643,13 +646,18 @@ public class POIXMLDocumentPart {
                 POIXMLDocumentPart childPart = context.get(p);
                 if (childPart == null) {
                     childPart = factory.createDocumentPart(this, p);
+                    //here we are checking if part if embedded and excel then set it to chart class
+                    //so that at the time to writing we can also write updated embedded part
+                    if (this instanceof XDDFChart && childPart instanceof XSSFWorkbook) {
+                        ((XDDFChart) this).setWorkbook((XSSFWorkbook) childPart);
+                    }
                     childPart.parent = this;
                     // already add child to context, so other children can reference it
                     context.put(p, childPart);
                     readLater.add(childPart);
                 }
 
-                addRelation(rel,childPart);
+                addRelation(rel, childPart);
             }
         }
 
@@ -672,7 +680,7 @@ public class POIXMLDocumentPart {
 
     /**
      * Fired when a new package part is created
-     * 
+     *
      * @throws IOException a subclass may throw an IOException on document creation
      */
     protected void onDocumentCreate() throws IOException {
@@ -681,7 +689,7 @@ public class POIXMLDocumentPart {
 
     /**
      * Fired when a package part is read
-     * 
+     *
      * @throws IOException a subclass may throw an IOException when a document is read
      */
     protected void onDocumentRead() throws IOException {
@@ -690,7 +698,7 @@ public class POIXMLDocumentPart {
 
     /**
      * Fired when a package part is about to be removed from the package
-     * 
+     *
      * @throws IOException a subclass may throw an IOException when a document is removed
      */
     protected void onDocumentRemove() throws IOException {
@@ -702,19 +710,19 @@ public class POIXMLDocumentPart {
      * <p>
      * This method only exists to allow access to protected {@link POIXMLDocumentPart#onDocumentRead()}
      * from {@link org.apache.poi.xwpf.usermodel.XWPFDocument} without reflection. It should be removed.
-     * 
+     *
      * @param part the part which is to be read
-     * 
      * @throws IOException if the part can't be read
      */
-    @Internal @Deprecated
+    @Internal
+    @Deprecated
     public static void _invokeOnDocumentRead(POIXMLDocumentPart part) throws IOException {
         part.onDocumentRead();
     }
 
     /**
      * Retrieves the core document part
-     * 
+     *
      * @since POI 3.14-Beta1
      */
     private static PackagePart getPartFromOPCPackage(OPCPackage pkg, String coreDocumentRel) {
@@ -723,11 +731,11 @@ public class POIXMLDocumentPart {
         if (coreRel != null) {
             PackagePart pp = pkg.getPart(coreRel);
             if (pp == null) {
-                throw new POIXMLException("OOXML file structure broken/invalid - core document '"+coreRel.getTargetURI()+"' not found.");
+                throw new POIXMLException("OOXML file structure broken/invalid - core document '" + coreRel.getTargetURI() + "' not found.");
             }
             return pp;
         }
-        
+
         coreRel = pkg.getRelationshipsByType(PackageRelationshipTypes.STRICT_CORE_DOCUMENT).getRelationship(0);
         if (coreRel != null) {
             throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699");
index 0f6bad2a093f52cee6651310902d35d67fab2475..4c302b83e7511d934219b769aab6e6fb541a4ca7 100644 (file)
@@ -22,6 +22,7 @@ package org.apache.poi.xddf.usermodel.chart;
 import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
 
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -29,12 +30,32 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.namespace.QName;
+
+import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.POIXMLFactory;
+import org.apache.poi.POIXMLRelation;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
 import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
 import org.apache.poi.xddf.usermodel.XDDFShapeProperties;
+import org.apache.poi.xslf.usermodel.XSLFChart;
+import org.apache.poi.xslf.usermodel.XSLFFactory;
+import org.apache.poi.xslf.usermodel.XSLFRelation;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.xwpf.usermodel.XWPFFactory;
+import org.apache.poi.xwpf.usermodel.XWPFRelation;
 import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlOptions;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
@@ -54,6 +75,13 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
 @Beta
 public abstract class XDDFChart extends POIXMLDocumentPart {
 
+    /**
+     * Underlying workbook
+     */
+    private XSSFWorkbook workbook;
+
+    private int chartIndex = 0;
+
     protected List<XDDFChartAxis> axes = new ArrayList<>();
 
     /**
@@ -81,8 +109,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart {
      * Construct a DrawingML chart from a package part.
      *
      * @param part the package part holding the chart data,
-     * the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
-     *
+     *             the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
      * @since POI 3.14-Beta1
      */
     protected XDDFChart(PackagePart part) throws IOException, XmlException {
@@ -125,7 +152,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart {
 
     /**
      * @return true if only visible cells will be present on the chart,
-     *         false otherwise
+     * false otherwise
      */
     public boolean isPlotOnlyVisibleCells() {
         if (chart.isSetPlotVisOnly()) {
@@ -137,7 +164,7 @@ public abstract class XDDFChart extends POIXMLDocumentPart {
 
     /**
      * @param only a flag specifying if only visible cells should be
-     *        present on the chart
+     *             present on the chart
      */
     public void setPlotOnlyVisibleCells(boolean only) {
         if (!chart.isSetPlotVisOnly()) {
@@ -206,8 +233,10 @@ public abstract class XDDFChart extends POIXMLDocumentPart {
     }
 
     public void plot(XDDFChartData data) {
+        XSSFSheet sheet = getSheet();
         for (XDDFChartData.Series series : data.getSeries()) {
             series.plot();
+            fillSheet(sheet, series.getCategoryData(), series.getValuesData());
         }
     }
 
@@ -306,18 +335,18 @@ public abstract class XDDFChart extends POIXMLDocumentPart {
         Map<Long, XDDFValueAxis> mapValues = Collections.singletonMap(values.getId(), values);
         final CTPlotArea plotArea = getCTPlotArea();
         switch (type) {
-        case BAR:
-            return new XDDFBarChartData(plotArea.addNewBarChart(), categories, mapValues);
-        case LINE:
-            return new XDDFLineChartData(plotArea.addNewLineChart(), categories, mapValues);
-        case PIE:
-            return new XDDFPieChartData(plotArea.addNewPieChart());
-        case RADAR:
-            return new XDDFRadarChartData(plotArea.addNewRadarChart(), categories, mapValues);
-        case SCATTER:
-            return new XDDFScatterChartData(plotArea.addNewScatterChart(), categories, mapValues);
-        default:
-            return null;
+            case BAR:
+                return new XDDFBarChartData(plotArea.addNewBarChart(), categories, mapValues);
+            case LINE:
+                return new XDDFLineChartData(plotArea.addNewLineChart(), categories, mapValues);
+            case PIE:
+                return new XDDFPieChartData(plotArea.addNewPieChart());
+            case RADAR:
+                return new XDDFRadarChartData(plotArea.addNewRadarChart(), categories, mapValues);
+            case SCATTER:
+                return new XDDFScatterChartData(plotArea.addNewScatterChart(), categories, mapValues);
+            default:
+                return null;
         }
     }
 
@@ -347,4 +376,247 @@ public abstract class XDDFChart extends POIXMLDocumentPart {
         }
     }
 
+    /**
+     * method to create relationship with embedded part
+     * for example writing xlsx file stream into output stream
+     *
+     * @param chartRelation relationship object
+     * @param chartFactory  ChartFactory object
+     * @param chartIndex    index used to suffix on file
+     * @return return relation part which used to write relation in .rels file and get relation id
+     * @since POI 4.0.0
+     */
+    public PackageRelationship createRelationshipInChart(POIXMLRelation chartRelation, POIXMLFactory chartFactory, int chartIndex) {
+        POIXMLDocumentPart documentPart = createRelationship(chartRelation, chartFactory, chartIndex, true).getDocumentPart();
+        documentPart.setCommited(true);
+        return this.addRelation(null, chartRelation, documentPart).getRelationship();
+    }
+
+    /**
+     * if embedded part was null then create new part
+     *
+     * @param chartRelation         chart relation object
+     * @param chartWorkbookRelation chart workbook relation object
+     * @param chartFactory          factory object of POIXMLFactory (XWPFFactory/XSLFFactory)
+     * @return return the new package part
+     * @throws InvalidFormatException
+     * @since POI 4.0.0
+     */
+    private PackagePart createWorksheetPart(POIXMLRelation chartRelation, POIXMLRelation chartWorkbookRelation, POIXMLFactory chartFactory) throws InvalidFormatException {
+        PackageRelationship xlsx = createRelationshipInChart(XSLFRelation.WORKBOOK_RELATIONSHIP, XSLFFactory.getInstance(), chartIndex);
+        this.setExternalId(xlsx.getId());
+        return getTargetPart(xlsx);
+    }
+
+    /**
+     * this method write the XSSFWorkbook object data into embedded excel file
+     *
+     * @param workbook XSSFworkbook object
+     * @throws IOException
+     * @throws InvalidFormatException
+     * @since POI 4.0.0
+     */
+    public void saveWorkbook(XSSFWorkbook workbook) throws IOException, InvalidFormatException {
+        PackagePart worksheetPart = getWorksheetPart(true);
+        if (worksheetPart == null) {
+            POIXMLRelation chartRelation = null;
+            POIXMLRelation chartWorkbookRelation = null;
+            POIXMLFactory chartFactory = null;
+            if (this instanceof XSLFChart) {
+                chartRelation = XSLFRelation.CHART;
+                chartWorkbookRelation = XSLFRelation.WORKBOOK_RELATIONSHIP;
+                chartFactory = XSLFFactory.getInstance();
+            } else {
+                chartRelation = XWPFRelation.CHART;
+                chartRelation = XWPFRelation.WORKBOOK_RELATIONSHIP;
+                chartFactory = XWPFFactory.getInstance();
+            }
+            worksheetPart = createWorksheetPart(chartRelation, chartWorkbookRelation, chartFactory);
+        }
+        try (OutputStream xlsOut = worksheetPart.getOutputStream()) {
+            workbook.write(xlsOut);
+        }
+    }
+
+    /**
+     * this method writes the data into sheet
+     *
+     * @param sheet        sheet of embedded excel
+     * @param categoryData category values
+     * @param valuesData   data values
+     * @since POI 4.0.0
+     */
+    protected void fillSheet(XSSFSheet sheet, XDDFDataSource<?> categoryData, XDDFNumericalDataSource<?> valuesData) {
+        int numOfPoints = categoryData.getPointCount();
+        for (int i = 0; i < numOfPoints; i++) {
+            XSSFRow row = sheet.createRow(i + 1); // first row is for title
+            row.createCell(0).setCellValue(categoryData.getPointAt(i).toString());
+            row.createCell(1).setCellValue(valuesData.getPointAt(i).doubleValue());
+        }
+    }
+
+    /**
+     * import content from other chart to created chart
+     *
+     * @param other chart object
+     * @since POI 4.0.0
+     */
+    public void importContent(XDDFChart other) {
+        this.chart.set(other.chart);
+    }
+
+    /**
+     * save chart xml
+     */
+    @Override
+    protected void commit() throws IOException {
+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
+
+        if (workbook != null) {
+            try {
+                saveWorkbook(workbook);
+            } catch (InvalidFormatException e) {
+                throw new POIXMLException(e);
+            }
+        }
+
+        PackagePart part = getPackagePart();
+        try (OutputStream out = part.getOutputStream()) {
+            chartSpace.save(out, xmlOptions);
+        }
+    }
+
+    /**
+     * set sheet time in excel file
+     *
+     * @param title title of sheet
+     * @return return cell reference
+     * @since POI 4.0.0
+     */
+    public CellReference setSheetTitle(String title) {
+        XSSFSheet sheet = getSheet();
+        sheet.createRow(0).createCell(1).setCellValue(title);
+        return new CellReference(sheet.getSheetName(), 0, 1, true, true);
+    }
+
+    /**
+     * @param range
+     * @return
+     * @since POI 4.0.0
+     */
+    public String formatRange(CellRangeAddress range) {
+        return range.formatAsString(getSheet().getSheetName(), true);
+    }
+
+    /**
+     * get sheet object of embedded excel file
+     *
+     * @return excel sheet object
+     * @since POI 4.0.0
+     */
+    private XSSFSheet getSheet() {
+        XSSFSheet sheet = null;
+        try {
+            sheet = getWorkbook().getSheetAt(0);
+        } catch (InvalidFormatException ife) {
+        } catch (IOException ioe) {
+        }
+        return sheet;
+    }
+
+    /**
+     * default method for worksheet part
+     *
+     * @return return embedded worksheet part
+     * @throws InvalidFormatException
+     * @since POI 4.0.0
+     */
+    private PackagePart getWorksheetPart() throws InvalidFormatException {
+        return getWorksheetPart(false);
+    }
+
+    /**
+     * this method is used to get worksheet part
+     * if call is from saveworkbook method then check isCommitted
+     * isCommitted variable shows that we are writing xssfworkbook object into output stream of embedded part
+     *
+     * @param isCommitted if it's true then it shows that we are writing xssfworkbook object into output stream of embedded part
+     * @return returns the packagepart of embedded file
+     * @throws InvalidFormatException
+     * @since POI 4.0.0
+     */
+    private PackagePart getWorksheetPart(boolean isCommitted) throws InvalidFormatException {
+        for (RelationPart part : getRelationParts()) {
+            if (POIXMLDocument.PACK_OBJECT_REL_TYPE.equals(part.getRelationship().getRelationshipType())) {
+                if (isCommitted) {
+                    part.getDocumentPart().setCommited(true);
+                }
+                return getTargetPart(part.getRelationship());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @return returns the workbook object of embedded excel file
+     * @throws IOException
+     * @throws InvalidFormatException
+     * @since POI 4.0.0
+     */
+    public XSSFWorkbook getWorkbook() throws IOException, InvalidFormatException {
+        if (workbook == null) {
+            try {
+                PackagePart worksheetPart = getWorksheetPart();
+                if (worksheetPart == null) {
+                    workbook = new XSSFWorkbook();
+                    workbook.createSheet();
+                } else {
+                    workbook = new XSSFWorkbook(worksheetPart.getInputStream());
+                }
+            } catch (NotOfficeXmlFileException e) {
+                workbook = new XSSFWorkbook();
+                workbook.createSheet();
+            }
+        }
+        return workbook;
+    }
+
+    /**
+     * while reading chart from template file then we need to parse and store embedded excel
+     * file in chart object show that we can modify value according to use
+     *
+     * @param workbook workbook object which we read from chart embedded part
+     * @since POI 4.0.0
+     */
+    public void setWorkbook(XSSFWorkbook workbook) {
+        this.workbook = workbook;
+    }
+
+    /**
+     * set the relation id of embedded excel relation id into external data relation tag
+     *
+     * @param id relation id of embedded excel relation id into external data relation tag
+     * @since POI 4.0.0
+     */
+    public void setExternalId(String id) {
+        getCTChartSpace().addNewExternalData().setId(id);
+    }
+
+    /**
+     * @return method return chart index
+     * @since POI 4.0.0
+     */
+    protected int getChartIndex() {
+        return chartIndex;
+    }
+
+    /**
+     * set chart index which can be use for relation part
+     *
+     * @param chartIndex chart index which can be use for relation part
+     */
+    public void setChartIndex(int chartIndex) {
+        this.chartIndex = chartIndex;
+    }
 }
index 1f66768cde861321b88f6f7ec55af3bf4bf3cc95..a935174f1458e86b8a7447b31c3e950898daaaca 100644 (file)
@@ -67,12 +67,12 @@ import org.openxmlformats.schemas.presentationml.x2006.main.PresentationDocument
 /**
  * High level representation of a ooxml slideshow.
  * This is the first object most users will construct whether
- *  they are reading or writing a slideshow. It is also the
- *  top level object for creating new slides/etc.
+ * they are reading or writing a slideshow. It is also the
+ * top level object for creating new slides/etc.
  */
 @Beta
 public class XMLSlideShow extends POIXMLDocument
-implements SlideShow<XSLFShape,XSLFTextParagraph> {
+        implements SlideShow<XSLFShape, XSLFTextParagraph> {
     private static final POILogger LOG = POILogFactory.getLogger(XMLSlideShow.class);
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 1_000_000;
@@ -94,13 +94,13 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
         super(pkg);
 
         try {
-            if(getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) {
+            if (getCorePart().getContentType().equals(XSLFRelation.THEME_MANAGER.getContentType())) {
                 rebase(getPackage());
             }
 
             //build a tree of POIXMLDocumentParts, this presentation being the root
             load(XSLFFactory.getInstance());
-        } catch (Exception e){
+        } catch (Exception e) {
             throw new POIXMLException(e);
         }
     }
@@ -116,7 +116,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
         }
         try {
             return OPCPackage.open(is);
-        } catch (Exception e){
+        } catch (Exception e) {
             throw new POIXMLException(e);
         } finally {
             IOUtils.closeQuietly(is);
@@ -144,17 +144,17 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
                     }
                 } else if (p instanceof XSLFSlideMaster) {
                     masterMap.put(getRelationId(p), (XSLFSlideMaster) p);
-                } else if (p instanceof XSLFTableStyles){
-                    _tableStyles = (XSLFTableStyles)p;
+                } else if (p instanceof XSLFTableStyles) {
+                    _tableStyles = (XSLFTableStyles) p;
                 } else if (p instanceof XSLFNotesMaster) {
-                    _notesMaster = (XSLFNotesMaster)p;
+                    _notesMaster = (XSLFNotesMaster) p;
                 } else if (p instanceof XSLFCommentAuthors) {
-                    _commentAuthors = (XSLFCommentAuthors)p;
+                    _commentAuthors = (XSLFCommentAuthors) p;
                 }
             }
 
             _charts = new ArrayList<>(chartMap.size());
-            for(XSLFChart chart : chartMap.values()) {
+            for (XSLFChart chart : chartMap.values()) {
                 _charts.add(chart);
             }
 
@@ -200,10 +200,10 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
 
     @Override
     public List<XSLFPictureData> getPictureData() {
-        if(_pictures == null){
+        if (_pictures == null) {
             List<PackagePart> mediaParts = getPackage().getPartsByName(Pattern.compile("/ppt/media/.*?"));
             _pictures = new ArrayList<>(mediaParts.size());
-            for(PackagePart part : mediaParts){
+            for (PackagePart part : mediaParts) {
                 XSLFPictureData pd = new XSLFPictureData(part);
                 pd.setIndex(_pictures.size());
                 _pictures.add(pd);
@@ -226,8 +226,8 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
             slideList = _presentation.addNewSldIdLst();
         } else {
             slideList = _presentation.getSldIdLst();
-            for(CTSlideIdListEntry slideId : slideList.getSldIdArray()){
-                slideNumber = (int)Math.max(slideId.getId() + 1, slideNumber);
+            for (CTSlideIdListEntry slideId : slideList.getSldIdArray()) {
+                slideNumber = (int) Math.max(slideId.getId() + 1, slideNumber);
                 cnt++;
             }
 
@@ -253,7 +253,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     private int findNextAvailableFileNameIndex(XSLFRelation relationType, int idx) {
         // Bug 55791: We also need to check that the resulting file name is not already taken
         // this can happen when removing/adding slides, notes or charts
-        while(true) {
+        while (true) {
             String fileName = relationType.getFileName(idx);
             boolean found = false;
             for (POIXMLDocumentPart relation : getRelations()) {
@@ -265,7 +265,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
                 }
             }
 
-            if(!found &&
+            if (!found &&
                     getPackage().getPartsByName(Pattern.compile(Pattern.quote(fileName))).size() > 0) {
                 // name is taken => try next one
                 found = true;
@@ -305,16 +305,11 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
         int chartIdx = findNextAvailableFileNameIndex(XSLFRelation.CHART, _charts.size() + 1);
         XSLFChart chart = (XSLFChart) createRelationship(XSLFRelation.CHART, XSLFFactory.getInstance(), chartIdx, true).getDocumentPart();
         slide.addRelation(null, XSLFRelation.CHART, chart);
-        createWorkbookRelationship(chart, chartIdx);
+        chart.setChartIndex(chartIdx);
         _charts.add(chart);
         return chart;
     }
 
-    protected PackageRelationship createWorkbookRelationship(XSLFChart chart, int chartIdx) {
-        POIXMLDocumentPart worksheet = createRelationship(XSLFChart.WORKBOOK_RELATIONSHIP, XSLFFactory.getInstance(), chartIdx, true).getDocumentPart();
-        return chart.addRelation(null, XSLFChart.WORKBOOK_RELATIONSHIP, worksheet).getRelationship();
-    }
-
     /**
      * Return notes slide for the specified slide or create new if it does not exist yet.
      */
@@ -344,7 +339,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
 
         // add notes slide to presentation
         XSLFNotes notesSlide = (XSLFNotes) createRelationship
-            (relationType, XSLFFactory.getInstance(), slideIndex);
+                (relationType, XSLFFactory.getInstance(), slideIndex);
         // link slide and notes slide with each other
         slide.addRelation(null, relationType, notesSlide);
         notesSlide.addRelation(null, XSLFRelation.NOTES_MASTER, _notesMaster);
@@ -360,7 +355,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
      */
     public void createNotesMaster() {
         RelationPart rp = createRelationship
-            (XSLFRelation.NOTES_MASTER, XSLFFactory.getInstance(), 1, false);
+                (XSLFRelation.NOTES_MASTER, XSLFFactory.getInstance(), 1, false);
         _notesMaster = rp.getDocumentPart();
 
         CTNotesMasterIdList notesMasterIdList = _presentation.addNewNotesMasterIdLst();
@@ -390,7 +385,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
         }
 
         XSLFTheme theme = (XSLFTheme) createRelationship
-            (XSLFRelation.THEME, XSLFFactory.getInstance(), themeIndex);
+                (XSLFRelation.THEME, XSLFFactory.getInstance(), themeIndex);
         theme.importTheme(getSlides().get(0).getTheme());
 
         _notesMaster.addRelation(null, XSLFRelation.THEME, theme);
@@ -433,12 +428,11 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     }
 
     /**
-     *
      * @param newIndex 0-based index of the slide
      */
-    public void setSlideOrder(XSLFSlide slide, int newIndex){
+    public void setSlideOrder(XSLFSlide slide, int newIndex) {
         int oldIndex = _slides.indexOf(slide);
-        if(oldIndex == -1) {
+        if (oldIndex == -1) {
             throw new IllegalArgumentException("Slide not found");
         }
         if (oldIndex == newIndex) {
@@ -461,7 +455,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
         sldIdLst.setSldIdArray(entries);
     }
 
-    public XSLFSlide removeSlide(int index){
+    public XSLFSlide removeSlide(int index) {
         XSLFSlide slide = _slides.remove(index);
         removeRelation(slide);
         _presentation.getSldIdLst().removeSldId(index);
@@ -479,15 +473,15 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     }
 
     @Override
-    public Dimension getPageSize(){
+    public Dimension getPageSize() {
         CTSlideSize sz = _presentation.getSldSz();
         int cx = sz.getCx();
         int cy = sz.getCy();
-        return new Dimension((int)Units.toPoints(cx), (int)Units.toPoints(cy));
+        return new Dimension((int) Units.toPoints(cx), (int) Units.toPoints(cy));
     }
 
     @Override
-    public void setPageSize(Dimension pgSize){
+    public void setPageSize(Dimension pgSize) {
         CTSlideSize sz = CTSlideSize.Factory.newInstance();
         sz.setCx(Units.toEMU(pgSize.getWidth()));
         sz.setCy(Units.toEMU(pgSize.getHeight()));
@@ -496,16 +490,15 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
 
 
     @Internal
-    public CTPresentation getCTPresentation(){
+    public CTPresentation getCTPresentation() {
         return _presentation;
     }
 
     /**
      * Adds a picture to the workbook.
      *
-     * @param pictureData       The bytes of the picture
-     * @param format            The format of the picture.
-     *
+     * @param pictureData The bytes of the picture
+     * @param format      The format of the picture.
      * @return the picture data
      */
     @Override
@@ -518,7 +511,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
         int imageNumber = _pictures.size();
         XSLFRelation relType = XSLFPictureData.getRelationForType(format);
         if (relType == null) {
-            throw new IllegalArgumentException("Picture type "+format+" is not supported.");
+            throw new IllegalArgumentException("Picture type " + format + " is not supported.");
         }
 
         img = createRelationship(relType, XSLFFactory.getInstance(), imageNumber + 1, true).getDocumentPart();
@@ -538,15 +531,13 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     /**
      * Adds a picture to the slideshow.
      *
-     * @param is                The stream to read image from
-     * @param format              The format of the picture
-     *
+     * @param is     The stream to read image from
+     * @param format The format of the picture
      * @return the picture data
      * @since 3.15 beta 2
      */
     @Override
-    public XSLFPictureData addPicture(InputStream is, PictureType format) throws IOException
-    {
+    public XSLFPictureData addPicture(InputStream is, PictureType format) throws IOException {
         return addPicture(IOUtils.toByteArray(is), format);
     }
 
@@ -554,15 +545,13 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     /**
      * Adds a picture to the presentation.
      *
-     * @param pict             The file containing the image to add
-     * @param format           The format of the picture.
-     *
+     * @param pict   The file containing the image to add
+     * @param format The format of the picture.
      * @return the picture data
      * @since 3.15 beta 2
      */
     @Override
-    public XSLFPictureData addPicture(File pict, PictureType format) throws IOException
-    {
+    public XSLFPictureData addPicture(File pict, PictureType format) throws IOException {
         int length = (int) pict.length();
         byte[] data = IOUtils.safelyAllocate(length, MAX_RECORD_LENGTH);
         try (InputStream is = new FileInputStream(pict)) {
@@ -583,10 +572,10 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     public XSLFPictureData findPictureData(byte[] pictureData) {
         long checksum = IOUtils.calculateChecksum(pictureData);
         byte cs[] = new byte[LittleEndianConsts.LONG_SIZE];
-        LittleEndian.putLong(cs,0,checksum);
+        LittleEndian.putLong(cs, 0, checksum);
 
-        for(XSLFPictureData pic : getPictureData()){
-            if(Arrays.equals(pic.getChecksum(), cs)) {
+        for (XSLFPictureData pic : getPictureData()) {
+            if (Arrays.equals(pic.getChecksum(), cs)) {
                 return pic;
             }
         }
@@ -597,7 +586,7 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     /**
      * Scan the master slides for the first slide layout with the given name.
      *
-     * @param name  The layout name (case-insensitive). Cannot be null.
+     * @param name The layout name (case-insensitive). Cannot be null.
      * @return the first layout found or null on failure
      */
     public XSLFSlideLayout findLayout(String name) {
@@ -611,23 +600,23 @@ implements SlideShow<XSLFShape,XSLFTextParagraph> {
     }
 
 
-    public XSLFTableStyles getTableStyles(){
+    public XSLFTableStyles getTableStyles() {
         return _tableStyles;
     }
 
     CTTextParagraphProperties getDefaultParagraphStyle(int level) {
         XmlObject[] o = _presentation.selectPath(
                 "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
-                "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
-                ".//p:defaultTextStyle/a:lvl" +(level+1)+ "pPr");
-        if(o.length == 1){
-            return (CTTextParagraphProperties)o[0];
+                        "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
+                        ".//p:defaultTextStyle/a:lvl" + (level + 1) + "pPr");
+        if (o.length == 1) {
+            return (CTTextParagraphProperties) o[0];
         }
         return null;
     }
 
     @Override
-    public MasterSheet<XSLFShape,XSLFTextParagraph> createMasterSheet() throws IOException {
+    public MasterSheet<XSLFShape, XSLFTextParagraph> createMasterSheet() throws IOException {
         // TODO: implement!
         throw new UnsupportedOperationException();
     }
index 30e594df8f504f8241ec1d5d2f1fb86b2789b585..a04b61e14e2526b7c82298e1fbbc1e9ddd8a1866 100644 (file)
 
 package org.apache.poi.xslf.usermodel;
 
-import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
-
 import java.io.IOException;
-import java.io.OutputStream;
-
-import javax.xml.namespace.QName;
 
 import org.apache.poi.POIXMLDocument;
-import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.POIXMLException;
 import org.apache.poi.POIXMLRelation;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
 import org.apache.poi.openxml4j.opc.PackagePart;
-import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.util.Beta;
 import org.apache.poi.xddf.usermodel.chart.XDDFChart;
-import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
-import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
-import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace;
 import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
 
 /**
  * Represents a Chart in a .pptx presentation
- *
- *
  */
 @Beta
 public final class XSLFChart extends XDDFChart {
-    protected static final POIXMLRelation WORKBOOK_RELATIONSHIP = new POIXMLRelation(
-            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
-            POIXMLDocument.PACK_OBJECT_REL_TYPE,
-            "/ppt/embeddings/Microsoft_Excel_Worksheet#.xlsx",
-            XSSFWorkbook.class
-    ){};
-
-
-    /**
-     * Underlying workbook
-     */
-    private XSSFWorkbook workbook;
-
 
     /**
      * Construct a PresentationML chart.
@@ -81,8 +48,7 @@ public final class XSLFChart extends XDDFChart {
      * Construct a PresentationML chart from a package part.
      *
      * @param part the package part holding the chart data,
-     * the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
-     *
+     *             the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
      * @since POI 3.14-Beta1
      */
     protected XSLFChart(PackagePart part) throws IOException, XmlException {
@@ -110,118 +76,4 @@ public final class XSLFChart extends XDDFChart {
             };
         }
     }
-
-    public CellReference setSheetTitle(String title) {
-        XSSFSheet sheet = getSheet();
-        sheet.createRow(0).createCell(1).setCellValue(title);
-        return new CellReference(sheet.getSheetName(), 0, 1, true, true);
-    }
-
-    public String formatRange(CellRangeAddress range) {
-        return range.formatAsString(getSheet().getSheetName(), true);
-    }
-
-    private XSSFSheet getSheet() {
-        XSSFSheet sheet = null;
-        try {
-            sheet = getWorkbook().getSheetAt(0);
-        } catch (InvalidFormatException ife) {
-        } catch (IOException ioe) {
-        }
-        return sheet;
-    }
-
-    private PackagePart getWorksheetPart() throws InvalidFormatException {
-        for (RelationPart part : getRelationParts()) {
-            if (WORKBOOK_RELATIONSHIP.getRelation().equals(part.getRelationship().getRelationshipType())) {
-                return getTargetPart(part.getRelationship());
-            }
-        }
-        return null;
-    }
-
-    protected XSSFWorkbook getWorkbook() throws IOException, InvalidFormatException {
-        if (workbook == null) {
-            try {
-                PackagePart worksheetPart = getWorksheetPart();
-                if (worksheetPart == null) {
-                    workbook = new XSSFWorkbook();
-                    workbook.createSheet();
-                } else {
-                    workbook = new XSSFWorkbook(worksheetPart.getInputStream());
-                }
-            } catch (NotOfficeXmlFileException e) {
-                workbook = new XSSFWorkbook();
-                workbook.createSheet();
-            }
-        }
-        return workbook;
-    }
-
-    private XMLSlideShow getSlideShow() {
-        POIXMLDocumentPart p = getParent();
-        while(p != null) {
-            if(p instanceof XMLSlideShow){
-                return (XMLSlideShow)p;
-            }
-            p = p.getParent();
-        }
-        throw new IllegalStateException("SlideShow was not found");
-    }
-
-    private PackagePart createWorksheetPart() throws InvalidFormatException {
-        Integer chartIdx = XSLFRelation.CHART.getFileNameIndex(this);
-        return getTargetPart(getSlideShow().createWorkbookRelationship(this, chartIdx));
-    }
-
-    protected void saveWorkbook(XSSFWorkbook workbook) throws IOException, InvalidFormatException {
-        PackagePart worksheetPart = getWorksheetPart();
-        if (worksheetPart == null) {
-            worksheetPart = createWorksheetPart();
-        }
-        try (OutputStream xlsOut = worksheetPart.getOutputStream()) {
-            workbook.write(xlsOut);
-        }
-    }
-
-    private void fillSheet(XSSFSheet sheet, XDDFDataSource<?> categoryData, XDDFNumericalDataSource<?> valuesData) {
-        int numOfPoints = categoryData.getPointCount();
-        for (int i = 0; i < numOfPoints; i++) {
-            XSSFRow row = sheet.createRow(i + 1); // first row is for title
-            row.createCell(0).setCellValue(categoryData.getPointAt(i).toString());
-            row.createCell(1).setCellValue(valuesData.getPointAt(i).doubleValue());
-        }
-    }
-
-    @Override
-    public void plot(XDDFChartData data) {
-        super.plot(data);
-        XSSFSheet sheet = getSheet();
-        for(XDDFChartData.Series series : data.getSeries()) {
-            fillSheet(sheet, series.getCategoryData(), series.getValuesData());
-        }
-    }
-
-    public void importContent(XSLFChart other) {
-        this.chart.set(other.chart);
-    }
-
-    @Override
-    protected void commit() throws IOException {
-        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
-
-        if (workbook != null) {
-            try {
-                saveWorkbook(workbook);
-            } catch (InvalidFormatException e) {
-                throw new POIXMLException(e);
-            }
-        }
-
-        PackagePart part = getPackagePart();
-        try (OutputStream out = part.getOutputStream()) {
-            chartSpace.save(out, xmlOptions);
-        }
-    }
 }
index 54ede091339212a3f96c7cc828bebf21c3cb8a3a..77c91b62d66743f84ea0d7257e32675b8ed98761 100644 (file)
@@ -19,103 +19,105 @@ package org.apache.poi.xslf.usermodel;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLRelation;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
 import org.apache.poi.util.Beta;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 @Beta
 public class XSLFRelation extends POIXMLRelation {
 
-   /**
-    * A map to lookup POIXMLRelation by its relation type
-    */
-   private static final Map<String, XSLFRelation> _table = new HashMap<>();
-   
-   public static final XSLFRelation MAIN = new XSLFRelation(
-           "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation MACRO = new XSLFRelation(
-           "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation MACRO_TEMPLATE = new XSLFRelation(
-           "application/vnd.ms-powerpoint.template.macroEnabled.main+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation PRESENTATIONML = new XSLFRelation(
-           "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation PRESENTATIONML_TEMPLATE = new XSLFRelation(
-           "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation PRESENTATION_MACRO = new XSLFRelation(
-           "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation THEME_MANAGER = new XSLFRelation(
-           "application/vnd.openxmlformats-officedocument.themeManager+xml",
-           null, null, null
-   );
-   
-   public static final XSLFRelation NOTES = new XSLFRelation(
-           "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml",
-           "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide", 
-           "/ppt/notesSlides/notesSlide#.xml",
-           XSLFNotes.class
-   );
-   
-   public static final XSLFRelation SLIDE = new XSLFRelation(
-           "application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
-           "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide", 
-           "/ppt/slides/slide#.xml", 
-           XSLFSlide.class
-   );
-   
-   public static final XSLFRelation SLIDE_LAYOUT = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
-         "/ppt/slideLayouts/slideLayout#.xml", 
-         XSLFSlideLayout.class
-   );
-   
-   public static final XSLFRelation SLIDE_MASTER = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster",
-         "/ppt/slideMasters/slideMaster#.xml",
-         XSLFSlideMaster.class
-   );
-
-   public static final XSLFRelation NOTES_MASTER = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster",
-         "/ppt/notesMasters/notesMaster#.xml",
-         XSLFNotesMaster.class
-   );
-
-   public static final XSLFRelation COMMENTS = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.presentationml.comments+xml",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
-         "/ppt/comments/comment#.xml",
-         XSLFComments.class
-   );
-   
-   public static final XSLFRelation COMMENT_AUTHORS = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors",
-         "/ppt/commentAuthors.xml",
-         XSLFCommentAuthors.class
-   );
-   
+    /**
+     * A map to lookup POIXMLRelation by its relation type
+     */
+    private static final Map<String, XSLFRelation> _table = new HashMap<>();
+
+    public static final XSLFRelation MAIN = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation MACRO = new XSLFRelation(
+            "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation MACRO_TEMPLATE = new XSLFRelation(
+            "application/vnd.ms-powerpoint.template.macroEnabled.main+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation PRESENTATIONML = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation PRESENTATIONML_TEMPLATE = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation PRESENTATION_MACRO = new XSLFRelation(
+            "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation THEME_MANAGER = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.themeManager+xml",
+            null, null, null
+    );
+
+    public static final XSLFRelation NOTES = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide",
+            "/ppt/notesSlides/notesSlide#.xml",
+            XSLFNotes.class
+    );
+
+    public static final XSLFRelation SLIDE = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide",
+            "/ppt/slides/slide#.xml",
+            XSLFSlide.class
+    );
+
+    public static final XSLFRelation SLIDE_LAYOUT = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
+            "/ppt/slideLayouts/slideLayout#.xml",
+            XSLFSlideLayout.class
+    );
+
+    public static final XSLFRelation SLIDE_MASTER = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster",
+            "/ppt/slideMasters/slideMaster#.xml",
+            XSLFSlideMaster.class
+    );
+
+    public static final XSLFRelation NOTES_MASTER = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster",
+            "/ppt/notesMasters/notesMaster#.xml",
+            XSLFNotesMaster.class
+    );
+
+    public static final XSLFRelation COMMENTS = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.comments+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
+            "/ppt/comments/comment#.xml",
+            XSLFComments.class
+    );
+
+    public static final XSLFRelation COMMENT_AUTHORS = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors",
+            "/ppt/commentAuthors.xml",
+            XSLFCommentAuthors.class
+    );
+
     public static final XSLFRelation HYPERLINK = new XSLFRelation(
             null,
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
@@ -123,19 +125,26 @@ public class XSLFRelation extends POIXMLRelation {
             null
     );
 
-   public static final XSLFRelation THEME = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.theme+xml",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
-         "/ppt/theme/theme#.xml", 
-         XSLFTheme.class
-   );
-   
-   public static final XSLFRelation VML_DRAWING = new XSLFRelation(
-         "application/vnd.openxmlformats-officedocument.vmlDrawing",
-         "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
-         "/ppt/drawings/vmlDrawing#.vml", 
-         null
-   );
+    public static final XSLFRelation THEME = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.theme+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
+            "/ppt/theme/theme#.xml",
+            XSLFTheme.class
+    );
+
+    public static final XSLFRelation VML_DRAWING = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.vmlDrawing",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
+            "/ppt/drawings/vmlDrawing#.vml",
+            null
+    );
+
+    public static final XSLFRelation WORKBOOK_RELATIONSHIP = new XSLFRelation(
+            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+            POIXMLDocument.PACK_OBJECT_REL_TYPE,
+            "/ppt/embeddings/Microsoft_Excel_Worksheet#.xlsx",
+            XSSFWorkbook.class
+    );
 
     public static final XSLFRelation CHART = new XSLFRelation(
             "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
@@ -145,113 +154,113 @@ public class XSLFRelation extends POIXMLRelation {
     );
 
     public static final XSLFRelation IMAGE_EMF = new XSLFRelation(
-          PictureType.EMF.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.emf",
-          XSLFPictureData.class
+            PictureType.EMF.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.emf",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_WMF = new XSLFRelation(
-          PictureType.WMF.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.wmf",
-          XSLFPictureData.class
+            PictureType.WMF.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.wmf",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_PICT = new XSLFRelation(
-          PictureType.PICT.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.pict",
-          XSLFPictureData.class
+            PictureType.PICT.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.pict",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_JPEG = new XSLFRelation(
-          PictureType.JPEG.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.jpeg",
-          XSLFPictureData.class
+            PictureType.JPEG.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.jpeg",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_PNG = new XSLFRelation(
-          PictureType.PNG.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.png",
-          XSLFPictureData.class
+            PictureType.PNG.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.png",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_DIB = new XSLFRelation(
-          PictureType.DIB.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.dib",
-          XSLFPictureData.class
+            PictureType.DIB.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.dib",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_GIF = new XSLFRelation(
-          PictureType.GIF.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.gif",
-          XSLFPictureData.class
+            PictureType.GIF.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.gif",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_TIFF = new XSLFRelation(
-          PictureType.TIFF.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.tiff",
-          XSLFPictureData.class
+            PictureType.TIFF.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.tiff",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_EPS = new XSLFRelation(
-          PictureType.EPS.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.eps",
-          XSLFPictureData.class
+            PictureType.EPS.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.eps",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_BMP = new XSLFRelation(
-          PictureType.BMP.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.bmp",
-          XSLFPictureData.class
+            PictureType.BMP.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.bmp",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_WPG = new XSLFRelation(
-          PictureType.WPG.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.wpg",
-          XSLFPictureData.class
+            PictureType.WPG.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.wpg",
+            XSLFPictureData.class
     );
     public static final XSLFRelation IMAGE_WDP = new XSLFRelation(
-          PictureType.WDP.contentType,
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-          "/ppt/media/image#.wdp",
-          XSLFPictureData.class
+            PictureType.WDP.contentType,
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            "/ppt/media/image#.wdp",
+            XSLFPictureData.class
     );
 
     public static final XSLFRelation IMAGES = new XSLFRelation(
             null,
-               "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
-               null,
-               XSLFPictureData.class
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+            null,
+            XSLFPictureData.class
     );
 
     public static final XSLFRelation TABLE_STYLES = new XSLFRelation(
-          "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml",
-          "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles",
-          "/ppt/tableStyles.xml",
-          XSLFTableStyles.class
+            "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles",
+            "/ppt/tableStyles.xml",
+            XSLFTableStyles.class
     );
 
     public static final XSLFRelation OLE_OBJECT = new XSLFRelation(
-        "application/vnd.openxmlformats-officedocument.oleObject",
-        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject",
-        "/ppt/embeddings/oleObject#.bin", 
-        XSLFObjectData.class
-    );
-    
-    
-   private XSLFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
-      super(type, rel, defaultName, cls);
-      _table.put(rel, this);
-   }
-
-   /**
-    * Get POIXMLRelation by relation type
-    *
-    * @param rel relation type, for example,
-    *    <code>http://schemas.openxmlformats.org/officeDocument/2006/relationships/image</code>
-    * @return registered POIXMLRelation or null if not found
-    */
-   public static XSLFRelation getInstance(String rel){
-       return _table.get(rel);
-   }
+            "application/vnd.openxmlformats-officedocument.oleObject",
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject",
+            "/ppt/embeddings/oleObject#.bin",
+            XSLFObjectData.class
+    );
+
+
+    private XSLFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
+        super(type, rel, defaultName, cls);
+        _table.put(rel, this);
+    }
+
+    /**
+     * Get POIXMLRelation by relation type
+     *
+     * @param rel relation type, for example,
+     *            <code>http://schemas.openxmlformats.org/officeDocument/2006/relationships/image</code>
+     * @return registered POIXMLRelation or null if not found
+     */
+    public static XSLFRelation getInstance(String rel) {
+        return _table.get(rel);
+    }
 }
index 78ec93481b8d452b802be4cd470e7c7c99a345cd..6bd11e93d62539fd3cb1a22cd747034338457f9a 100644 (file)
@@ -329,6 +329,15 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
         this(openPackage(path));
     }
     
+    /**
+     * Constructs a XSSFWorkbook object using Package Part.
+     * @param part  package part
+     * @since POI 4.0.0
+     */
+    public XSSFWorkbook(PackagePart part) throws IOException {
+        this(part.getInputStream());
+    }
+    
     protected void beforeDocumentRead() {
         // Ensure it isn't a XLSB file, which we don't support
         if (getCorePart().getContentType().equals(XSSFRelation.XLSB_BINARY_WORKBOOK.getContentType())) {
index dbc68c215592646fcb4ff0fd82d47017d088ea4e..b48a3e02ceffe2b900c3ba9fdbb526e3079a75bb 100644 (file)
 
 package org.apache.poi.xwpf.usermodel;
 
-import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
-
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
-
-import javax.xml.namespace.QName;
 
 import org.apache.poi.POIXMLException;
 import org.apache.poi.openxml4j.opc.PackagePart;
@@ -31,40 +26,52 @@ import org.apache.poi.util.Beta;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xddf.usermodel.chart.XDDFChart;
 import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace;
+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
 
 /**
  * Represents a Chart in a .docx file
  */
 @Beta
 public class XWPFChart extends XDDFChart {
+    /**
+     * default width of chart in emu
+     */
+    public static final int DEFAULT_WIDTH = 500000;
+
+    /**
+     * default height of chart in emu
+     */
+    public static final int DEFAULT_HEIGHT = 500000;
 
     // lazy initialization
     private Long checksum;
 
+    /**
+     * this object is used to modify drawing properties
+     */
+    private CTInline ctInline;
+
+    /**
+     * constructor to
+     * Create a new chart in document
+     *
+     * @since POI 4.0.0
+     */
+    protected XWPFChart() {
+        super();
+    }
+
     /**
      * Construct a chart from a package part.
      *
      * @param part the package part holding the chart data,
-     * the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
-     *
+     *             the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
      * @since POI 4.0.0
      */
     protected XWPFChart(PackagePart part) throws IOException, XmlException {
         super(part);
     }
 
-    @Override
-    protected void commit() throws IOException {
-        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
-
-        try (OutputStream out = getPackagePart().getOutputStream()) {
-            chartSpace.save(out, xmlOptions);
-        }
-    }
-
     public Long getChecksum() {
         if (this.checksum == null) {
             InputStream is = null;
@@ -120,4 +127,160 @@ public class XWPFChart extends XDDFChart {
     public int hashCode() {
         return getChecksum().hashCode();
     }
+
+    /**
+     * initialize in line object
+     *
+     * @param inline this object is used to adjust the margin and dimension of chart
+     * @since POI 4.0.0
+     */
+    protected void setAttachTo(CTInline ctInline) {
+        this.ctInline = ctInline;
+    }
+
+    /**
+     * set chart height
+     *
+     * @param height height of chart
+     * @since POI 4.0.0
+     */
+    public void setChartHeight(long height) {
+        ctInline.getExtent().setCy(height);
+    }
+
+    /**
+     * set chart width
+     *
+     * @param width width of chart
+     * @since POI 4.0.0
+     */
+    public void setChartWidth(long width) {
+        ctInline.getExtent().setCx(width);
+    }
+
+    /**
+     * get chart height
+     *
+     * @since POI 4.0.0
+     */
+    public long getChartHeight() {
+        return ctInline.getExtent().getCy();
+    }
+
+    /**
+     * get chart width
+     *
+     * @since POI 4.0.0
+     */
+    public long getChartWidth() {
+        return ctInline.getExtent().getCx();
+    }
+
+    /**
+     * set chart height and width
+     *
+     * @param width  width of chart
+     * @param height height of chart
+     * @since POI 4.0.0
+     */
+    public void setChartBoundingBox(long width, long height) {
+        this.setChartWidth(width);
+        this.setChartHeight(height);
+    }
+
+    /**
+     * set margin from top
+     *
+     * @param margin margin from top
+     * @since POI 4.0.0
+     */
+    public void setChartTopMargin(long margin) {
+        ctInline.setDistT(margin);
+    }
+
+    /**
+     * get margin from Top
+     *
+     * @param margin
+     * @since POI 4.0.0
+     */
+    public long getChartTopMargin(long margin) {
+        return ctInline.getDistT();
+    }
+
+    /**
+     * set margin from bottom
+     *
+     * @param margin margin from Bottom
+     * @since POI 4.0.0
+     */
+    public void setChartBottomMargin(long margin) {
+        ctInline.setDistB(margin);
+    }
+
+    /**
+     * get margin from Bottom
+     *
+     * @param margin
+     * @since POI 4.0.0
+     */
+    public long getChartBottomMargin(long margin) {
+        return ctInline.getDistB();
+    }
+
+    /**
+     * set margin from left
+     *
+     * @param margin margin from left
+     * @since POI 4.0.0
+     */
+    public void setChartLeftMargin(long margin) {
+        ctInline.setDistL(margin);
+    }
+
+    /**
+     * get margin from left
+     *
+     * @param margin
+     * @since POI 4.0.0
+     */
+    public long getChartLeftMargin(long margin) {
+        return ctInline.getDistL();
+    }
+
+    /**
+     * set margin from Right
+     *
+     * @param margin from right
+     * @since POI 4.0.0
+     */
+    public void setChartRightMargin(long margin) {
+        ctInline.setDistR(margin);
+    }
+
+    /**
+     * get margin from Right
+     *
+     * @param margin
+     * @since POI 4.0.0
+     */
+    public long getChartRightMargin(long margin) {
+        return ctInline.getDistR();
+    }
+
+    /**
+     * set chart margin
+     *
+     * @param top    margin from top
+     * @param right  margin from right
+     * @param bottom margin from bottom
+     * @param left   margin from left
+     * @since POI 4.0.0
+     */
+    public void setChartMargin(long top, long right, long bottom, long left) {
+        this.setChartBottomMargin(bottom);
+        this.setChartRightMargin(right);
+        this.setChartLeftMargin(left);
+        this.setChartRightMargin(right);
+    }
 }
index 31412e8c8f6c6ac88274efca0e23efcc1579fce3..824bdb00f6342330f70f791bcddcfd6f410af545 100644 (file)
@@ -63,6 +63,7 @@ import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
@@ -245,7 +246,6 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
                 } else if (relation.equals(XWPFRelation.CHART.getRelation())) {
                     //now we can use all methods to modify charts in XWPFDocument
                     XWPFChart chartData = (XWPFChart) p;
-//                    chartData.onDocumentRead(); // ??? there is nothing to be done there!!!
                     charts.add(chartData);
                 } else if (relation.equals(XWPFRelation.GLOSSARY_DOCUMENT.getRelation())) {
                     // We don't currently process the glossary itself
@@ -356,6 +356,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     public List<XWPFChart> getCharts() {
         return Collections.unmodifiableList(charts);
     }
+
     /**
      * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
      */
@@ -375,7 +376,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     }
 
     public XWPFFooter getFooterArray(int pos) {
-        if(pos >=0 && pos < footers.size()) {
+        if (pos >= 0 && pos < footers.size()) {
             return footers.get(pos);
         }
         return null;
@@ -389,7 +390,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     }
 
     public XWPFHeader getHeaderArray(int pos) {
-        if(pos >=0 && pos < headers.size()) {
+        if (pos >= 0 && pos < headers.size()) {
             return headers.get(pos);
         }
         return null;
@@ -468,11 +469,12 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     public XWPFHeaderFooterPolicy getHeaderFooterPolicy() {
         return headerFooterPolicy;
     }
+
     public XWPFHeaderFooterPolicy createHeaderFooterPolicy() {
         if (headerFooterPolicy == null) {
-//            if (! ctDocument.getBody().isSetSectPr()) {
-//                ctDocument.getBody().addNewSectPr();
-//            }
+            //            if (! ctDocument.getBody().isSetSectPr()) {
+            //                ctDocument.getBody().addNewSectPr();
+            //            }
             headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
         }
         return headerFooterPolicy;
@@ -493,7 +495,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
                 CTOnOff titlePg = ctSectPr.addNewTitlePg();
                 titlePg.setVal(STOnOff.ON);
             }
-        // } else if (type == HeaderFooterType.EVEN) {
+            // } else if (type == HeaderFooterType.EVEN) {
             // TODO Add support for Even/Odd headings and footers
         }
         return hfPolicy.createHeader(STHdrFtr.Enum.forInt(type.toInt()));
@@ -515,7 +517,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
                 CTOnOff titlePg = ctSectPr.addNewTitlePg();
                 titlePg.setVal(STOnOff.ON);
             }
-        // } else if (type == HeaderFooterType.EVEN) {
+            // } else if (type == HeaderFooterType.EVEN) {
             // TODO Add support for Even/Odd headings and footers
         }
         return hfPolicy.createFooter(STHdrFtr.Enum.forInt(type.toInt()));
@@ -1014,7 +1016,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
         ctDocument.getBody().setTblArray(pos, table.getCTTbl());
     }
 
-       /**
+    /**
      * Verifies that the documentProtection tag in settings.xml file <br>
      * specifies that the protection is enforced (w:enforcement="1") <br>
      * <br>
@@ -1608,4 +1610,59 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     public XWPFDocument getXWPFDocument() {
         return this;
     }
+
+    /**
+     * This method is used to create template for chart XML
+     * no need to read MS-Word file and modify charts
+     *
+     * @return This method return object of XWPFChart Object with default height and width
+     * @throws InvalidFormatException
+     * @throws IOException
+     * @since POI 4.0.0
+     */
+    public XWPFChart createChart() throws InvalidFormatException, IOException {
+        return createChart(XWPFChart.DEFAULT_WIDTH, XWPFChart.DEFAULT_HEIGHT);
+    }
+
+    /**
+     * This method is used to create template for chart XML
+     * no need to read MS-Word file and modify charts
+     *
+     * @param width  width of chart in document
+     * @param height height of chart in document
+     * @return This method return object of XWPFChart
+     * @throws InvalidFormatException
+     * @throws IOException
+     * @since POI 4.0.0
+     */
+    public XWPFChart createChart(int width, int height) throws InvalidFormatException, IOException {
+
+        //get chart number
+        int chartNumber = getPackagePart().getPackage().
+                getPartsByContentType(XWPFRelation.CHART.getContentType()).size() + 1;
+
+        //create relationship in document for new chart
+        RelationPart rp = createRelationship(
+                XWPFRelation.CHART, XWPFFactory.getInstance(), chartNumber, false);
+
+        //get chart relationship id
+        String chartId = rp.getRelationship().getId();
+
+        //create paragraph and run object
+        XWPFRun xRun = this.createParagraph().createRun();
+
+        CTInline inline = xRun.addChart(width, height, chartId);
+
+        //get package part of xwpfchart object
+        XWPFChart xwpfChart = rp.getDocumentPart();
+
+        xwpfChart.setChartIndex(chartNumber);
+
+        //set in line object into xwpfchart object
+        xwpfChart.setAttachTo(inline);
+
+        //add chart object to chart list
+        charts.add(xwpfChart);
+        return xwpfChart;
+    }
 }
index f8da0c5042a7acd6a35f8566a303cb40e2c696b5..d0d44e398fb453a7af735a8b1fcbdc32bd9515a0 100644 (file)
@@ -20,9 +20,11 @@ package org.apache.poi.xwpf.usermodel;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.POIXMLRelation;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * @author Yegor Kozlov
@@ -112,6 +114,14 @@ public final class XWPFRelation extends POIXMLRelation {
             "/word/theme/theme#.xml",
             null
     );
+
+    public static final XWPFRelation WORKBOOK_RELATIONSHIP = new XWPFRelation(
+            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+            POIXMLDocument.PACK_OBJECT_REL_TYPE,
+            "/word/embeddings/Microsoft_Excel_Worksheet#.xlsx",
+            XSSFWorkbook.class
+    );
+
     public static final XWPFRelation CHART = new XWPFRelation(
             "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
index fdfe2cc6fa667db18653a7cc44692ce6da6e052c..9c2d79ee076c046b4f70f1c5277099b2bdf7e70a 100644 (file)
@@ -39,6 +39,8 @@ import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlString;
 import org.apache.xmlbeans.XmlToken;
 import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTRelId;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
@@ -242,9 +244,9 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
             return true;
         final STOnOff.Enum val = onoff.getVal();
         return (
-            (STOnOff.TRUE == val) ||
-            (STOnOff.X_1 == val) ||
-            (STOnOff.ON == val)
+                (STOnOff.TRUE == val) ||
+                        (STOnOff.X_1 == val) ||
+                        (STOnOff.ON == val)
         );
     }
 
@@ -256,7 +258,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
     public String getLang() {
         CTRPr pr = run.getRPr();
         Object lang = pr == null || !pr.isSetLang() ? null : pr.getLang().getVal();
-        return (String)lang;
+        return (String) lang;
     }
 
     /**
@@ -917,7 +919,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @param width       width in EMUs. To convert to / from points use {@link org.apache.poi.util.Units}
      * @param height      height in EMUs. To convert to / from points use {@link org.apache.poi.util.Units}
      * @throws InvalidFormatException If the format of the picture is not known.
-     * @throws IOException If reading the picture-data from the stream fails.
+     * @throws IOException            If reading the picture-data from the stream fails.
      * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF
      * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF
      * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT
@@ -929,12 +931,12 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
             throws InvalidFormatException, IOException {
         String relationId;
         XWPFPictureData picData;
-        
+
         // Work out what to add the picture to, then add both the
         //  picture and the relationship for it
         // TODO Should we have an interface for this sort of thing?
         if (parent.getPart() instanceof XWPFHeaderFooter) {
-            XWPFHeaderFooter headerFooter = (XWPFHeaderFooter)parent.getPart();
+            XWPFHeaderFooter headerFooter = (XWPFHeaderFooter) parent.getPart();
             relationId = headerFooter.addPictureData(pictureData, pictureType);
             picData = (XWPFPictureData) headerFooter.getRelationById(relationId);
         } else {
@@ -1025,6 +1027,62 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
         }
     }
 
+    /**
+     * this method add chart template into document
+     *
+     * @param width      set width of chart object
+     * @param height     set height of chart  object
+     * @param chartRelId relation id of chart in document relation file
+     * @throws InvalidFormatException
+     * @throws IOException
+     * @since POI 4.0.0
+     */
+    @Internal
+    public CTInline addChart(int width, int height, String chartRelId)
+            throws InvalidFormatException, IOException {
+        try {
+            CTInline inline = run.addNewDrawing().addNewInline();
+
+            //xml part of chart in document
+            String xml =
+                    "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +
+                            "<a:graphicData uri=\"" + CTChart.type.getName().getNamespaceURI() + "\">" +
+                            "<c:chart xmlns:c=\"" + CTChart.type.getName().getNamespaceURI() + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"" + chartRelId + "\" />" +
+                            "</a:graphicData>" +
+                            "</a:graphic>";
+
+            InputSource is = new InputSource(new StringReader(xml));
+
+            org.w3c.dom.Document doc = DocumentHelper.readDocument(is);
+
+            inline.set(XmlToken.Factory.parse(doc.getDocumentElement(), DEFAULT_XML_OPTIONS));
+
+            // Setup the inline with 0 margin
+            inline.setDistT(0);
+            inline.setDistR(0);
+            inline.setDistB(0);
+            inline.setDistL(0);
+
+            CTNonVisualDrawingProps docPr = inline.addNewDocPr();
+            long id = getParent().getDocument().getDrawingIdManager().reserveNew();
+            docPr.setId(id);
+            //This name is not visible in Word anywhere.
+            docPr.setName("chart " + id);
+
+            CTPositiveSize2D extent = inline.addNewExtent();
+            //set hegiht and width of drawaing object;
+            extent.setCx(width);
+            extent.setCy(height);
+
+            return inline;
+        } catch (XmlException e) {
+            throw new IllegalStateException(e);
+        } catch (SAXException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+
     /**
      * Returns the embedded pictures of the run. These
      * are pictures which reference an external,
@@ -1040,7 +1098,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
     public String toString() {
         String phonetic = getPhonetic();
         if (phonetic.length() > 0) {
-            return text() +" ("+ phonetic +")";
+            return text() + " (" + phonetic + ")";
         } else {
             return text();
         }
@@ -1071,7 +1129,6 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
     }
 
     /**
-     *
      * @return the phonetic (ruby) string associated with this run or an empty String if none exists
      */
     public String getPhonetic() {
@@ -1096,9 +1153,8 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
     }
 
     /**
-     *
-     * @param rubyObj rubyobject
-     * @param text buffer to which to append the content
+     * @param rubyObj         rubyobject
+     * @param text            buffer to which to append the content
      * @param extractPhonetic extract the phonetic (rt) component or the base component
      */
     private void handleRuby(XmlObject rubyObj, StringBuilder text, boolean extractPhonetic) {
@@ -1124,7 +1180,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
             } else {
                 if (extractPhonetic && inRT) {
                     _getText(o, text);
-                } else if (! extractPhonetic && inBase) {
+                } else if (!extractPhonetic && inBase) {
                     _getText(o, text);
                 }
             }
index cb553711607223f7e034ef50aa8170e905935fb4..719fbb9d35970bfe79ef2ae9cc73354592e96a70 100644 (file)
@@ -20,6 +20,7 @@ package org.apache.poi.xwpf.usermodel;
 import java.io.IOException;
 import java.util.List;
 
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.xddf.usermodel.chart.XDDFBarChartData;
 import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
 import org.apache.poi.xwpf.XWPFTestDataSamples;
@@ -37,8 +38,7 @@ public class TestXWPFChart extends TestCase {
     /**
      * test method to check charts are not null
      */
-    public void testRead() throws IOException
-    {
+    public void testRead() throws IOException {
         XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("61745.docx");
         List<XWPFChart> charts = sampleDoc.getCharts();
         assertNotNull(charts);
@@ -58,11 +58,10 @@ public class TestXWPFChart extends TestCase {
     /**
      * test method to add chart title and check whether it's set
      */
-    public void testChartTitle() throws IOException
-    {
+    public void testChartTitle() throws IOException {
         XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("61745.docx");
         List<XWPFChart> charts = sampleDoc.getCharts();
-        XWPFChart chart=charts.get(0);
+        XWPFChart chart = charts.get(0);
         CTChart ctChart = chart.getCTChart();
         CTTitle title = ctChart.getTitle();
         CTTx tx = title.addNewTx();
@@ -75,16 +74,42 @@ public class TestXWPFChart extends TestCase {
         r.setT("XWPF CHART");
         assertEquals("XWPF CHART", chart.getCTChart().getTitle().getTx().getRich().getPArray(0).getRArray(0).getT());
     }
+
     /**
      * test method to check relationship
      */
-    public void testChartRelation() throws IOException
-    {
+    public void testChartRelation() throws IOException {
         XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("61745.docx");
         List<XWPFChart> charts = sampleDoc.getCharts();
-        XWPFChart chart=charts.get(0);
+        XWPFChart chart = charts.get(0);
         assertEquals(XWPFRelation.CHART.getContentType(), chart.getPackagePart().getContentType());
         assertEquals("/word/document.xml", chart.getParent().getPackagePart().getPartName().getName());
         assertEquals("/word/charts/chart1.xml", chart.getPackagePart().getPartName().getName());
     }
+
+    /**
+     * test method to check adding chart in document
+     */
+    public static void testAddChartsToNewDocument() throws InvalidFormatException, IOException {
+
+        XWPFDocument document = new XWPFDocument();
+
+        XWPFChart chart = document.createChart();
+        assertEquals(1, document.getCharts().size());
+        assertNotNull(chart);
+        assertNotNull(chart.getCTChartSpace());
+        assertNotNull(chart.getCTChart());
+        assertEquals(XWPFChart.DEFAULT_HEIGHT, chart.getChartHeight());
+        assertEquals(XWPFChart.DEFAULT_WIDTH, chart.getChartWidth());
+
+        XWPFChart chart2 = document.createChart();
+        assertEquals(2, document.getCharts().size());
+        assertNotNull(chart2);
+        assertNotNull(chart2.getCTChartSpace());
+        assertNotNull(chart2.getCTChart());
+        chart.setChartHeight(500500);
+        assertEquals(500500, chart.getChartHeight());
+
+        assertNotNull(XWPFTestDataSamples.writeOutAndReadBack(document));
+    }
 }