]> source.dussan.org Git - poi.git/commitdiff
More work on XSSF Hyperlinks. Still not quite there, but mostly now. Just need to...
authorNick Burch <nick@apache.org>
Sat, 5 Apr 2008 21:43:53 +0000 (21:43 +0000)
committerNick Burch <nick@apache.org>
Sat, 5 Apr 2008 21:43:53 +0000 (21:43 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@645179 13f79535-47bb-0310-9956-ffa450edef68

14 files changed:
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java
src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java
src/ooxml/interfaces-jdk14/org/apache/poi/ss/usermodel/Cell.java
src/ooxml/interfaces-jdk14/org/apache/poi/ss/usermodel/CellStyle.java
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Cell.java
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/CreationHelper.java
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Hyperlink.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHyperlink.java [new file with mode: 0644]

index ededf0d6480192920fa9189a91414749c4a0bc8b..2a605c8a7537f058d0168f3134c26ff126295d98 100644 (file)
@@ -40,6 +40,7 @@ import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.Hyperlink;
 import org.apache.poi.ss.usermodel.RichTextString;
 
 /**
@@ -1120,7 +1121,9 @@ public class HSSFCell implements Cell
      *
      * @param link hypelrink associated with this cell
      */
-    public void setHyperlink(HSSFHyperlink link){
+    public void setHyperlink(Hyperlink hyperlink){
+       HSSFHyperlink link = (HSSFHyperlink)hyperlink;
+       
         link.setFirstRow(record.getRow());
         link.setLastRow(record.getRow());
         link.setFirstColumn(record.getColumn());
index 42d28a7281766b150fe09aeb6b0fd55873327b6b..6986ef94b5ff4ffe292e3f77ed82632a1ec43567 100644 (file)
@@ -41,9 +41,6 @@ public class HSSFCreationHelper implements CreationHelper {
                return dataFormat;
        }
        
-       public HSSFHyperlink createHyperlink(int type, Sheet sheetFor) {
-               return createHyperlink(type);
-       }
        public HSSFHyperlink createHyperlink(int type) {
                return new HSSFHyperlink(type);
        }
index 53d9298ee0654a5bbfa8d25d8cfaf15809eda1fe..3bfbf880b3603a3438b100cdc31b96f26550ecb7 100755 (executable)
@@ -130,7 +130,7 @@ public class HSSFHyperlink implements Hyperlink {
      *\r
      * @return the 0-based column of the first cell that contains the hyperlink\r
      */\r
-    public short getFirstColumn(){\r
+    public int getFirstColumn(){\r
         return record.getFirstColumn();\r
     }\r
 \r
@@ -139,8 +139,8 @@ public class HSSFHyperlink implements Hyperlink {
      *\r
      * @param col the 0-based column of the first cell that contains the hyperlink\r
      */\r
-    public void setFirstColumn(short col){\r
-        record.setFirstColumn(col);\r
+    public void setFirstColumn(int col){\r
+        record.setFirstColumn((short)col);\r
     }\r
 \r
     /**\r
@@ -148,7 +148,7 @@ public class HSSFHyperlink implements Hyperlink {
      *\r
      * @return the 0-based column of the last cell that contains the hyperlink\r
      */\r
-    public short getLastColumn(){\r
+    public int getLastColumn(){\r
         return record.getLastColumn();\r
     }\r
 \r
@@ -157,8 +157,8 @@ public class HSSFHyperlink implements Hyperlink {
      *\r
      * @param col the 0-based column of the last cell that contains the hyperlink\r
      */\r
-    public void setLastColumn(short col){\r
-        record.setLastColumn(col);\r
+    public void setLastColumn(int col){\r
+        record.setLastColumn((short)col);\r
     }\r
 \r
     /**\r
index 28b8b14ea205cdb2a7dc7dd7617d0b3b8890683a..bdee648b75f8a46a8974d615f9a5941901ec7bcf 100644 (file)
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.usermodel;
 
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 import org.apache.poi.hssf.usermodel.HSSFRichTextString;
 
 /**
@@ -80,6 +81,8 @@ public interface Cell {
     byte getErrorCellValue();
     String getCellFormula();
 
+    HSSFCellStyle getCellStyle();
+
     boolean getBooleanCellValue();
     double getNumericCellValue();
     HSSFRichTextString getRichStringCellValue();
index c23d696aefece342e3281c472a10ec4a6370c0f8..2105937fe8472f1fde4daadf4cb1b809508a5f2a 100644 (file)
@@ -17,4 +17,7 @@
 
 package org.apache.poi.ss.usermodel;
 
-public interface CellStyle {}
+public interface CellStyle {
+    short getDataFormat();
+    String getDataFormatString();
+}
index 1a250b26d8563ae698312da145d4feac2950f4af..b63f604657ef3a94f930928fddb68768453f1452 100644 (file)
@@ -20,7 +20,6 @@ package org.apache.poi.ss.usermodel;
 import java.util.Calendar;
 import java.util.Date;
 
-
 public interface Cell {
 
     /**
@@ -281,4 +280,17 @@ public interface Cell {
      */
     Comment getCellComment();
 
+    /**
+     * Returns hyperlink associated with this cell
+     *
+     * @return hyperlink associated with this cell or null if not found
+     */
+    public Hyperlink getHyperlink();
+
+    /**
+     * Assign a hypelrink to this cell
+     *
+     * @param link hypelrink associated with this cell
+     */
+    public void setHyperlink(Hyperlink link);
 }
\ No newline at end of file
index 375429c6b923ddbebae750f28f597a04d4ae4f38..f0b119f99a471d8bcceeb27449ab82cbfdd81491 100644 (file)
@@ -41,8 +41,7 @@ public interface CreationHelper {
     DataFormat createDataFormat();
     
     /**
-     * Creates a new Hyperlink, of the given type,
-     *  for the given sheet
+     * Creates a new Hyperlink, of the given type
      */
-    Hyperlink createHyperlink(int type, Sheet sheetFor);
+    Hyperlink createHyperlink(int type);
 }
\ No newline at end of file
index c207c925ad6c0aa69dc1fa39c6a3faec0a4e09ce..4fbacf338fa1bced1b2cfff463e47101e958f1e0 100644 (file)
@@ -73,28 +73,28 @@ public interface Hyperlink {
      *
      * @return the 0-based column of the first cell that contains the hyperlink
      */
-    public short getFirstColumn();
+    public int getFirstColumn();
 
     /**
      * Set the column of the first cell that contains the hyperlink
      *
      * @param col the 0-based column of the first cell that contains the hyperlink
      */
-    public void setFirstColumn(short col);
+    public void setFirstColumn(int col);
 
     /**
      * Return the column of the last cell that contains the hyperlink
      *
      * @return the 0-based column of the last cell that contains the hyperlink
      */
-    public short getLastColumn();
+    public int getLastColumn();
 
     /**
      * Set the column of the last cell that contains the hyperlink
      *
      * @param col the 0-based column of the last cell that contains the hyperlink
      */
-    public void setLastColumn(short col);
+    public void setLastColumn(int col);
 
 
     
index 31c764eb3d30e8e6f97dfa152d582f3b8017eb8a..3606415b8fdc165714405cdbfcec33059e518d81 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Comment;
+import org.apache.poi.ss.usermodel.Hyperlink;
 import org.apache.poi.ss.usermodel.RichTextString;
 import org.apache.poi.ss.usermodel.SharedStringSource;
 import org.apache.poi.ss.usermodel.StylesSource;
@@ -398,4 +399,11 @@ public class XSSFCell implements Cell {
        public RichTextString createRichTextString(String text) {
                return new XSSFRichTextString(text);
        }
+       
+       public Hyperlink getHyperlink() {
+               return row.getSheet().getHyperlink(row.getRowNum(), cellNum);
+       }
+       public void setHyperlink(Hyperlink hyperlink) {
+               row.getSheet().setCellHyperlink((XSSFHyperlink)hyperlink);
+       }
 }
index e22fe01fa0164a11f4fe7b14446d25b159293f96..771f68482f220184c52d57462d4937d7b98a4841 100644 (file)
@@ -20,7 +20,6 @@ import org.apache.poi.ss.usermodel.CreationHelper;
 import org.apache.poi.ss.usermodel.DataFormat;
 import org.apache.poi.ss.usermodel.Hyperlink;
 import org.apache.poi.ss.usermodel.RichTextString;
-import org.apache.poi.ss.usermodel.Sheet;
 
 public class XSSFCreationHelper implements CreationHelper {
        private XSSFWorkbook workbook;
@@ -43,7 +42,7 @@ public class XSSFCreationHelper implements CreationHelper {
                return dataFormat;
        }
        
-       public Hyperlink createHyperlink(int type, Sheet sheetFor) {
-               return new XSSFHyperlink(type, (XSSFSheet)sheetFor);
+       public Hyperlink createHyperlink(int type) {
+               return new XSSFHyperlink(type);
        }
 }
index feba0cf9df4bbfcf58b06c447cb5de017c2da068..2a27138a75a013474826ed4d343cc7df520759e4 100644 (file)
 ==================================================================== */
 package org.apache.poi.xssf.usermodel;
 
+import java.net.URI;
+
 import org.apache.poi.ss.usermodel.Hyperlink;
+import org.apache.poi.ss.util.CellReference;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
 
 import org.openxml4j.opc.Package;
 import org.openxml4j.opc.PackagePart;
+import org.openxml4j.opc.PackageRelationship;
+
 
 /**
  * XSSF Implementation of a Hyperlink.
@@ -29,20 +34,39 @@ import org.openxml4j.opc.PackagePart;
  */
 public class XSSFHyperlink implements Hyperlink {
        private int type;
-       private XSSFSheet sheet;
+       private PackageRelationship externalRel;
        private CTHyperlink ctHyperlink;
+       private String location;
        
-       protected XSSFHyperlink(int type, XSSFSheet sheet) {
+       protected XSSFHyperlink(int type) {
                this.type = type;
-               this.sheet = sheet;
                this.ctHyperlink = CTHyperlink.Factory.newInstance();
        }
-       protected XSSFHyperlink(CTHyperlink ctHyperlink, XSSFSheet sheet) {
-               this.sheet = sheet;
+       protected XSSFHyperlink(CTHyperlink ctHyperlink, PackageRelationship hyperlinkRel) {
                this.ctHyperlink = ctHyperlink;
+               this.externalRel = hyperlinkRel;
                
                // Figure out the Hyperlink type
-               // TODO
+               
+               // If it has a location, it's internal
+               if(ctHyperlink.getLocation() != null) {
+                       type = Hyperlink.LINK_DOCUMENT;
+                       location = ctHyperlink.getLocation();
+               } else {
+                       // Otherwise it's somehow external, check
+                       //  the relation to see how
+                       if(externalRel == null) {
+                               if(ctHyperlink.getId() != null) {
+                                       throw new IllegalStateException("The hyperlink for cell " + ctHyperlink.getRef() + " references relation " + ctHyperlink.getId() + ", but that didn't exist!");
+                               } else {
+                                       throw new IllegalStateException("A sheet hyperlink must either have a location, or a relationship. Found:\n" + ctHyperlink);
+                               }
+                       }
+                       // TODO
+                       
+                       //URI target = externalRel.getTargetURI();
+                       //location = target.toString();
+               }
        }
 
        /**
@@ -57,65 +81,80 @@ public class XSSFHyperlink implements Hyperlink {
         *  this hyperlink?
         */
        public boolean needsRelationToo() {
-               // TODO
-               return false;
+               return (type != Hyperlink.LINK_DOCUMENT);
        }
        
        /**
         * Generates the relation if required
         */
-       protected void generateRelationIfNeeded(Package pkg, PackagePart sheetPart) {
-               // TODO
+       protected void generateRelationIfNeeded(PackagePart sheetPart) {
+               if(needsRelationToo()) {
+                       // TODO
+               }
        }
        
        public int getType() {
                return type;
        }
        
+       /**
+        * Get the reference of the cell this applies to,
+        *  eg A55
+        */
+       public String getCellRef() {
+               return ctHyperlink.getRef();
+       }
+       
        public String getAddress() {
-               // TODO Auto-generated method stub
-               return null;
+               return location;
        }
        public String getLabel() {
-               // TODO Auto-generated method stub
-               return null;
+               return ctHyperlink.getDisplay();
        }
        
        public void setLabel(String label) {
-               // TODO Auto-generated method stub
+               ctHyperlink.setDisplay(label);
        }
        public void setAddress(String address) {
-               // TODO Auto-generated method stub
-               
+               location = address;
+       }
+
+       private CellReference buildCellReference() {
+               return new CellReference(ctHyperlink.getRef());
        }
        
-       public short getFirstColumn() {
-               // TODO Auto-generated method stub
-               return 0;
+       public int getFirstColumn() {
+               return buildCellReference().getCol();
        }
-       public int getFirstRow() {
-               // TODO Auto-generated method stub
-               return 0;
+       public int getLastColumn() {
+               return buildCellReference().getCol();
        }
-       public short getLastColumn() {
-               // TODO Auto-generated method stub
-               return 0;
+       
+       public int getFirstRow() {
+               return buildCellReference().getRow();
        }
        public int getLastRow() {
-               // TODO Auto-generated method stub
-               return 0;
+               return buildCellReference().getRow();
        }
        
-       public void setFirstColumn(short col) {
-               // TODO Auto-generated method stub
+       public void setFirstColumn(int col) {
+               ctHyperlink.setRef(
+                               new CellReference(
+                                               getFirstRow(), col
+                               ).formatAsString()
+               );
        }
-       public void setFirstRow(int row) {
-               // TODO Auto-generated method stub
+       public void setLastColumn(int col) {
+               setFirstColumn(col);
        }
-       public void setLastColumn(short col) {
-               // TODO Auto-generated method stub
+       public void setFirstRow(int row) {
+               ctHyperlink.setRef(
+                               new CellReference(
+                                               row, getFirstColumn()
+                               ).formatAsString()
+               );
        }
        public void setLastRow(int row) {
-               // TODO Auto-generated method stub
+               setFirstRow(row);
        }
 }
index 78c9d4e983718a6839f7a5dae8fcb0eb7c81091f..d6106ff20e7de21ba45baaf5fbfd6a42017eefff 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -30,6 +31,7 @@ import org.apache.poi.ss.usermodel.Comment;
 import org.apache.poi.ss.usermodel.CommentsSource;
 import org.apache.poi.ss.usermodel.Footer;
 import org.apache.poi.ss.usermodel.Header;
+import org.apache.poi.ss.usermodel.Hyperlink;
 import org.apache.poi.ss.usermodel.Patriarch;
 import org.apache.poi.ss.usermodel.PrintSetup;
 import org.apache.poi.ss.usermodel.Row;
@@ -38,10 +40,14 @@ import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.xssf.model.CommentsTable;
 import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
 import org.apache.xmlbeans.XmlOptions;
+import org.openxml4j.opc.PackagePart;
+import org.openxml4j.opc.PackageRelationship;
+import org.openxml4j.opc.PackageRelationshipCollection;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr;
@@ -62,6 +68,7 @@ public class XSSFSheet implements Sheet {
     protected CTWorksheet worksheet;
     protected CTDialogsheet dialogsheet;
     protected List<Row> rows;
+    protected List<XSSFHyperlink> hyperlinks;
     protected ColumnHelper columnHelper;
     protected XSSFWorkbook workbook;
     protected CommentsSource sheetComments;
@@ -90,10 +97,14 @@ public class XSSFSheet implements Sheet {
         }
         initRows(this.worksheet);
         initColumns(this.worksheet);
+        
+       hyperlinks = new ArrayList<XSSFHyperlink>();
        }
 
     public XSSFSheet(XSSFWorkbook workbook) {
         this.workbook = workbook;
+        
+        hyperlinks = new ArrayList<XSSFHyperlink>();
     }
 
     public XSSFWorkbook getWorkbook() {
@@ -105,7 +116,7 @@ public class XSSFSheet implements Sheet {
      *  will accept without a massive huff, and write into
      *  the OutputStream supplied.
      */
-    protected void save(OutputStream out, XmlOptions xmlOptions) throws IOException {
+    protected void save(PackagePart sheetPart, XmlOptions xmlOptions) throws IOException {
        // Excel objects to <cols/>
        if(worksheet.getColsArray().length == 1) {
                CTCols col = worksheet.getColsArray(0);
@@ -113,9 +124,28 @@ public class XSSFSheet implements Sheet {
                        worksheet.setColsArray(null);
                }
        }
+       
+       // Now re-generate our CTHyperlinks, if needed
+       if(hyperlinks.size() > 0) {
+               if(worksheet.getHyperlinks() == null) {
+                       worksheet.addNewHyperlinks();
+               }
+               CTHyperlink[] ctHls = new CTHyperlink[hyperlinks.size()];
+               for(int i=0; i<ctHls.length; i++) {
+                   // If our sheet has hyperlinks, have them add
+                   //  any relationships that they might need
+                       XSSFHyperlink hyperlink = hyperlinks.get(i);
+                       hyperlink.generateRelationIfNeeded(sheetPart);
+                       // Now grab their underling object
+                       ctHls[i] = hyperlink.getCTHyperlink();
+               }
+               worksheet.getHyperlinks().setHyperlinkArray(ctHls);
+       }
 
        // Save
+       OutputStream out = sheetPart.getOutputStream();
         worksheet.save(out, xmlOptions);
+        out.close();
     }
     
     protected CTWorksheet getWorksheet() {
@@ -136,7 +166,24 @@ public class XSSFSheet implements Sheet {
     protected void initColumns(CTWorksheet worksheet) {
         columnHelper = new ColumnHelper(worksheet);
     }
-
+    
+    protected void initHyperlinks(PackageRelationshipCollection hyperRels) {
+       if(worksheet.getHyperlinks() == null) return;
+       
+       // Turn each one into a XSSFHyperlink
+       for(CTHyperlink hyperlink : worksheet.getHyperlinks().getHyperlinkArray()) {
+               PackageRelationship hyperRel = null;
+               if(hyperlink.getId() != null) {
+                       hyperRel = hyperRels.getRelationshipByID(hyperlink.getId());
+               }
+               
+               // TODO: fix openxml4j
+//             hyperlinks.add(
+//                             new XSSFHyperlink(hyperlink, hyperRel)
+//             );
+       }
+    }
+    
     protected CTSheet getSheet() {
         return this.sheet;
     }
@@ -242,6 +289,16 @@ public class XSSFSheet implements Sheet {
     public Comment getCellComment(int row, int column) {
        return getComments().findCellComment(row, column);
     }
+    
+    public Hyperlink getHyperlink(int row, int column) {
+       String ref = new CellReference(row, column).formatAsString();
+       for(XSSFHyperlink hyperlink : hyperlinks) {
+               if(hyperlink.getCellRef().equals(ref)) {
+                       return hyperlink;
+               }
+       }
+       return null;
+    }
 
     public short[] getColumnBreaks() {
         CTBreak[] brkArray = getSheetTypeColumnBreaks().getBrkArray();
@@ -416,6 +473,10 @@ public class XSSFSheet implements Sheet {
         // TODO Auto-generated method stub
         return 0;
     }
+    
+    public int getNumHyperlinks() {
+       return hyperlinks.size();
+    }
 
     public boolean getObjectProtect() {
         // TODO Auto-generated method stub
@@ -871,6 +932,10 @@ public class XSSFSheet implements Sheet {
        getComments().setCellComment(cellRef, comment);
     }
     
+    public void setCellHyperlink(XSSFHyperlink hyperlink) {
+       hyperlinks.add(hyperlink);
+    }
+    
     public String getActiveCell() {
        return getSheetTypeSelection().getActiveCell();
     }
index e308a7c1a059fa0bea6bab12db4692cd41fcc5d6..72432380568d23f934bdf67d0f3497507e237417 100644 (file)
@@ -281,6 +281,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
                 WorksheetDocument worksheetDoc = WorksheetDocument.Factory.parse(part.getInputStream());
                 XSSFSheet sheet = new XSSFSheet(ctSheet, worksheetDoc.getWorksheet(), this, comments);
                 this.sheets.add(sheet);
+                
+                // Process external hyperlinks for the sheet,
+                //  if there are any
+                PackageRelationshipCollection hyperlinkRels =
+                       part.getRelationshipsByType(SHEET_HYPERLINKS.REL);
+                sheet.initHyperlinks(hyperlinkRels);
             }
         } catch (XmlException e) {
             throw new IOException(e.toString());
@@ -687,9 +693,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
                  
                 // XXX This should not be needed, but apparently the setSaveOuter call above does not work in XMLBeans 2.2
                 xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorksheet.type.getName().getNamespaceURI(), "worksheet"));
-                out = part.getOutputStream();
-                sheet.save(out, xmlOptions);
-                out.close();
+                sheet.save(part, xmlOptions);
                  
                 // Update our internal reference for the package part
                 workbook.getSheets().getSheetArray(i).setId(rel.getId());
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHyperlink.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFHyperlink.java
new file mode 100644 (file)
index 0000000..57b088d
--- /dev/null
@@ -0,0 +1,86 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xssf.usermodel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.openxml4j.opc.Package;
+
+public class TestXSSFHyperlink extends TestCase {
+    public TestXSSFHyperlink(String name) {
+               super(name);
+               
+               // Use system out logger
+           System.setProperty(
+                   "org.apache.poi.util.POILogger",
+                   "org.apache.poi.util.SystemOutLogger"
+           );
+       }
+    
+    public void testAddNew() throws Exception {
+       
+    }
+
+    public void testLoadExisting() throws Exception {
+               File xml = new File(
+                               System.getProperty("HSSF.testdata.path") +
+                               File.separator + "WithMoreVariousData.xlsx"
+               );
+               assertTrue(xml.exists());
+       
+               XSSFWorkbook workbook = new XSSFWorkbook(xml.toString());
+               assertEquals(3, workbook.getNumberOfSheets());
+               
+               XSSFSheet sheet = (XSSFSheet)workbook.getSheetAt(0);
+
+               // TODO - check hyperlinks
+               //assertEquals(4, sheet.getNumHyperlinks());
+       }
+
+    public void testLoadSave() throws Exception {
+               File xml = new File(
+                               System.getProperty("HSSF.testdata.path") +
+                               File.separator + "WithMoreVariousData.xlsx"
+               );
+               assertTrue(xml.exists());
+       
+               XSSFWorkbook workbook = new XSSFWorkbook(xml.toString());
+               assertEquals(3, workbook.getNumberOfSheets());
+
+               // TODO - check hyperlinks
+               
+               // Write out, and check
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               workbook.write(baos);
+               ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+               
+               // Load up again, check all links still there
+               XSSFWorkbook wb2 = new XSSFWorkbook(Package.open(bais));
+               assertEquals(3, wb2.getNumberOfSheets());
+               assertNotNull(wb2.getSheetAt(0));
+               assertNotNull(wb2.getSheetAt(1));
+               assertNotNull(wb2.getSheetAt(2));
+
+               // TODO
+    }
+    
+}