From 8ec2aaafd661f439a4fbfd3dddd66839e21a58e7 Mon Sep 17 00:00:00 2001
From: Ugo Cei
If you use a unix shell, you may find the following following + sequence of commands useful for building the files to attach.
+ -The latest release of Apache POI is 3.0.2 BETA2 which was promoted to "Beta" on 12 January 2008. It contains a mixture of
- new features and bug fixes, compared to 3.0.1. A full list of changes
- is available in
- the changelog, and
- download
+ The POI team is pleased to announce POI 3.0.2, the latest release of Apache POI.
+ There have been many important bug fixes since the 3.0.1 release and a lot of new features. A full list of changes is available in
+ the changelog, and
+ download
the source and binaries from your
- local mirror.
- The release is also available from the central Maven repository under Group ID "org.apache.poi".
+ local mirror.
+ The release is also available from the central Maven repository under Group ID "org.apache.poi" and Version "3.0.2-FINAL".
+ A property in a {@link Section} of a {@link PropertySet}. Compares two properties. Please beware that a property with ID == 0 is a special case: It does not have a type, and its value is the section's
- * dictionary. Another special case are strings: Two properties may have
- * the different types Variant.VT_LPSTR and Variant.VT_LPWSTR; Compares two properties. Please beware that a property with
+ * ID == 0 is a special case: It does not have a type, and its value is the
+ * section's dictionary. Another special case are strings: Two properties
+ * may have the different types Variant.VT_LPSTR and Variant.VT_LPWSTR; HPSF is able to read these {@link Variant} types. Checks whether HPSF supports the specified variant type. Unsupported
+ * types should be implemented included in the {@link #SUPPORTED_TYPES}
+ * array. Reads a variant type from a byte array.true
if HPFS supports this type, else
+ * false
+ */
+ public boolean isSupportedType(final int variantType)
+ {
+ for (int i = 0; i < SUPPORTED_TYPES.length; i++)
+ if (variantType == SUPPORTED_TYPES[i])
+ return true;
+ return false;
+ }
+
+
/**
* HyperlinkRecord
wraps an HLINK-record
@@ -31,146 +29,283 @@ import org.apache.poi.util.StringUtil;
* Supports only external links for now (eg http://)
*
* @author Mark Hissink Muller (in.remaining()/2) ? (in.remaining()/2) : field_7_url_len;
- field_12_url = in.readUnicodeLEString(strlen);
+
}
-
- /* (non-Javadoc)
- * @see org.apache.poi.hssf.record.Record#getSid()
- */
+
public short getSid()
{
return HyperlinkRecord.sid;
@@ -244,55 +378,75 @@ public class HyperlinkRecord extends Record implements CellValueRecordInterface
public int serialize(int offset, byte[] data)
{
- LittleEndian.putShort(data, 0 + offset, sid);
- LittleEndian.putShort(data, 2 + offset,
- ( short )(getRecordSize()-4));
- LittleEndian.putShort(data, 4 + offset, field_1_unknown);
- LittleEndian.putUShort(data, 6 + offset, field_2_row);
- LittleEndian.putShort(data, 8 + offset, field_3_column);
- LittleEndian.putShort(data, 10 + offset, field_4_xf_index);
-
- offset += 12;
- for(int i=0; isetCellValue(value.getTime())
which will
+ * automatically shift the times to the default timezone.
*
* @param value the date value to set this cell to. For formulas we'll set the
* precalculated value, for numerics we'll set its value. For othertypes we
@@ -557,7 +564,7 @@ public class HSSFCell implements Cell
*/
public void setCellValue(Calendar value)
{
- setCellValue(value.getTime());
+ setCellValue( HSSFDateUtil.getExcelDate(value, this.book.isUsing1904DateWindowing()) );
}
/**
@@ -1071,7 +1078,7 @@ public class HSSFCell implements Cell
Record rec = ( Record ) it.next();
if (rec instanceof HyperlinkRecord){
HyperlinkRecord link = (HyperlinkRecord)rec;
- if(link.getColumn() == record.getColumn() && link.getRow() == record.getRow()){
+ if(link.getFirstColumn() == record.getColumn() && link.getFirstRow() == record.getRow()){
return new HSSFHyperlink(link);
}
}
@@ -1085,6 +1092,25 @@ public class HSSFCell implements Cell
* @param link hypelrink associated with this cell
*/
public void setHyperlink(HSSFHyperlink link){
+ link.setFirstRow(record.getRow());
+ link.setLastRow(record.getRow());
+ link.setFirstColumn(record.getColumn());
+ link.setLastColumn(record.getColumn());
+ switch(link.getType()){
+ case HSSFHyperlink.LINK_EMAIL:
+ case HSSFHyperlink.LINK_URL:
+ link.setLabel("url");
+ break;
+ case HSSFHyperlink.LINK_FILE:
+ link.setLabel("file");
+ break;
+ case HSSFHyperlink.LINK_DOCUMENT:
+ link.setLabel("place");
+ break;
+ }
+
+ int eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
+ sheet.getRecords().add( eofLoc, link.record );
}
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
index a0837cdd0..6d066fc8d 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
@@ -914,4 +914,29 @@ public class HSSFCellStyle implements CellStyle
{
return format.getFillForeground();
}
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((format == null) ? 0 : format.hashCode());
+ result = prime * result + index;
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (obj instanceof HSSFCellStyle) {
+ final HSSFCellStyle other = (HSSFCellStyle) obj;
+ if (format == null) {
+ if (other.format != null)
+ return false;
+ } else if (!format.equals(other.format))
+ return false;
+ if (index != other.index)
+ return false;
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java b/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
index fb3a92df8..0e3d1ee54 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
@@ -70,9 +70,25 @@ public class HSSFDateUtil
public static double getExcelDate(Date date, boolean use1904windowing) {
Calendar calStart = new GregorianCalendar();
calStart.setTime(date); // If date includes hours, minutes, and seconds, set them to 0
-
- if ((!use1904windowing && calStart.get(Calendar.YEAR) < 1900) ||
- (use1904windowing && calStart.get(Calendar.YEAR) < 1904))
+ return internalGetExcelDate(calStart, use1904windowing);
+ }
+ /**
+ * Given a Date in the form of a Calendar, converts it into a double
+ * representing its internal Excel representation, which is the
+ * number of days since 1/1/1900. Fractional days represent hours,
+ * minutes, and seconds.
+ *
+ * @return Excel representation of Date (-1 if error - test for error by checking for less than 0.1)
+ * @param date the Calendar holding the date to convert
+ * @param use1904windowing Should 1900 or 1904 date windowing be used?
+ */
+ public static double getExcelDate(Calendar date, boolean use1904windowing) {
+ // Don't alter the supplied Calendar as we do our work
+ return internalGetExcelDate( (Calendar)date.clone(), use1904windowing );
+ }
+ private static double internalGetExcelDate(Calendar date, boolean use1904windowing) {
+ if ((!use1904windowing && date.get(Calendar.YEAR) < 1900) ||
+ (use1904windowing && date.get(Calendar.YEAR) < 1904))
{
return BAD_DATE;
} else {
@@ -83,12 +99,12 @@ public class HSSFDateUtil
// be 4 hours.
// E.g. 2004-03-28 04:00 CEST - 2004-03-28 00:00 CET is 3 hours
// and 2004-10-31 04:00 CET - 2004-10-31 00:00 CEST is 5 hours
- double fraction = (((calStart.get(Calendar.HOUR_OF_DAY) * 60
- + calStart.get(Calendar.MINUTE)
- ) * 60 + calStart.get(Calendar.SECOND)
- ) * 1000 + calStart.get(Calendar.MILLISECOND)
+ double fraction = (((date.get(Calendar.HOUR_OF_DAY) * 60
+ + date.get(Calendar.MINUTE)
+ ) * 60 + date.get(Calendar.SECOND)
+ ) * 1000 + date.get(Calendar.MILLISECOND)
) / ( double ) DAY_MILLISECONDS;
- calStart = dayStart(calStart);
+ Calendar calStart = dayStart(date);
double value = fraction + absoluteDay(calStart, use1904windowing);
@@ -208,9 +224,9 @@ public class HSSFDateUtil
// who knows what that starting bit is all about
fs = fs.replaceAll("\\[\\$\\-.*?\\]", "");
- // Otherwise, check it's only made up of:
- // y m d - / ,
- if(fs.matches("^[ymd\\-/, ]+$")) {
+ // Otherwise, check it's only made up, in any case, of:
+ // y m d h s - / , . :
+ if(fs.matches("^[yYmMdDhHsS\\-/,. :]+$")) {
return true;
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFont.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFont.java
index 5c1d4dd8c..2141c74f0 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFFont.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFont.java
@@ -306,5 +306,28 @@ public class HSSFFont implements Font
"}";
}
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((font == null) ? 0 : font.hashCode());
+ result = prime * result + index;
+ return result;
+ }
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (obj instanceof HSSFFont) {
+ final HSSFFont other = (HSSFFont) obj;
+ if (font == null) {
+ if (other.font != null)
+ return false;
+ } else if (!font.equals(other.font))
+ return false;
+ if (index != other.index)
+ return false;
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java
index e1bd28af6..7f1c2639c 100755
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java
@@ -27,9 +27,9 @@ import java.util.List;
import java.util.Iterator;
/**
- * Represents a hyperlink.
+ * Represents an Excel hyperlink.
*
- * @author Yegor Kozlov
+ * @author Yegor Kozlov (yegor at apache dot org)
*/
public class HSSFHyperlink {
@@ -49,67 +49,145 @@ public class HSSFHyperlink {
public static final int LINK_EMAIL = 3;
/**
- * Unknown type
+ * Link to a file
*/
- public static final int LINK_UNKNOWN = 4;
+ public static final int LINK_FILE = 4;
/**
* Low-level record object that stores the actual hyperlink data
*/
- private HyperlinkRecord record = null;
+ protected HyperlinkRecord record = null;
+ /**
+ * If we create a new hypelrink remember its type
+ */
+ protected int link_type;
+
+ /**
+ * Construct a new hyperlink
+ *
+ * @param type the type of hyperlink to create
+ */
+ public HSSFHyperlink( int type )
+ {
+ this.link_type = type;
+ record = new HyperlinkRecord();
+ switch(type){
+ case LINK_URL:
+ case LINK_EMAIL:
+ record.newUrlLink();
+ break;
+ case LINK_FILE:
+ record.newFileLink();
+ break;
+ case LINK_DOCUMENT:
+ record.newDocumentLink();
+ break;
+ }
+ }
+
+ /**
+ * Initialize the hyperlink by a HyperlinkRecord
record
+ *
+ * @param record
+ */
protected HSSFHyperlink( HyperlinkRecord record )
{
this.record = record;
}
/**
- * Return the row of the cell that contains the hyperlink
+ * Return the row of the first cell that contains the hyperlink
*
* @return the 0-based row of the cell that contains the hyperlink
*/
- public int getRow(){
- return record.getRow();
+ public int getFirstRow(){
+ return record.getFirstRow();
}
/**
- * Set the row of the cell that contains the hyperlink
+ * Set the row of the first cell that contains the hyperlink
*
- * @param row the 0-based row of the cell that contains the hyperlink
+ * @param row the 0-based row of the first cell that contains the hyperlink
*/
- public void setRow(int row){
- record.setRow(row);
+ public void setFirstRow(int row){
+ record.setFirstRow(row);
}
/**
- * Return the column of the cell that contains the hyperlink
+ * Return the row of the last cell that contains the hyperlink
*
- * @return the 0-based column of the cell that contains the hyperlink
+ * @return the 0-based row of the last cell that contains the hyperlink
*/
- public short getColumn(){
- return record.getColumn();
+ public int getLastRow(){
+ return record.getLastRow();
}
/**
- * Set the column of the cell that contains the hyperlink
+ * Set the row of the last cell that contains the hyperlink
*
- * @param col the 0-based column of the cell that contains the hyperlink
+ * @param row the 0-based row of the last cell that contains the hyperlink
*/
- public void setColumn(short col){
- record.setColumn(col);
+ public void setLastRow(int row){
+ record.setLastRow(row);
}
/**
- * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, etc.
+ * Return the column of the first cell that contains the hyperlink
+ *
+ * @return the 0-based column of the first cell that contains the hyperlink
+ */
+ public short getFirstColumn(){
+ return record.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){
+ record.setFirstColumn(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(){
+ return record.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){
+ record.setLastColumn(col);
+ }
+
+ /**
+ * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, patrh to a file, etc.
*
* @return the address of this hyperlink
*/
public String getAddress(){
- return record.getUrlString();
+ return record.getAddress();
}
/**
- * Return text to display for this hyperlink
+ * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, patrh to a file, etc.
+ *
+ * @param address the address of this hyperlink
+ */
+ public void setAddress(String address){
+ record.setAddress(address);
+ }
+
+ /**
+ * Return text label for this hyperlink
*
* @return text to display
*/
@@ -117,12 +195,21 @@ public class HSSFHyperlink {
return record.getLabel();
}
+ /**
+ * Sets text label for this hyperlink
+ *
+ * @param label text label for this hyperlink
+ */
+ public void setLabel(String label){
+ record.setLabel(label);
+ }
+
/**
* Return the type of this hyperlink
*
* @return the type of this hyperlink
*/
- public int getType(){
- throw new RuntimeException("Not implemented");
+ protected int getType(){
+ return link_type;
}
}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
index 3ac5ae3a5..0c9807b5a 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
@@ -471,7 +471,6 @@ public class HSSFRow
* @return cell iterator of the physically defined cells. Note element 4 may
* actually be row cell depending on how many are defined!
*/
-
public Iterator cellIterator()
{
return new CellIterator();
@@ -481,7 +480,7 @@ public class HSSFRow
* foreach loops
*/
public Iterator iterator() {
- return cellIterator();
+ return cellIterator();
}
private class CellIterator implements Iterator
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index bb1f5794f..0a64cee35 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -724,8 +724,9 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet
* foreach loops
*/
public Iterator iterator() {
- return rowIterator();
+ return rowIterator();
}
+
/**
* used internally in the API to get the low level Sheet record represented by this
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/data/ProblemExtracting.doc b/src/scratchpad/testcases/org/apache/poi/hwpf/data/ProblemExtracting.doc
new file mode 100644
index 0000000000000000000000000000000000000000..b9800894391d6e8d49abf5eac85dc6f8c497e227
GIT binary patch
literal 424448
zcmeF42VfM%*T6Rc=^aF+NGKv8Eun+--g{Nh0HG6*geodsx`2X}-kTyIO;kVxMMXfc
zqM~9~L{wD%NWS0O$L?*eLWRMV#!^xNHQJ_afFmHSkkv)WaQF_-s8o#Dl1t)|?1
zZbM7d*pz%-Ge6HWlcubpn-Wq&R|Lxz$}C&v@M5v#DWJ4XQ&Vc1nv78c=_i(zmDZCm
z+FE*^LC3(PtcA$iSr?T+Mr0*3QK_w!uC{IBbbVv0{q%1GBvsKsONP$Wb$yneXNNj#
zkoMMgvm{y3)J02@Vjt5ZA*+<0G}{pKB6cTmTY6Fyd3#dSG_3lnj%$6z5~zhy3!GSg
zoja7;iqc1{bamfeXMp;QTlL%0dC~5X*fWo1)IKlui?r)!l}c8iB0(8XuC7$hXVS?p
zQ3bn1mc*@+NlQq{oI2sZXIS>YlBKkDUvpM3{_=-PJNO&D+QalWMFNlBp4zC(+3)rI1N<~2EiB@5A$I;
ztbui~9&SLpj|V{q=m-ydA_&eN-MxEV@I0U3`DvqekJ>F8%j%Q6NA`c|bU%(3e9mhH
z;=3#3p|iVEZXPDPR>0)zSJHc>UrA{P?~&{tgx=5x`oVxc*c1$gAutSv!w9H=X)qmT
z!ZR=n=D-Hn2%BLGym#mahrY`{`u`7q@ZNjc_=AVzD8(mZwz2(^j%!5b!Ebr8cCy0@
zH}WHEquEL?H@))pI6KMvzjS&WqhQ@7r>(FZhJ6w_!&q1Wt6>Yg59i?`T!PEcp)WcD
z!(arAgbJvF#jpg{KvzP7`=LKclz)%AFSmA}Imdq`<9;v