From e04ac3122e1c32eb1a0b67f680fb6a3ed975ec18 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sat, 2 Feb 2008 17:06:14 +0000 Subject: [PATCH] usermodel support for excel hyperlinks git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@617834 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/hssf/dev/BiffViewer.java | 3 + .../poi/hssf/record/HyperlinkRecord.java | 11 +- .../apache/poi/hssf/usermodel/HSSFCell.java | 42 ++++-- .../poi/hssf/usermodel/HSSFHyperlink.java | 128 ++++++++++++++++++ .../poi/hssf/usermodel/TestHSSFCell.java | 100 ++++++-------- 5 files changed, 205 insertions(+), 79 deletions(-) create mode 100755 src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java index 2e343012d4..242a85f45f 100644 --- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java @@ -515,6 +515,9 @@ public class BiffViewer { case FileSharingRecord.sid: retval = new FileSharingRecord( in ); break; + case HyperlinkRecord.sid: + retval = new HyperlinkRecord( in ); + break; default: retval = new UnknownRecord( in ); } diff --git a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java index ec91dc3419..0dcd45a724 100644 --- a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java +++ b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java @@ -195,7 +195,7 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface field_5_unknown = new byte[16]; try { in.read(field_5_unknown); - } catch(IOException e) { throw new IllegalStateException(e); } + } catch(IOException e) { throw new IllegalStateException(e.getMessage()); } // Some sort of opts field_6_label_opts = in.readInt(); @@ -212,7 +212,7 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface field_10_unknown = new byte[16]; try { in.read(field_10_unknown); - } catch(IOException e) { throw new IllegalStateException(e); } + } catch(IOException e) { throw new IllegalStateException(e.getMessage()); } // Might need to nudge the length by one byte // This is an empirical hack! @@ -222,7 +222,8 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface } // Finally it's the URL - field_12_url = in.readUnicodeLEString(field_7_url_len); + int strlen = field_7_url_len > (in.remaining()/2) ? (in.remaining()/2) : field_7_url_len; + field_12_url = in.readUnicodeLEString(strlen); } /* (non-Javadoc) @@ -362,4 +363,8 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface this.field_12_url = url + '\u0000'; this.field_7_url_len = field_12_url.length(); } + + public int getOptions(){ + return field_11_url_opts; + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 3e24106ca7..7b6102b69d 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -34,20 +34,7 @@ import java.util.Iterator; import org.apache.poi.hssf.model.FormulaParser; import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.CommonObjectDataSubRecord; -import org.apache.poi.hssf.record.ExtendedFormatRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.ObjRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SubRecord; -import org.apache.poi.hssf.record.TextObjectRecord; -import org.apache.poi.hssf.record.UnicodeString; +import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.formula.Ptg; @@ -1068,4 +1055,31 @@ public class HSSFCell } return comment; } + + /** + * Returns hyperlink associated with this cell + * + * @return hyperlink associated with this cell or null if not found + */ + public HSSFHyperlink getHyperlink(){ + for (Iterator it = sheet.getRecords().iterator(); it.hasNext(); ) { + Record rec = ( Record ) it.next(); + if (rec instanceof HyperlinkRecord){ + HyperlinkRecord link = (HyperlinkRecord)rec; + if(link.getColumn() == record.getColumn() && link.getRow() == record.getRow()){ + return new HSSFHyperlink(link); + } + } + } + return null; + } + + /** + * Assign a hypelrink to this cell + * + * @param link hypelrink associated with this cell + */ + public void setHyperlink(HSSFHyperlink link){ + + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java new file mode 100755 index 0000000000..e1bd28af6c --- /dev/null +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java @@ -0,0 +1,128 @@ +/* ==================================================================== + 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.hssf.usermodel; + +import org.apache.poi.hssf.record.EscherAggregate; +import org.apache.poi.hssf.record.NoteRecord; +import org.apache.poi.hssf.record.TextObjectRecord; +import org.apache.poi.hssf.record.HyperlinkRecord; +import org.apache.poi.ddf.*; + +import java.util.Map; +import java.util.List; +import java.util.Iterator; + +/** + * Represents a hyperlink. + * + * @author Yegor Kozlov + */ +public class HSSFHyperlink { + + /** + * Link to a existing file or web page + */ + public static final int LINK_URL = 1; + + /** + * Link to a place in this document + */ + public static final int LINK_DOCUMENT = 2; + + /** + * Link to an E-mail address + */ + public static final int LINK_EMAIL = 3; + + /** + * Unknown type + */ + public static final int LINK_UNKNOWN = 4; + + /** + * Low-level record object that stores the actual hyperlink data + */ + private HyperlinkRecord record = null; + + protected HSSFHyperlink( HyperlinkRecord record ) + { + this.record = record; + } + + /** + * Return the row of the cell that contains the hyperlink + * + * @return the 0-based row of the cell that contains the hyperlink + */ + public int getRow(){ + return record.getRow(); + } + + /** + * Set the row of the cell that contains the hyperlink + * + * @param row the 0-based row of the cell that contains the hyperlink + */ + public void setRow(int row){ + record.setRow(row); + } + + /** + * Return the column of the cell that contains the hyperlink + * + * @return the 0-based column of the cell that contains the hyperlink + */ + public short getColumn(){ + return record.getColumn(); + } + + /** + * Set the column of the cell that contains the hyperlink + * + * @param col the 0-based column of the cell that contains the hyperlink + */ + public void setColumn(short col){ + record.setColumn(col); + } + + /** + * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, etc. + * + * @return the address of this hyperlink + */ + public String getAddress(){ + return record.getUrlString(); + } + + /** + * Return text to display for this hyperlink + * + * @return text to display + */ + public String getLabel(){ + return record.getLabel(); + } + + /** + * Return the type of this hyperlink + * + * @return the type of this hyperlink + */ + public int getType(){ + throw new RuntimeException("Not implemented"); + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java index 76f1b9fba2..80785ca182 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java @@ -303,77 +303,53 @@ extends TestCase { assertTrue("Bottom Border", (cs.getBorderBottom() == (short)1)); in.close(); - } - - public void BROKENtestWithHyperlink() throws Exception { + } + + /** + * Test reading hyperlinks + */ + public void testWithHyperlink() throws Exception { String dir = System.getProperty("HSSF.testdata.path"); File f = new File(dir, "WithHyperlink.xls"); HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(f)); - - assertEquals(3, wb.getNumberOfSheets()); - - // Find our hyperlink record, and check they're - // as we'd expect - List records = wb.getWorkbook().getHyperlinks(); - assertEquals(1, records.size()); - - HyperlinkRecord link = (HyperlinkRecord) - records.get(0); - assertNotNull(link); - - // Is in A5 - assertEquals("Foo", link.getLabel()); - assertEquals("http://poi.apache.org/", link.getUrlString()); - assertEquals(4, link.getRow()); - assertEquals(0, link.getColumn()); - - // Now check at the HSSFCell level - assertEquals(3, wb.getNumberOfSheets()); - - HSSFSheet s = wb.getSheetAt(1); - HSSFRow r = s.getRow(4); - assertNotNull(r); - HSSFCell c = r.getCell((short)0); + + HSSFSheet sheet = wb.getSheetAt(0); + HSSFCell cell = sheet.getRow(4).getCell((short)0); + HSSFHyperlink link = cell.getHyperlink(); + assertNotNull(link); + + assertEquals("Foo", link.getLabel()); + assertEquals("http://poi.apache.org/", link.getAddress()); + assertEquals(4, link.getRow()); + assertEquals(0, link.getColumn()); } - public void BROKENtestWithTwoHyperlinks() throws Exception { + /** + * Test reading hyperlinks + */ + public void testWithTwoHyperlinks() throws Exception { String dir = System.getProperty("HSSF.testdata.path"); File f = new File(dir, "WithTwoHyperLinks.xls"); HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(f)); - assertEquals(3, wb.getNumberOfSheets()); - - // Find our hyperlink record, and check they're - // as we'd expect - List records = wb.getWorkbook().getHyperlinks(); - assertEquals(2, records.size()); - - HyperlinkRecord linkA = (HyperlinkRecord) - records.get(0); - HyperlinkRecord linkB = (HyperlinkRecord) - records.get(1); - assertNotNull(linkA); - assertNotNull(linkB); - - // Is in A5 - assertEquals("Foo", linkA.getLabel()); - assertEquals("http://poi.apache.org/", linkA.getUrlString()); - assertEquals(4, linkA.getRow()); - assertEquals(0, linkA.getColumn()); - - // Is in B9 - assertEquals("Bar", linkB.getLabel()); - assertEquals("http://poi.apache.org/", linkB.getUrlString()); - assertEquals(8, linkB.getRow()); - assertEquals(1, linkB.getColumn()); - - // Now check at the HSSFCell level - assertEquals(3, wb.getNumberOfSheets()); - - HSSFSheet s = wb.getSheetAt(1); - HSSFRow r = s.getRow(4); - assertNotNull(r); - HSSFCell c = r.getCell((short)0); + HSSFSheet sheet = wb.getSheetAt(0); + + HSSFCell cell1 = sheet.getRow(4).getCell((short)0); + HSSFHyperlink link1 = cell1.getHyperlink(); + assertNotNull(link1); + assertEquals("Foo", link1.getLabel()); + assertEquals("http://poi.apache.org/", link1.getAddress()); + assertEquals(4, link1.getRow()); + assertEquals(0, link1.getColumn()); + + HSSFCell cell2 = sheet.getRow(8).getCell((short)1); + HSSFHyperlink link2 = cell2.getHyperlink(); + assertNotNull(link2); + assertEquals("Bar", link2.getLabel()); + assertEquals("http://poi.apache.org/", link2.getAddress()); + assertEquals(8, link2.getRow()); + assertEquals(1, link2.getColumn()); + } /*tests the toString() method of HSSFCell*/ -- 2.39.5