Ver código fonte

Changed CRLF to LF in .java base src files. Minor reformatting fixes.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@776377 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_3_5_BETA6
Josh Micich 15 anos atrás
pai
commit
6a7fc37e73
54 arquivos alterados com 6111 adições e 6112 exclusões
  1. 276
    276
      src/java/org/apache/poi/ddf/EscherPictBlip.java
  2. 82
    82
      src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java
  3. 87
    87
      src/java/org/apache/poi/hssf/record/ArrayRecord.java
  4. 132
    132
      src/java/org/apache/poi/hssf/record/CellRecord.java
  5. 109
    109
      src/java/org/apache/poi/hssf/record/HeaderFooterBase.java
  6. 57
    57
      src/java/org/apache/poi/hssf/record/StandardRecord.java
  7. 87
    87
      src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java
  8. 70
    70
      src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java
  9. 115
    115
      src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
  10. 69
    69
      src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java
  11. 257
    257
      src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java
  12. 114
    114
      src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java
  13. 64
    64
      src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java
  14. 54
    54
      src/java/org/apache/poi/hssf/record/formula/RefPtg.java
  15. 40
    40
      src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java
  16. 40
    40
      src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java
  17. 162
    162
      src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
  18. 316
    315
      src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
  19. 220
    220
      src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java
  20. 193
    194
      src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java
  21. 38
    38
      src/java/org/apache/poi/hssf/util/CellRangeAddress.java
  22. 73
    73
      src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java
  23. 74
    74
      src/java/org/apache/poi/poifs/dev/POIFSDump.java
  24. 119
    120
      src/java/org/apache/poi/ss/SpreadsheetVersion.java
  25. 77
    77
      src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java
  26. 41
    41
      src/java/org/apache/poi/ss/formula/EvaluationName.java
  27. 65
    65
      src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java
  28. 197
    197
      src/java/org/apache/poi/ss/formula/Formula.java
  29. 55
    55
      src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java
  30. 131
    131
      src/java/org/apache/poi/ss/formula/FormulaRenderer.java
  31. 40
    40
      src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java
  32. 40
    40
      src/java/org/apache/poi/ss/formula/FormulaType.java
  33. 68
    68
      src/java/org/apache/poi/ss/formula/LazyRefEval.java
  34. 48
    48
      src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java
  35. 30
    30
      src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java
  36. 36
    36
      src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java
  37. 132
    132
      src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java
  38. 129
    129
      src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java
  39. 144
    144
      src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java
  40. 133
    133
      src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java
  41. 114
    114
      src/java/org/apache/poi/ss/usermodel/CellValue.java
  42. 202
    202
      src/java/org/apache/poi/ss/usermodel/ClientAnchor.java
  43. 665
    665
      src/java/org/apache/poi/ss/usermodel/DataFormatter.java
  44. 24
    24
      src/java/org/apache/poi/ss/usermodel/Drawing.java
  45. 140
    140
      src/java/org/apache/poi/ss/usermodel/FormulaError.java
  46. 95
    95
      src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java
  47. 42
    42
      src/java/org/apache/poi/ss/usermodel/Picture.java
  48. 212
    212
      src/java/org/apache/poi/ss/usermodel/ShapeTypes.java
  49. 69
    69
      src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java
  50. 34
    34
      src/java/org/apache/poi/util/DelayableLittleEndianOutput.java
  51. 34
    34
      src/java/org/apache/poi/util/LittleEndianInput.java
  52. 144
    144
      src/java/org/apache/poi/util/LittleEndianInputStream.java
  53. 31
    31
      src/java/org/apache/poi/util/LittleEndianOutput.java
  54. 91
    91
      src/java/org/apache/poi/util/LittleEndianOutputStream.java

+ 276
- 276
src/java/org/apache/poi/ddf/EscherPictBlip.java Ver arquivo

@@ -1,276 +1,276 @@
/*
* 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.ddf;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.InflaterInputStream;
/**
* @author Daniel Noll
* @version $Id$
*/
public class EscherPictBlip
extends EscherBlipRecord
{
private static final POILogger log = POILogFactory.getLogger(EscherPictBlip.class);
public static final short RECORD_ID_EMF = (short) 0xF018 + 2;
public static final short RECORD_ID_WMF = (short) 0xF018 + 3;
public static final short RECORD_ID_PICT = (short) 0xF018 + 4;
private static final int HEADER_SIZE = 8;
private byte[] field_1_UID;
private int field_2_cb;
private int field_3_rcBounds_x1;
private int field_3_rcBounds_y1;
private int field_3_rcBounds_x2;
private int field_3_rcBounds_y2;
private int field_4_ptSize_w;
private int field_4_ptSize_h;
private int field_5_cbSave;
private byte field_6_fCompression;
private byte field_7_fFilter;
private byte[] raw_pictureData;
/**
* This method deserializes the record from a byte array.
*
* @param data The byte array containing the escher record information
* @param offset The starting offset into <code>data</code>.
* @param recordFactory May be null since this is not a container record.
* @return The number of bytes read from the byte array.
*/
public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory )
{
int bytesAfterHeader = readHeader( data, offset );
int pos = offset + HEADER_SIZE;
field_1_UID = new byte[16];
System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16;
field_2_cb = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_x1 = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_y1 = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_x2 = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_y2 = LittleEndian.getInt( data, pos ); pos += 4;
field_4_ptSize_w = LittleEndian.getInt( data, pos ); pos += 4;
field_4_ptSize_h = LittleEndian.getInt( data, pos ); pos += 4;
field_5_cbSave = LittleEndian.getInt( data, pos ); pos += 4;
field_6_fCompression = data[pos]; pos++;
field_7_fFilter = data[pos]; pos++;
raw_pictureData = new byte[field_5_cbSave];
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave );
// 0 means DEFLATE compression
// 0xFE means no compression
if (field_6_fCompression == 0)
{
field_pictureData = inflatePictureData(raw_pictureData);
}
else
{
field_pictureData = raw_pictureData;
}
return bytesAfterHeader + HEADER_SIZE;
}
/**
* Serializes the record to an existing byte array.
*
* @param offset the offset within the byte array
* @param data the data array to serialize to
* @param listener a listener for begin and end serialization events. This
* is useful because the serialization is
* hierarchical/recursive and sometimes you need to be able
* break into that.
* @return the number of bytes written.
*/
public int serialize( int offset, byte[] data, EscherSerializationListener listener )
{
listener.beforeRecordSerialize(offset, getRecordId(), this);
int pos = offset;
LittleEndian.putShort( data, pos, getOptions() ); pos += 2;
LittleEndian.putShort( data, pos, getRecordId() ); pos += 2;
LittleEndian.putInt( data, getRecordSize() - HEADER_SIZE ); pos += 4;
System.arraycopy( field_1_UID, 0, data, pos, 16 ); pos += 16;
LittleEndian.putInt( data, pos, field_2_cb ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_x1 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_y1 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_x2 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_y2 ); pos += 4;
LittleEndian.putInt( data, pos, field_4_ptSize_w ); pos += 4;
LittleEndian.putInt( data, pos, field_4_ptSize_h ); pos += 4;
LittleEndian.putInt( data, pos, field_5_cbSave ); pos += 4;
data[pos] = field_6_fCompression; pos++;
data[pos] = field_7_fFilter; pos++;
System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length );
listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this);
return HEADER_SIZE + 16 + 1 + raw_pictureData.length;
}
/**
* Decompresses the provided data, returning the inflated result.
*
* @param data the deflated picture data.
* @return the inflated picture data.
*/
private static byte[] inflatePictureData(byte[] data)
{
try
{
InflaterInputStream in = new InflaterInputStream(
new ByteArrayInputStream( data ) );
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int readBytes;
while ((readBytes = in.read(buf)) > 0)
{
out.write(buf, 0, readBytes);
}
return out.toByteArray();
}
catch ( IOException e )
{
log.log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e);
return data;
}
}
/**
* Returns the number of bytes that are required to serialize this record.
*
* @return Number of bytes
*/
public int getRecordSize()
{
return 8 + 50 + raw_pictureData.length;
}
public byte[] getUID()
{
return field_1_UID;
}
public void setUID( byte[] field_1_UID )
{
this.field_1_UID = field_1_UID;
}
public int getUncompressedSize()
{
return field_2_cb;
}
public void setUncompressedSize(int uncompressedSize)
{
field_2_cb = uncompressedSize;
}
public Rectangle getBounds()
{
return new Rectangle(field_3_rcBounds_x1,
field_3_rcBounds_y1,
field_3_rcBounds_x2 - field_3_rcBounds_x1,
field_3_rcBounds_y2 - field_3_rcBounds_y1);
}
public void setBounds(Rectangle bounds)
{
field_3_rcBounds_x1 = bounds.x;
field_3_rcBounds_y1 = bounds.y;
field_3_rcBounds_x2 = bounds.x + bounds.width;
field_3_rcBounds_y2 = bounds.y + bounds.height;
}
public Dimension getSizeEMU()
{
return new Dimension(field_4_ptSize_w, field_4_ptSize_h);
}
public void setSizeEMU(Dimension sizeEMU)
{
field_4_ptSize_w = sizeEMU.width;
field_4_ptSize_h = sizeEMU.height;
}
public int getCompressedSize()
{
return field_5_cbSave;
}
public void setCompressedSize(int compressedSize)
{
field_5_cbSave = compressedSize;
}
public boolean isCompressed()
{
return (field_6_fCompression == 0);
}
public void setCompressed(boolean compressed)
{
field_6_fCompression = compressed ? 0 : (byte)0xFE;
}
// filtering is always 254 according to available docs, so no point giving it a setter method.
public String toString()
{
String nl = System.getProperty( "line.separator" );
String extraData;
ByteArrayOutputStream b = new ByteArrayOutputStream();
try
{
HexDump.dump( this.field_pictureData, 0, b, 0 );
extraData = b.toString();
}
catch ( Exception e )
{
extraData = e.toString();
}
return getClass().getName() + ":" + nl +
" RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
" Options: 0x" + HexDump.toHex( getOptions() ) + nl +
" UID: 0x" + HexDump.toHex( field_1_UID ) + nl +
" Uncompressed Size: " + HexDump.toHex( field_2_cb ) + nl +
" Bounds: " + getBounds() + nl +
" Size in EMU: " + getSizeEMU() + nl +
" Compressed Size: " + HexDump.toHex( field_5_cbSave ) + nl +
" Compression: " + HexDump.toHex( field_6_fCompression ) + nl +
" Filter: " + HexDump.toHex( field_7_fFilter ) + nl +
" Extra Data:" + nl + extraData;
}
}
/*
* 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.ddf;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.InflaterInputStream;
/**
* @author Daniel Noll
* @version $Id$
*/
public class EscherPictBlip
extends EscherBlipRecord
{
private static final POILogger log = POILogFactory.getLogger(EscherPictBlip.class);
public static final short RECORD_ID_EMF = (short) 0xF018 + 2;
public static final short RECORD_ID_WMF = (short) 0xF018 + 3;
public static final short RECORD_ID_PICT = (short) 0xF018 + 4;
private static final int HEADER_SIZE = 8;
private byte[] field_1_UID;
private int field_2_cb;
private int field_3_rcBounds_x1;
private int field_3_rcBounds_y1;
private int field_3_rcBounds_x2;
private int field_3_rcBounds_y2;
private int field_4_ptSize_w;
private int field_4_ptSize_h;
private int field_5_cbSave;
private byte field_6_fCompression;
private byte field_7_fFilter;
private byte[] raw_pictureData;
/**
* This method deserializes the record from a byte array.
*
* @param data The byte array containing the escher record information
* @param offset The starting offset into <code>data</code>.
* @param recordFactory May be null since this is not a container record.
* @return The number of bytes read from the byte array.
*/
public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory )
{
int bytesAfterHeader = readHeader( data, offset );
int pos = offset + HEADER_SIZE;
field_1_UID = new byte[16];
System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16;
field_2_cb = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_x1 = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_y1 = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_x2 = LittleEndian.getInt( data, pos ); pos += 4;
field_3_rcBounds_y2 = LittleEndian.getInt( data, pos ); pos += 4;
field_4_ptSize_w = LittleEndian.getInt( data, pos ); pos += 4;
field_4_ptSize_h = LittleEndian.getInt( data, pos ); pos += 4;
field_5_cbSave = LittleEndian.getInt( data, pos ); pos += 4;
field_6_fCompression = data[pos]; pos++;
field_7_fFilter = data[pos]; pos++;
raw_pictureData = new byte[field_5_cbSave];
System.arraycopy( data, pos, raw_pictureData, 0, field_5_cbSave );
// 0 means DEFLATE compression
// 0xFE means no compression
if (field_6_fCompression == 0)
{
field_pictureData = inflatePictureData(raw_pictureData);
}
else
{
field_pictureData = raw_pictureData;
}
return bytesAfterHeader + HEADER_SIZE;
}
/**
* Serializes the record to an existing byte array.
*
* @param offset the offset within the byte array
* @param data the data array to serialize to
* @param listener a listener for begin and end serialization events. This
* is useful because the serialization is
* hierarchical/recursive and sometimes you need to be able
* break into that.
* @return the number of bytes written.
*/
public int serialize( int offset, byte[] data, EscherSerializationListener listener )
{
listener.beforeRecordSerialize(offset, getRecordId(), this);
int pos = offset;
LittleEndian.putShort( data, pos, getOptions() ); pos += 2;
LittleEndian.putShort( data, pos, getRecordId() ); pos += 2;
LittleEndian.putInt( data, getRecordSize() - HEADER_SIZE ); pos += 4;
System.arraycopy( field_1_UID, 0, data, pos, 16 ); pos += 16;
LittleEndian.putInt( data, pos, field_2_cb ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_x1 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_y1 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_x2 ); pos += 4;
LittleEndian.putInt( data, pos, field_3_rcBounds_y2 ); pos += 4;
LittleEndian.putInt( data, pos, field_4_ptSize_w ); pos += 4;
LittleEndian.putInt( data, pos, field_4_ptSize_h ); pos += 4;
LittleEndian.putInt( data, pos, field_5_cbSave ); pos += 4;
data[pos] = field_6_fCompression; pos++;
data[pos] = field_7_fFilter; pos++;
System.arraycopy( raw_pictureData, 0, data, pos, raw_pictureData.length );
listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this);
return HEADER_SIZE + 16 + 1 + raw_pictureData.length;
}
/**
* Decompresses the provided data, returning the inflated result.
*
* @param data the deflated picture data.
* @return the inflated picture data.
*/
private static byte[] inflatePictureData(byte[] data)
{
try
{
InflaterInputStream in = new InflaterInputStream(
new ByteArrayInputStream( data ) );
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int readBytes;
while ((readBytes = in.read(buf)) > 0)
{
out.write(buf, 0, readBytes);
}
return out.toByteArray();
}
catch ( IOException e )
{
log.log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e);
return data;
}
}
/**
* Returns the number of bytes that are required to serialize this record.
*
* @return Number of bytes
*/
public int getRecordSize()
{
return 8 + 50 + raw_pictureData.length;
}
public byte[] getUID()
{
return field_1_UID;
}
public void setUID( byte[] field_1_UID )
{
this.field_1_UID = field_1_UID;
}
public int getUncompressedSize()
{
return field_2_cb;
}
public void setUncompressedSize(int uncompressedSize)
{
field_2_cb = uncompressedSize;
}
public Rectangle getBounds()
{
return new Rectangle(field_3_rcBounds_x1,
field_3_rcBounds_y1,
field_3_rcBounds_x2 - field_3_rcBounds_x1,
field_3_rcBounds_y2 - field_3_rcBounds_y1);
}
public void setBounds(Rectangle bounds)
{
field_3_rcBounds_x1 = bounds.x;
field_3_rcBounds_y1 = bounds.y;
field_3_rcBounds_x2 = bounds.x + bounds.width;
field_3_rcBounds_y2 = bounds.y + bounds.height;
}
public Dimension getSizeEMU()
{
return new Dimension(field_4_ptSize_w, field_4_ptSize_h);
}
public void setSizeEMU(Dimension sizeEMU)
{
field_4_ptSize_w = sizeEMU.width;
field_4_ptSize_h = sizeEMU.height;
}
public int getCompressedSize()
{
return field_5_cbSave;
}
public void setCompressedSize(int compressedSize)
{
field_5_cbSave = compressedSize;
}
public boolean isCompressed()
{
return (field_6_fCompression == 0);
}
public void setCompressed(boolean compressed)
{
field_6_fCompression = compressed ? 0 : (byte)0xFE;
}
// filtering is always 254 according to available docs, so no point giving it a setter method.
public String toString()
{
String nl = System.getProperty( "line.separator" );
String extraData;
ByteArrayOutputStream b = new ByteArrayOutputStream();
try
{
HexDump.dump( this.field_pictureData, 0, b, 0 );
extraData = b.toString();
}
catch ( Exception e )
{
extraData = e.toString();
}
return getClass().getName() + ":" + nl +
" RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
" Options: 0x" + HexDump.toHex( getOptions() ) + nl +
" UID: 0x" + HexDump.toHex( field_1_UID ) + nl +
" Uncompressed Size: " + HexDump.toHex( field_2_cb ) + nl +
" Bounds: " + getBounds() + nl +
" Size in EMU: " + getSizeEMU() + nl +
" Compressed Size: " + HexDump.toHex( field_5_cbSave ) + nl +
" Compression: " + HexDump.toHex( field_6_fCompression ) + nl +
" Filter: " + HexDump.toHex( field_7_fFilter ) + nl +
" Extra Data:" + nl + extraData;
}
}

+ 82
- 82
src/java/org/apache/poi/hssf/model/HSSFFormulaParser.java Ver arquivo

@@ -1,82 +1,82 @@
/* ====================================================================
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.model;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.formula.FormulaType;
/**
* HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer}
*
* @author Josh Micich
*/
public final class HSSFFormulaParser {
private static FormulaParsingWorkbook createParsingWorkbook(HSSFWorkbook book) {
return HSSFEvaluationWorkbook.create(book);
}
private HSSFFormulaParser() {
// no instances of this class
}
/**
* Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int)}
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook) {
return parse(formula, workbook, FormulaType.CELL);
}
/**
* @param formulaType a constant from {@link FormulaType}
* @return the parsed formula tokens
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) {
return parse(formula, workbook, formulaType, -1);
}
/**
* @param formula the formula to parse
* @param workbook the parent workbook
* @param formulaType a constant from {@link FormulaType}
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
* The sheet index is required to resolve sheet-level names. <code>-1</code> means that
* the scope of the name will be ignored and the parser will match named ranges only by name
*
* @return the parsed formula tokens
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) {
return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex);
}
/**
* Static method to convert an array of {@link Ptg}s in RPN order
* to a human readable string format in infix mode.
* @param book used for defined names and 3D references
* @param ptgs must not be <code>null</code>
* @return a human readable String
*/
public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) {
return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs);
}
}
/* ====================================================================
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.model;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.formula.FormulaType;
/**
* HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer}
*
* @author Josh Micich
*/
public final class HSSFFormulaParser {
private static FormulaParsingWorkbook createParsingWorkbook(HSSFWorkbook book) {
return HSSFEvaluationWorkbook.create(book);
}
private HSSFFormulaParser() {
// no instances of this class
}
/**
* Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int)}
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook) {
return parse(formula, workbook, FormulaType.CELL);
}
/**
* @param formulaType a constant from {@link FormulaType}
* @return the parsed formula tokens
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) {
return parse(formula, workbook, formulaType, -1);
}
/**
* @param formula the formula to parse
* @param workbook the parent workbook
* @param formulaType a constant from {@link FormulaType}
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
* The sheet index is required to resolve sheet-level names. <code>-1</code> means that
* the scope of the name will be ignored and the parser will match named ranges only by name
*
* @return the parsed formula tokens
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) {
return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex);
}
/**
* Static method to convert an array of {@link Ptg}s in RPN order
* to a human readable string format in infix mode.
* @param book used for defined names and 3D references
* @param ptgs must not be <code>null</code>
* @return a human readable String
*/
public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) {
return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs);
}
}

+ 87
- 87
src/java/org/apache/poi/hssf/record/ArrayRecord.java Ver arquivo

@@ -1,87 +1,87 @@
/* ====================================================================
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.record;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;
/**
* ARRAY (0x0221)<p/>
*
* Treated in a similar way to SharedFormulaRecord
*
* @author Josh Micich
*/
public final class ArrayRecord extends SharedValueRecordBase {
public final static short sid = 0x0221;
private static final int OPT_ALWAYS_RECALCULATE = 0x0001;
private static final int OPT_CALCULATE_ON_OPEN = 0x0002;
private int _options;
private int _field3notUsed;
private Formula _formula;
public ArrayRecord(RecordInputStream in) {
super(in);
_options = in.readUShort();
_field3notUsed = in.readInt();
int formulaTokenLen = in.readUShort();
int totalFormulaLen = in.available();
_formula = Formula.read(formulaTokenLen, in, totalFormulaLen);
}
public boolean isAlwaysRecalculate() {
return (_options & OPT_ALWAYS_RECALCULATE) != 0;
}
public boolean isCalculateOnOpen() {
return (_options & OPT_CALCULATE_ON_OPEN) != 0;
}
protected int getExtraDataSize() {
return 2 + 4
+ _formula.getEncodedSize();
}
protected void serializeExtraData(LittleEndianOutput out) {
out.writeShort(_options);
out.writeInt(_field3notUsed);
_formula.serialize(out);
}
public short getSid() {
return sid;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName()).append(" [ARRAY]\n");
sb.append(" range=").append(getRange().toString()).append("\n");
sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n");
sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n");
sb.append(" formula:").append("\n");
Ptg[] ptgs = _formula.getTokens();
for (int i = 0; i < ptgs.length; i++) {
Ptg ptg = ptgs[i];
sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n");
}
sb.append("]");
return sb.toString();
}
}
/* ====================================================================
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.record;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;
/**
* ARRAY (0x0221)<p/>
*
* Treated in a similar way to SharedFormulaRecord
*
* @author Josh Micich
*/
public final class ArrayRecord extends SharedValueRecordBase {
public final static short sid = 0x0221;
private static final int OPT_ALWAYS_RECALCULATE = 0x0001;
private static final int OPT_CALCULATE_ON_OPEN = 0x0002;
private int _options;
private int _field3notUsed;
private Formula _formula;
public ArrayRecord(RecordInputStream in) {
super(in);
_options = in.readUShort();
_field3notUsed = in.readInt();
int formulaTokenLen = in.readUShort();
int totalFormulaLen = in.available();
_formula = Formula.read(formulaTokenLen, in, totalFormulaLen);
}
public boolean isAlwaysRecalculate() {
return (_options & OPT_ALWAYS_RECALCULATE) != 0;
}
public boolean isCalculateOnOpen() {
return (_options & OPT_CALCULATE_ON_OPEN) != 0;
}
protected int getExtraDataSize() {
return 2 + 4
+ _formula.getEncodedSize();
}
protected void serializeExtraData(LittleEndianOutput out) {
out.writeShort(_options);
out.writeInt(_field3notUsed);
_formula.serialize(out);
}
public short getSid() {
return sid;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName()).append(" [ARRAY]\n");
sb.append(" range=").append(getRange().toString()).append("\n");
sb.append(" options=").append(HexDump.shortToHex(_options)).append("\n");
sb.append(" notUsed=").append(HexDump.intToHex(_field3notUsed)).append("\n");
sb.append(" formula:").append("\n");
Ptg[] ptgs = _formula.getTokens();
for (int i = 0; i < ptgs.length; i++) {
Ptg ptg = ptgs[i];
sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n");
}
sb.append("]");
return sb.toString();
}
}

+ 132
- 132
src/java/org/apache/poi/hssf/record/CellRecord.java Ver arquivo

@@ -1,132 +1,132 @@
/* ====================================================================
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.record;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;
/**
* Base class for all cell value records (implementors of {@link CellValueRecordInterface}).
* Subclasses are expected to manage the cell data values (of various types).
*
* @author Josh Micich
*/
public abstract class CellRecord extends StandardRecord implements CellValueRecordInterface {
private int _rowIndex;
private int _columnIndex;
private int _formatIndex;
protected CellRecord() {
// fields uninitialised
}
protected CellRecord(RecordInputStream in) {
_rowIndex = in.readUShort();
_columnIndex = in.readUShort();
_formatIndex = in.readUShort();
}
public final void setRow(int row) {
_rowIndex = row;
}
public final void setColumn(short col) {
_columnIndex = col;
}
/**
* set the index to the ExtendedFormat
*
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
* @param xf index to the XF record
*/
public final void setXFIndex(short xf) {
_formatIndex = xf;
}
public final int getRow() {
return _rowIndex;
}
public final short getColumn() {
return (short) _columnIndex;
}
/**
* get the index to the ExtendedFormat
*
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
* @return index to the XF record
*/
public final short getXFIndex() {
return (short) _formatIndex;
}
public final String toString() {
StringBuilder sb = new StringBuilder();
String recordName = getRecordName();
sb.append("[").append(recordName).append("]\n");
sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n");
sb.append(" .col = ").append(HexDump.shortToHex(getColumn())).append("\n");
sb.append(" .xfindex= ").append(HexDump.shortToHex(getXFIndex())).append("\n");
appendValueText(sb);
sb.append("\n");
sb.append("[/").append(recordName).append("]\n");
return sb.toString();
}
/**
* Append specific debug info (used by {@link #toString()} for the value
* contained in this record. Trailing new-line should not be appended
* (superclass does that).
*/
protected abstract void appendValueText(StringBuilder sb);
/**
* Gets the debug info BIFF record type name (used by {@link #toString()}.
*/
protected abstract String getRecordName();
/**
* writes out the value data for this cell record
*/
protected abstract void serializeValue(LittleEndianOutput out);
/**
* @return the size (in bytes) of the value data for this cell record
*/
protected abstract int getValueDataSize();
public final void serialize(LittleEndianOutput out) {
out.writeShort(getRow());
out.writeShort(getColumn());
out.writeShort(getXFIndex());
serializeValue(out);
}
protected final int getDataSize() {
return 6 + getValueDataSize();
}
protected final void copyBaseFields(CellRecord rec) {
rec._rowIndex = _rowIndex;
rec._columnIndex = _columnIndex;
rec._formatIndex = _formatIndex;
}
}
/* ====================================================================
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.record;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianOutput;
/**
* Base class for all cell value records (implementors of {@link CellValueRecordInterface}).
* Subclasses are expected to manage the cell data values (of various types).
*
* @author Josh Micich
*/
public abstract class CellRecord extends StandardRecord implements CellValueRecordInterface {
private int _rowIndex;
private int _columnIndex;
private int _formatIndex;
protected CellRecord() {
// fields uninitialised
}
protected CellRecord(RecordInputStream in) {
_rowIndex = in.readUShort();
_columnIndex = in.readUShort();
_formatIndex = in.readUShort();
}
public final void setRow(int row) {
_rowIndex = row;
}
public final void setColumn(short col) {
_columnIndex = col;
}
/**
* set the index to the ExtendedFormat
*
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
* @param xf index to the XF record
*/
public final void setXFIndex(short xf) {
_formatIndex = xf;
}
public final int getRow() {
return _rowIndex;
}
public final short getColumn() {
return (short) _columnIndex;
}
/**
* get the index to the ExtendedFormat
*
* @see org.apache.poi.hssf.record.ExtendedFormatRecord
* @return index to the XF record
*/
public final short getXFIndex() {
return (short) _formatIndex;
}
public final String toString() {
StringBuilder sb = new StringBuilder();
String recordName = getRecordName();
sb.append("[").append(recordName).append("]\n");
sb.append(" .row = ").append(HexDump.shortToHex(getRow())).append("\n");
sb.append(" .col = ").append(HexDump.shortToHex(getColumn())).append("\n");
sb.append(" .xfindex= ").append(HexDump.shortToHex(getXFIndex())).append("\n");
appendValueText(sb);
sb.append("\n");
sb.append("[/").append(recordName).append("]\n");
return sb.toString();
}
/**
* Append specific debug info (used by {@link #toString()} for the value
* contained in this record. Trailing new-line should not be appended
* (superclass does that).
*/
protected abstract void appendValueText(StringBuilder sb);
/**
* Gets the debug info BIFF record type name (used by {@link #toString()}.
*/
protected abstract String getRecordName();
/**
* writes out the value data for this cell record
*/
protected abstract void serializeValue(LittleEndianOutput out);
/**
* @return the size (in bytes) of the value data for this cell record
*/
protected abstract int getValueDataSize();
public final void serialize(LittleEndianOutput out) {
out.writeShort(getRow());
out.writeShort(getColumn());
out.writeShort(getXFIndex());
serializeValue(out);
}
protected final int getDataSize() {
return 6 + getValueDataSize();
}
protected final void copyBaseFields(CellRecord rec) {
rec._rowIndex = _rowIndex;
rec._columnIndex = _columnIndex;
rec._formatIndex = _formatIndex;
}
}

+ 109
- 109
src/java/org/apache/poi/hssf/record/HeaderFooterBase.java Ver arquivo

@@ -1,109 +1,109 @@
/* ====================================================================
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.record;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
/**
* Common header/footer base class
*
* @author Josh Micich
*/
abstract class HeaderFooterBase extends StandardRecord {
private boolean field_2_hasMultibyte;
private String field_3_text;
protected HeaderFooterBase(String text) {
setText(text);
}
protected HeaderFooterBase(RecordInputStream in) {
if (in.remaining() > 0) {
int field_1_footer_len = in.readShort();
field_2_hasMultibyte = in.readByte() != 0x00;
if (field_2_hasMultibyte) {
field_3_text = in.readUnicodeLEString(field_1_footer_len);
} else {
field_3_text = in.readCompressedUnicode(field_1_footer_len);
}
} else {
// Note - this is unusual: when the text is empty string, the whole record is empty (just the 4 byte BIFF header)
field_3_text = "";
}
}
/**
* set the footer string
*
* @param text string to display
*/
public final void setText(String text) {
if (text == null) {
throw new IllegalArgumentException("text must not be null");
}
field_2_hasMultibyte = StringUtil.hasMultibyte(text);
field_3_text = text;
// Check it'll fit into the space in the record
if (field_2_hasMultibyte) {
if (field_3_text.length() > 127) {
throw new IllegalArgumentException(
"Footer string too long (limit is 127 for unicode strings)");
}
} else {
if (field_3_text.length() > 255) {
throw new IllegalArgumentException(
"Footer string too long (limit is 255 for non-unicode strings)");
}
}
}
/**
* get the length of the footer string
*
* @return length of the footer string
*/
private int getTextLength() {
return field_3_text.length();
}
public final String getText() {
return field_3_text;
}
public final void serialize(LittleEndianOutput out) {
if (getTextLength() > 0) {
out.writeShort(getTextLength());
out.writeByte(field_2_hasMultibyte ? 0x01 : 0x00);
if (field_2_hasMultibyte) {
StringUtil.putUnicodeLE(field_3_text, out);
} else {
StringUtil.putCompressedUnicode(field_3_text, out);
}
}
}
protected final int getDataSize() {
if (getTextLength() < 1) {
return 0;
}
return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1);
}
}
/* ====================================================================
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.record;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
/**
* Common header/footer base class
*
* @author Josh Micich
*/
abstract class HeaderFooterBase extends StandardRecord {
private boolean field_2_hasMultibyte;
private String field_3_text;
protected HeaderFooterBase(String text) {
setText(text);
}
protected HeaderFooterBase(RecordInputStream in) {
if (in.remaining() > 0) {
int field_1_footer_len = in.readShort();
field_2_hasMultibyte = in.readByte() != 0x00;
if (field_2_hasMultibyte) {
field_3_text = in.readUnicodeLEString(field_1_footer_len);
} else {
field_3_text = in.readCompressedUnicode(field_1_footer_len);
}
} else {
// Note - this is unusual: when the text is empty string, the whole record is empty (just the 4 byte BIFF header)
field_3_text = "";
}
}
/**
* set the footer string
*
* @param text string to display
*/
public final void setText(String text) {
if (text == null) {
throw new IllegalArgumentException("text must not be null");
}
field_2_hasMultibyte = StringUtil.hasMultibyte(text);
field_3_text = text;
// Check it'll fit into the space in the record
if (field_2_hasMultibyte) {
if (field_3_text.length() > 127) {
throw new IllegalArgumentException(
"Footer string too long (limit is 127 for unicode strings)");
}
} else {
if (field_3_text.length() > 255) {
throw new IllegalArgumentException(
"Footer string too long (limit is 255 for non-unicode strings)");
}
}
}
/**
* get the length of the footer string
*
* @return length of the footer string
*/
private int getTextLength() {
return field_3_text.length();
}
public final String getText() {
return field_3_text;
}
public final void serialize(LittleEndianOutput out) {
if (getTextLength() > 0) {
out.writeShort(getTextLength());
out.writeByte(field_2_hasMultibyte ? 0x01 : 0x00);
if (field_2_hasMultibyte) {
StringUtil.putUnicodeLE(field_3_text, out);
} else {
StringUtil.putCompressedUnicode(field_3_text, out);
}
}
}
protected final int getDataSize() {
if (getTextLength() < 1) {
return 0;
}
return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1);
}
}

+ 57
- 57
src/java/org/apache/poi/hssf/record/StandardRecord.java Ver arquivo

@@ -1,57 +1,57 @@
/* ====================================================================
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.record;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianOutput;
/**
* Subclasses of this class (the majority of BIFF records) are non-continuable. This allows for
* some simplification of serialization logic
*
* @author Josh Micich
*/
public abstract class StandardRecord extends Record {
protected abstract int getDataSize();
public final int getRecordSize() {
return 4 + getDataSize();
}
@Override
public final int serialize(int offset, byte[] data) {
int dataSize = getDataSize();
int recSize = 4 + dataSize;
LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
out.writeShort(getSid());
out.writeShort(dataSize);
serialize(out);
if (out.getWriteIndex() - offset != recSize) {
throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): "
+ "Incorrect number of bytes written - expected "
+ recSize + " but got " + (out.getWriteIndex() - offset));
}
return recSize;
}
/**
* Write the data content of this BIFF record. The 'ushort sid' and 'ushort size' header fields
* have already been written by the superclass.<br/>
*
* The subclass must write the exact number of bytes as reported by {@link org.apache.poi.hssf.record.Record#getRecordSize()}}
*/
protected abstract void serialize(LittleEndianOutput out);
}
/* ====================================================================
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.record;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianOutput;
/**
* Subclasses of this class (the majority of BIFF records) are non-continuable. This allows for
* some simplification of serialization logic
*
* @author Josh Micich
*/
public abstract class StandardRecord extends Record {
protected abstract int getDataSize();
public final int getRecordSize() {
return 4 + getDataSize();
}
@Override
public final int serialize(int offset, byte[] data) {
int dataSize = getDataSize();
int recSize = 4 + dataSize;
LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
out.writeShort(getSid());
out.writeShort(dataSize);
serialize(out);
if (out.getWriteIndex() - offset != recSize) {
throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): "
+ "Incorrect number of bytes written - expected "
+ recSize + " but got " + (out.getWriteIndex() - offset));
}
return recSize;
}
/**
* Write the data content of this BIFF record. The 'ushort sid' and 'ushort size' header fields
* have already been written by the superclass.<br/>
*
* The subclass must write the exact number of bytes as reported by {@link org.apache.poi.hssf.record.Record#getRecordSize()}}
*/
protected abstract void serialize(LittleEndianOutput out);
}

+ 87
- 87
src/java/org/apache/poi/hssf/record/aggregates/ChartSubstreamRecordAggregate.java Ver arquivo

@@ -1,87 +1,87 @@
/* ====================================================================
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.record.aggregates;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordBase;
import org.apache.poi.hssf.record.UnknownRecord;
/**
* Manages the all the records associated with a chart sub-stream.<br/>
* Includes the initial {@link BOFRecord} and final {@link EOFRecord}.
*
* @author Josh Micich
*/
public final class ChartSubstreamRecordAggregate extends RecordAggregate {
private final BOFRecord _bofRec;
/**
* All the records between BOF and EOF
*/
private final List<RecordBase> _recs;
private PageSettingsBlock _psBlock;
public ChartSubstreamRecordAggregate(RecordStream rs) {
_bofRec = (BOFRecord) rs.getNext();
List<RecordBase> temp = new ArrayList<RecordBase>();
while (rs.peekNextClass() != EOFRecord.class) {
if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
if (_psBlock != null) {
if (rs.peekNextSid() == UnknownRecord.HEADER_FOOTER_089C) {
// test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls
_psBlock.addLateHeaderFooter(rs.getNext());
continue;
}
throw new IllegalStateException(
"Found more than one PageSettingsBlock in chart sub-stream");
}
_psBlock = new PageSettingsBlock(rs);
temp.add(_psBlock);
continue;
}
temp.add(rs.getNext());
}
_recs = temp;
Record eof = rs.getNext(); // no need to save EOF in field
if (!(eof instanceof EOFRecord)) {
throw new IllegalStateException("Bad chart EOF");
}
}
public void visitContainedRecords(RecordVisitor rv) {
if (_recs.isEmpty()) {
return;
}
rv.visitRecord(_bofRec);
for (int i = 0; i < _recs.size(); i++) {
RecordBase rb = _recs.get(i);
if (rb instanceof RecordAggregate) {
((RecordAggregate) rb).visitContainedRecords(rv);
} else {
rv.visitRecord((Record) rb);
}
}
rv.visitRecord(EOFRecord.instance);
}
}
/* ====================================================================
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.record.aggregates;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordBase;
import org.apache.poi.hssf.record.UnknownRecord;
/**
* Manages the all the records associated with a chart sub-stream.<br/>
* Includes the initial {@link BOFRecord} and final {@link EOFRecord}.
*
* @author Josh Micich
*/
public final class ChartSubstreamRecordAggregate extends RecordAggregate {
private final BOFRecord _bofRec;
/**
* All the records between BOF and EOF
*/
private final List<RecordBase> _recs;
private PageSettingsBlock _psBlock;
public ChartSubstreamRecordAggregate(RecordStream rs) {
_bofRec = (BOFRecord) rs.getNext();
List<RecordBase> temp = new ArrayList<RecordBase>();
while (rs.peekNextClass() != EOFRecord.class) {
if (PageSettingsBlock.isComponentRecord(rs.peekNextSid())) {
if (_psBlock != null) {
if (rs.peekNextSid() == UnknownRecord.HEADER_FOOTER_089C) {
// test samples: 45538_classic_Footer.xls, 45538_classic_Header.xls
_psBlock.addLateHeaderFooter(rs.getNext());
continue;
}
throw new IllegalStateException(
"Found more than one PageSettingsBlock in chart sub-stream");
}
_psBlock = new PageSettingsBlock(rs);
temp.add(_psBlock);
continue;
}
temp.add(rs.getNext());
}
_recs = temp;
Record eof = rs.getNext(); // no need to save EOF in field
if (!(eof instanceof EOFRecord)) {
throw new IllegalStateException("Bad chart EOF");
}
}
public void visitContainedRecords(RecordVisitor rv) {
if (_recs.isEmpty()) {
return;
}
rv.visitRecord(_bofRec);
for (int i = 0; i < _recs.size(); i++) {
RecordBase rb = _recs.get(i);
if (rb instanceof RecordAggregate) {
((RecordAggregate) rb).visitContainedRecords(rv);
} else {
rv.visitRecord((Record) rb);
}
}
rv.visitRecord(EOFRecord.instance);
}
}

+ 70
- 70
src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java Ver arquivo

@@ -1,70 +1,70 @@
/* ====================================================================
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.record.aggregates;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.DVALRecord;
import org.apache.poi.hssf.record.DVRecord;
import org.apache.poi.hssf.record.Record;
/**
* Manages the DVALRecord and DVRecords for a single sheet<br/>
* See OOO excelfileformat.pdf section 4.14
* @author Josh Micich
*/
public final class DataValidityTable extends RecordAggregate {
private final DVALRecord _headerRec;
/**
* The list of data validations for the current sheet.
* Note - this may be empty (contrary to OOO documentation)
*/
private final List _validationList;
public DataValidityTable(RecordStream rs) {
_headerRec = (DVALRecord) rs.getNext();
List temp = new ArrayList();
while (rs.peekNextClass() == DVRecord.class) {
temp.add(rs.getNext());
}
_validationList = temp;
}
public DataValidityTable() {
_headerRec = new DVALRecord();
_validationList = new ArrayList();
}
public void visitContainedRecords(RecordVisitor rv) {
if (_validationList.isEmpty()) {
return;
}
rv.visitRecord(_headerRec);
for (int i = 0; i < _validationList.size(); i++) {
rv.visitRecord((Record) _validationList.get(i));
}
}
public void addDataValidation(DVRecord dvRecord) {
_validationList.add(dvRecord);
_headerRec.setDVRecNo(_validationList.size());
}
}
/* ====================================================================
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.record.aggregates;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.DVALRecord;
import org.apache.poi.hssf.record.DVRecord;
import org.apache.poi.hssf.record.Record;
/**
* Manages the DVALRecord and DVRecords for a single sheet<br/>
* See OOO excelfileformat.pdf section 4.14
* @author Josh Micich
*/
public final class DataValidityTable extends RecordAggregate {
private final DVALRecord _headerRec;
/**
* The list of data validations for the current sheet.
* Note - this may be empty (contrary to OOO documentation)
*/
private final List _validationList;
public DataValidityTable(RecordStream rs) {
_headerRec = (DVALRecord) rs.getNext();
List temp = new ArrayList();
while (rs.peekNextClass() == DVRecord.class) {
temp.add(rs.getNext());
}
_validationList = temp;
}
public DataValidityTable() {
_headerRec = new DVALRecord();
_validationList = new ArrayList();
}
public void visitContainedRecords(RecordVisitor rv) {
if (_validationList.isEmpty()) {
return;
}
rv.visitRecord(_headerRec);
for (int i = 0; i < _validationList.size(); i++) {
rv.visitRecord((Record) _validationList.get(i));
}
}
public void addDataValidation(DVRecord dvRecord) {
_validationList.add(dvRecord);
_headerRec.setDVRecNo(_validationList.size());
}
}

+ 115
- 115
src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java Ver arquivo

@@ -1,115 +1,115 @@
/* ====================================================================
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.record.aggregates;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordBase;
/**
* <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored
* together and/or updated together. Workbook / Sheet records are typically stored in a sequential
* list, which does not provide much structure to coordinate updates.
*
* @author Josh Micich
*/
public abstract class RecordAggregate extends RecordBase {
/**
* Visit each of the atomic BIFF records contained in this {@link RecordAggregate} in the order
* that they should be written to file. Implementors may or may not return the actual
* {@link Record}s being used to manage POI's internal implementation. Callers should not
* assume either way, and therefore only attempt to modify those {@link Record}s after cloning
*/
public abstract void visitContainedRecords(RecordVisitor rv);
public final int serialize(int offset, byte[] data) {
SerializingRecordVisitor srv = new SerializingRecordVisitor(data, offset);
visitContainedRecords(srv);
return srv.countBytesWritten();
}
public int getRecordSize() {
RecordSizingVisitor rsv = new RecordSizingVisitor();
visitContainedRecords(rsv);
return rsv.getTotalSize();
}
public interface RecordVisitor {
/**
* Implementors may call non-mutating methods on Record r.
* @param r must not be <code>null</code>
*/
void visitRecord(Record r);
}
private static final class SerializingRecordVisitor implements RecordVisitor {
private final byte[] _data;
private final int _startOffset;
private int _countBytesWritten;
public SerializingRecordVisitor(byte[] data, int startOffset) {
_data = data;
_startOffset = startOffset;
_countBytesWritten = 0;
}
public int countBytesWritten() {
return _countBytesWritten;
}
public void visitRecord(Record r) {
int currentOffset = _startOffset + _countBytesWritten;
_countBytesWritten += r.serialize(currentOffset, _data);
}
}
private static final class RecordSizingVisitor implements RecordVisitor {
private int _totalSize;
public RecordSizingVisitor() {
_totalSize = 0;
}
public int getTotalSize() {
return _totalSize;
}
public void visitRecord(Record r) {
_totalSize += r.getRecordSize();
}
}
/**
* A wrapper for {@link RecordVisitor} which accumulates the sizes of all
* records visited.
*/
public static final class PositionTrackingVisitor implements RecordVisitor {
private final RecordVisitor _rv;
private int _position;
public PositionTrackingVisitor(RecordVisitor rv, int initialPosition) {
_rv = rv;
_position = initialPosition;
}
public void visitRecord(Record r) {
_position += r.getRecordSize();
_rv.visitRecord(r);
}
public void setPosition(int position) {
_position = position;
}
public int getPosition() {
return _position;
}
}
}
/* ====================================================================
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.record.aggregates;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RecordBase;
/**
* <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored
* together and/or updated together. Workbook / Sheet records are typically stored in a sequential
* list, which does not provide much structure to coordinate updates.
*
* @author Josh Micich
*/
public abstract class RecordAggregate extends RecordBase {
/**
* Visit each of the atomic BIFF records contained in this {@link RecordAggregate} in the order
* that they should be written to file. Implementors may or may not return the actual
* {@link Record}s being used to manage POI's internal implementation. Callers should not
* assume either way, and therefore only attempt to modify those {@link Record}s after cloning
*/
public abstract void visitContainedRecords(RecordVisitor rv);
public final int serialize(int offset, byte[] data) {
SerializingRecordVisitor srv = new SerializingRecordVisitor(data, offset);
visitContainedRecords(srv);
return srv.countBytesWritten();
}
public int getRecordSize() {
RecordSizingVisitor rsv = new RecordSizingVisitor();
visitContainedRecords(rsv);
return rsv.getTotalSize();
}
public interface RecordVisitor {
/**
* Implementors may call non-mutating methods on Record r.
* @param r must not be <code>null</code>
*/
void visitRecord(Record r);
}
private static final class SerializingRecordVisitor implements RecordVisitor {
private final byte[] _data;
private final int _startOffset;
private int _countBytesWritten;
public SerializingRecordVisitor(byte[] data, int startOffset) {
_data = data;
_startOffset = startOffset;
_countBytesWritten = 0;
}
public int countBytesWritten() {
return _countBytesWritten;
}
public void visitRecord(Record r) {
int currentOffset = _startOffset + _countBytesWritten;
_countBytesWritten += r.serialize(currentOffset, _data);
}
}
private static final class RecordSizingVisitor implements RecordVisitor {
private int _totalSize;
public RecordSizingVisitor() {
_totalSize = 0;
}
public int getTotalSize() {
return _totalSize;
}
public void visitRecord(Record r) {
_totalSize += r.getRecordSize();
}
}
/**
* A wrapper for {@link RecordVisitor} which accumulates the sizes of all
* records visited.
*/
public static final class PositionTrackingVisitor implements RecordVisitor {
private final RecordVisitor _rv;
private int _position;
public PositionTrackingVisitor(RecordVisitor rv, int initialPosition) {
_rv = rv;
_position = initialPosition;
}
public void visitRecord(Record r) {
_position += r.getRecordSize();
_rv.visitRecord(r);
}
public void setPosition(int position) {
_position = position;
}
public int getPosition() {
return _position;
}
}
}

+ 69
- 69
src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java Ver arquivo

@@ -1,69 +1,69 @@
/* ====================================================================
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.record.cont;
import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianOutput;
/**
* Common superclass of all records that can produce {@link ContinueRecord}s while being serialized.
*
* @author Josh Micich
*/
public abstract class ContinuableRecord extends Record {
protected ContinuableRecord() {
// no fields to initialise
}
/**
* Serializes this record's content to the supplied data output.<br/>
* The standard BIFF header (ushort sid, ushort size) has been handled by the superclass, so
* only BIFF data should be written by this method. Simple data types can be written with the
* standard {@link LittleEndianOutput} methods. Methods from {@link ContinuableRecordOutput}
* can be used to serialize strings (with {@link ContinueRecord}s being written as required).
* If necessary, implementors can explicitly start {@link ContinueRecord}s (regardless of the
* amount of remaining space).
*
* @param out a data output stream
*/
protected abstract void serialize(ContinuableRecordOutput out);
/**
* @return the total length of the encoded record(s)
* (Note - if any {@link ContinueRecord} is required, this result includes the
* size of those too)
*/
public final int getRecordSize() {
ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly();
serialize(out);
out.terminate();
return out.getTotalSize();
}
public final int serialize(int offset, byte[] data) {
LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset);
ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid());
serialize(out);
out.terminate();
return out.getTotalSize();
}
}
/* ====================================================================
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.record.cont;
import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianOutput;
/**
* Common superclass of all records that can produce {@link ContinueRecord}s while being serialized.
*
* @author Josh Micich
*/
public abstract class ContinuableRecord extends Record {
protected ContinuableRecord() {
// no fields to initialise
}
/**
* Serializes this record's content to the supplied data output.<br/>
* The standard BIFF header (ushort sid, ushort size) has been handled by the superclass, so
* only BIFF data should be written by this method. Simple data types can be written with the
* standard {@link LittleEndianOutput} methods. Methods from {@link ContinuableRecordOutput}
* can be used to serialize strings (with {@link ContinueRecord}s being written as required).
* If necessary, implementors can explicitly start {@link ContinueRecord}s (regardless of the
* amount of remaining space).
*
* @param out a data output stream
*/
protected abstract void serialize(ContinuableRecordOutput out);
/**
* @return the total length of the encoded record(s)
* (Note - if any {@link ContinueRecord} is required, this result includes the
* size of those too)
*/
public final int getRecordSize() {
ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly();
serialize(out);
out.terminate();
return out.getTotalSize();
}
public final int serialize(int offset, byte[] data) {
LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset);
ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid());
serialize(out);
out.terminate();
return out.getTotalSize();
}
}

+ 257
- 257
src/java/org/apache/poi/hssf/record/cont/ContinuableRecordOutput.java Ver arquivo

@@ -1,257 +1,257 @@
/* ====================================================================
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.record.cont;
import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.util.DelayableLittleEndianOutput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
/**
* An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s.
* This class keeps track of how much remaining space is available in the current BIFF record and
* can start new {@link ContinueRecord}s as required.
*
* @author Josh Micich
*/
public final class ContinuableRecordOutput implements LittleEndianOutput {
private final LittleEndianOutput _out;
private UnknownLengthRecordOutput _ulrOutput;
private int _totalPreviousRecordsSize;
ContinuableRecordOutput(LittleEndianOutput out, int sid) {
_ulrOutput = new UnknownLengthRecordOutput(out, sid);
_out = out;
_totalPreviousRecordsSize = 0;
}
public static ContinuableRecordOutput createForCountingOnly() {
return new ContinuableRecordOutput(NOPOutput, -777); // fake sid
}
/**
* @return total number of bytes written so far (including all BIFF headers)
*/
public int getTotalSize() {
return _totalPreviousRecordsSize + _ulrOutput.getTotalSize();
}
/**
* Terminates the last record (also updates its 'ushort size' field)
*/
void terminate() {
_ulrOutput.terminate();
}
/**
* @return number of remaining bytes of space in current record
*/
public int getAvailableSpace() {
return _ulrOutput.getAvailableSpace();
}
/**
* Terminates the current record and starts a new {@link ContinueRecord} (regardless
* of how much space is still available in the current record).
*/
public void writeContinue() {
_ulrOutput.terminate();
_totalPreviousRecordsSize += _ulrOutput.getTotalSize();
_ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid);
}
public void writeContinueIfRequired(int requiredContinuousSize) {
if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) {
writeContinue();
}
}
/**
* Writes the 'optionFlags' byte and encoded character data of a unicode string. This includes:
* <ul>
* <li>byte optionFlags</li>
* <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
* </ul>
*
* Notes:
* <ul>
* <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
* of <tt>text</tt></li>
* <li>The string options flag is never separated (by a {@link ContinueRecord}) from the
* first chunk of character data it refers to.</li>
* <li>The 'ushort length' field is assumed to have been explicitly written earlier. Hence,
* there may be an intervening {@link ContinueRecord}</li>
* </ul>
*/
public void writeStringData(String text) {
boolean is16bitEncoded = StringUtil.hasMultibyte(text);
// calculate total size of the header and first encoded char
int keepTogetherSize = 1 + 1; // ushort len, at least one character byte
int optionFlags = 0x00;
if (is16bitEncoded) {
optionFlags |= 0x01;
keepTogetherSize += 1; // one extra byte for first char
}
writeContinueIfRequired(keepTogetherSize);
writeByte(optionFlags);
writeCharacterData(text, is16bitEncoded);
}
/**
* Writes a unicode string complete with header and character data. This includes:
* <ul>
* <li>ushort length</li>
* <li>byte optionFlags</li>
* <li>ushort numberOfRichTextRuns (optional)</li>
* <li>ushort extendedDataSize (optional)</li>
* <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
* </ul>
*
* The following bits of the 'optionFlags' byte will be set as appropriate:
* <table border='1'>
* <tr><th>Mask</th><th>Description</th></tr>
* <tr><td>0x01</td><td>is16bitEncoded</td></tr>
* <tr><td>0x04</td><td>hasExtendedData</td></tr>
* <tr><td>0x08</td><td>isRichText</td></tr>
* </table>
* Notes:
* <ul>
* <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
* of <tt>text</tt></li>
* <li>The string header fields are never separated (by a {@link ContinueRecord}) from the
* first chunk of character data (i.e. the first character is always encoded in the same
* record as the string header).</li>
* </ul>
*/
public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) {
boolean is16bitEncoded = StringUtil.hasMultibyte(text);
// calculate total size of the header and first encoded char
int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte
int optionFlags = 0x00;
if (is16bitEncoded) {
optionFlags |= 0x01;
keepTogetherSize += 1; // one extra byte for first char
}
if (numberOfRichTextRuns > 0) {
optionFlags |= 0x08;
keepTogetherSize += 2;
}
if (extendedDataSize > 0) {
optionFlags |= 0x04;
keepTogetherSize += 4;
}
writeContinueIfRequired(keepTogetherSize);
writeShort(text.length());
writeByte(optionFlags);
if (numberOfRichTextRuns > 0) {
writeShort(numberOfRichTextRuns);
}
if (extendedDataSize > 0) {
writeInt(extendedDataSize);
}
writeCharacterData(text, is16bitEncoded);
}
private void writeCharacterData(String text, boolean is16bitEncoded) {
int nChars = text.length();
int i=0;
if (is16bitEncoded) {
while(true) {
int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2);
for ( ; nWritableChars > 0; nWritableChars--) {
_ulrOutput.writeShort(text.charAt(i++));
}
if (i >= nChars) {
break;
}
writeContinue();
writeByte(0x01);
}
} else {
while(true) {
int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1);
for ( ; nWritableChars > 0; nWritableChars--) {
_ulrOutput.writeByte(text.charAt(i++));
}
if (i >= nChars) {
break;
}
writeContinue();
writeByte(0x00);
}
}
}
public void write(byte[] b) {
writeContinueIfRequired(b.length);
_ulrOutput.write(b);
}
public void write(byte[] b, int offset, int len) {
writeContinueIfRequired(len);
_ulrOutput.write(b, offset, len);
}
public void writeByte(int v) {
writeContinueIfRequired(1);
_ulrOutput.writeByte(v);
}
public void writeDouble(double v) {
writeContinueIfRequired(8);
_ulrOutput.writeDouble(v);
}
public void writeInt(int v) {
writeContinueIfRequired(4);
_ulrOutput.writeInt(v);
}
public void writeLong(long v) {
writeContinueIfRequired(8);
_ulrOutput.writeLong(v);
}
public void writeShort(int v) {
writeContinueIfRequired(2);
_ulrOutput.writeShort(v);
}
/**
* Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only.
*/
private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() {
public LittleEndianOutput createDelayedOutput(int size) {
return this;
}
public void write(byte[] b) {
// does nothing
}
public void write(byte[] b, int offset, int len) {
// does nothing
}
public void writeByte(int v) {
// does nothing
}
public void writeDouble(double v) {
// does nothing
}
public void writeInt(int v) {
// does nothing
}
public void writeLong(long v) {
// does nothing
}
public void writeShort(int v) {
// does nothing
}
};
}
/* ====================================================================
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.record.cont;
import org.apache.poi.hssf.record.ContinueRecord;
import org.apache.poi.util.DelayableLittleEndianOutput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.StringUtil;
/**
* An augmented {@link LittleEndianOutput} used for serialization of {@link ContinuableRecord}s.
* This class keeps track of how much remaining space is available in the current BIFF record and
* can start new {@link ContinueRecord}s as required.
*
* @author Josh Micich
*/
public final class ContinuableRecordOutput implements LittleEndianOutput {
private final LittleEndianOutput _out;
private UnknownLengthRecordOutput _ulrOutput;
private int _totalPreviousRecordsSize;
ContinuableRecordOutput(LittleEndianOutput out, int sid) {
_ulrOutput = new UnknownLengthRecordOutput(out, sid);
_out = out;
_totalPreviousRecordsSize = 0;
}
public static ContinuableRecordOutput createForCountingOnly() {
return new ContinuableRecordOutput(NOPOutput, -777); // fake sid
}
/**
* @return total number of bytes written so far (including all BIFF headers)
*/
public int getTotalSize() {
return _totalPreviousRecordsSize + _ulrOutput.getTotalSize();
}
/**
* Terminates the last record (also updates its 'ushort size' field)
*/
void terminate() {
_ulrOutput.terminate();
}
/**
* @return number of remaining bytes of space in current record
*/
public int getAvailableSpace() {
return _ulrOutput.getAvailableSpace();
}
/**
* Terminates the current record and starts a new {@link ContinueRecord} (regardless
* of how much space is still available in the current record).
*/
public void writeContinue() {
_ulrOutput.terminate();
_totalPreviousRecordsSize += _ulrOutput.getTotalSize();
_ulrOutput = new UnknownLengthRecordOutput(_out, ContinueRecord.sid);
}
public void writeContinueIfRequired(int requiredContinuousSize) {
if (_ulrOutput.getAvailableSpace() < requiredContinuousSize) {
writeContinue();
}
}
/**
* Writes the 'optionFlags' byte and encoded character data of a unicode string. This includes:
* <ul>
* <li>byte optionFlags</li>
* <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
* </ul>
*
* Notes:
* <ul>
* <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
* of <tt>text</tt></li>
* <li>The string options flag is never separated (by a {@link ContinueRecord}) from the
* first chunk of character data it refers to.</li>
* <li>The 'ushort length' field is assumed to have been explicitly written earlier. Hence,
* there may be an intervening {@link ContinueRecord}</li>
* </ul>
*/
public void writeStringData(String text) {
boolean is16bitEncoded = StringUtil.hasMultibyte(text);
// calculate total size of the header and first encoded char
int keepTogetherSize = 1 + 1; // ushort len, at least one character byte
int optionFlags = 0x00;
if (is16bitEncoded) {
optionFlags |= 0x01;
keepTogetherSize += 1; // one extra byte for first char
}
writeContinueIfRequired(keepTogetherSize);
writeByte(optionFlags);
writeCharacterData(text, is16bitEncoded);
}
/**
* Writes a unicode string complete with header and character data. This includes:
* <ul>
* <li>ushort length</li>
* <li>byte optionFlags</li>
* <li>ushort numberOfRichTextRuns (optional)</li>
* <li>ushort extendedDataSize (optional)</li>
* <li>encoded character data (in "ISO-8859-1" or "UTF-16LE" encoding)</li>
* </ul>
*
* The following bits of the 'optionFlags' byte will be set as appropriate:
* <table border='1'>
* <tr><th>Mask</th><th>Description</th></tr>
* <tr><td>0x01</td><td>is16bitEncoded</td></tr>
* <tr><td>0x04</td><td>hasExtendedData</td></tr>
* <tr><td>0x08</td><td>isRichText</td></tr>
* </table>
* Notes:
* <ul>
* <li>The value of the 'is16bitEncoded' flag is determined by the actual character data
* of <tt>text</tt></li>
* <li>The string header fields are never separated (by a {@link ContinueRecord}) from the
* first chunk of character data (i.e. the first character is always encoded in the same
* record as the string header).</li>
* </ul>
*/
public void writeString(String text, int numberOfRichTextRuns, int extendedDataSize) {
boolean is16bitEncoded = StringUtil.hasMultibyte(text);
// calculate total size of the header and first encoded char
int keepTogetherSize = 2 + 1 + 1; // ushort len, byte optionFlags, at least one character byte
int optionFlags = 0x00;
if (is16bitEncoded) {
optionFlags |= 0x01;
keepTogetherSize += 1; // one extra byte for first char
}
if (numberOfRichTextRuns > 0) {
optionFlags |= 0x08;
keepTogetherSize += 2;
}
if (extendedDataSize > 0) {
optionFlags |= 0x04;
keepTogetherSize += 4;
}
writeContinueIfRequired(keepTogetherSize);
writeShort(text.length());
writeByte(optionFlags);
if (numberOfRichTextRuns > 0) {
writeShort(numberOfRichTextRuns);
}
if (extendedDataSize > 0) {
writeInt(extendedDataSize);
}
writeCharacterData(text, is16bitEncoded);
}
private void writeCharacterData(String text, boolean is16bitEncoded) {
int nChars = text.length();
int i=0;
if (is16bitEncoded) {
while(true) {
int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 2);
for ( ; nWritableChars > 0; nWritableChars--) {
_ulrOutput.writeShort(text.charAt(i++));
}
if (i >= nChars) {
break;
}
writeContinue();
writeByte(0x01);
}
} else {
while(true) {
int nWritableChars = Math.min(nChars-i, _ulrOutput.getAvailableSpace() / 1);
for ( ; nWritableChars > 0; nWritableChars--) {
_ulrOutput.writeByte(text.charAt(i++));
}
if (i >= nChars) {
break;
}
writeContinue();
writeByte(0x00);
}
}
}
public void write(byte[] b) {
writeContinueIfRequired(b.length);
_ulrOutput.write(b);
}
public void write(byte[] b, int offset, int len) {
writeContinueIfRequired(len);
_ulrOutput.write(b, offset, len);
}
public void writeByte(int v) {
writeContinueIfRequired(1);
_ulrOutput.writeByte(v);
}
public void writeDouble(double v) {
writeContinueIfRequired(8);
_ulrOutput.writeDouble(v);
}
public void writeInt(int v) {
writeContinueIfRequired(4);
_ulrOutput.writeInt(v);
}
public void writeLong(long v) {
writeContinueIfRequired(8);
_ulrOutput.writeLong(v);
}
public void writeShort(int v) {
writeContinueIfRequired(2);
_ulrOutput.writeShort(v);
}
/**
* Allows optimised usage of {@link ContinuableRecordOutput} for sizing purposes only.
*/
private static final LittleEndianOutput NOPOutput = new DelayableLittleEndianOutput() {
public LittleEndianOutput createDelayedOutput(int size) {
return this;
}
public void write(byte[] b) {
// does nothing
}
public void write(byte[] b, int offset, int len) {
// does nothing
}
public void writeByte(int v) {
// does nothing
}
public void writeDouble(double v) {
// does nothing
}
public void writeInt(int v) {
// does nothing
}
public void writeLong(long v) {
// does nothing
}
public void writeShort(int v) {
// does nothing
}
};
}

+ 114
- 114
src/java/org/apache/poi/hssf/record/cont/UnknownLengthRecordOutput.java Ver arquivo

@@ -1,114 +1,114 @@
/* ====================================================================
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.record.cont;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.util.DelayableLittleEndianOutput;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianOutput;
/**
* Allows the writing of BIFF records when the 'ushort size' header field is not known in advance.
* When the client is finished writing data, it calls {@link #terminate()}, at which point this
* class updates the 'ushort size' with its final value.
*
* @author Josh Micich
*/
final class UnknownLengthRecordOutput implements LittleEndianOutput {
private static final int MAX_DATA_SIZE = RecordInputStream.MAX_RECORD_DATA_SIZE;
private final LittleEndianOutput _originalOut;
/** for writing the 'ushort size' field once its value is known */
private final LittleEndianOutput _dataSizeOutput;
private final byte[] _byteBuffer;
private LittleEndianOutput _out;
private int _size;
public UnknownLengthRecordOutput(LittleEndianOutput out, int sid) {
_originalOut = out;
out.writeShort(sid);
if (out instanceof DelayableLittleEndianOutput) {
// optimisation
DelayableLittleEndianOutput dleo = (DelayableLittleEndianOutput) out;
_dataSizeOutput = dleo.createDelayedOutput(2);
_byteBuffer = null;
_out = out;
} else {
// otherwise temporarily write all subsequent data to a buffer
_dataSizeOutput = out;
_byteBuffer = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE];
_out = new LittleEndianByteArrayOutputStream(_byteBuffer, 0);
}
}
/**
* includes 4 byte header
*/
public int getTotalSize() {
return 4 + _size;
}
public int getAvailableSpace() {
if (_out == null) {
throw new IllegalStateException("Record already terminated");
}
return MAX_DATA_SIZE - _size;
}
/**
* Finishes writing the current record and updates 'ushort size' field.<br/>
* After this method is called, only {@link #getTotalSize()} may be called.
*/
public void terminate() {
if (_out == null) {
throw new IllegalStateException("Record already terminated");
}
_dataSizeOutput.writeShort(_size);
if (_byteBuffer != null) {
_originalOut.write(_byteBuffer, 0, _size);
_out = null;
return;
}
_out = null;
}
public void write(byte[] b) {
_out.write(b);
_size += b.length;
}
public void write(byte[] b, int offset, int len) {
_out.write(b, offset, len);
_size += len;
}
public void writeByte(int v) {
_out.writeByte(v);
_size += 1;
}
public void writeDouble(double v) {
_out.writeDouble(v);
_size += 8;
}
public void writeInt(int v) {
_out.writeInt(v);
_size += 4;
}
public void writeLong(long v) {
_out.writeLong(v);
_size += 8;
}
public void writeShort(int v) {
_out.writeShort(v);
_size += 2;
}
}
/* ====================================================================
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.record.cont;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.util.DelayableLittleEndianOutput;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianOutput;
/**
* Allows the writing of BIFF records when the 'ushort size' header field is not known in advance.
* When the client is finished writing data, it calls {@link #terminate()}, at which point this
* class updates the 'ushort size' with its final value.
*
* @author Josh Micich
*/
final class UnknownLengthRecordOutput implements LittleEndianOutput {
private static final int MAX_DATA_SIZE = RecordInputStream.MAX_RECORD_DATA_SIZE;
private final LittleEndianOutput _originalOut;
/** for writing the 'ushort size' field once its value is known */
private final LittleEndianOutput _dataSizeOutput;
private final byte[] _byteBuffer;
private LittleEndianOutput _out;
private int _size;
public UnknownLengthRecordOutput(LittleEndianOutput out, int sid) {
_originalOut = out;
out.writeShort(sid);
if (out instanceof DelayableLittleEndianOutput) {
// optimisation
DelayableLittleEndianOutput dleo = (DelayableLittleEndianOutput) out;
_dataSizeOutput = dleo.createDelayedOutput(2);
_byteBuffer = null;
_out = out;
} else {
// otherwise temporarily write all subsequent data to a buffer
_dataSizeOutput = out;
_byteBuffer = new byte[RecordInputStream.MAX_RECORD_DATA_SIZE];
_out = new LittleEndianByteArrayOutputStream(_byteBuffer, 0);
}
}
/**
* includes 4 byte header
*/
public int getTotalSize() {
return 4 + _size;
}
public int getAvailableSpace() {
if (_out == null) {
throw new IllegalStateException("Record already terminated");
}
return MAX_DATA_SIZE - _size;
}
/**
* Finishes writing the current record and updates 'ushort size' field.<br/>
* After this method is called, only {@link #getTotalSize()} may be called.
*/
public void terminate() {
if (_out == null) {
throw new IllegalStateException("Record already terminated");
}
_dataSizeOutput.writeShort(_size);
if (_byteBuffer != null) {
_originalOut.write(_byteBuffer, 0, _size);
_out = null;
return;
}
_out = null;
}
public void write(byte[] b) {
_out.write(b);
_size += b.length;
}
public void write(byte[] b, int offset, int len) {
_out.write(b, offset, len);
_size += len;
}
public void writeByte(int v) {
_out.writeByte(v);
_size += 1;
}
public void writeDouble(double v) {
_out.writeDouble(v);
_size += 8;
}
public void writeInt(int v) {
_out.writeInt(v);
_size += 4;
}
public void writeLong(long v) {
_out.writeLong(v);
_size += 8;
}
public void writeShort(int v) {
_out.writeShort(v);
_size += 2;
}
}

+ 64
- 64
src/java/org/apache/poi/hssf/record/formula/Area2DPtgBase.java Ver arquivo

@@ -1,64 +1,64 @@
/* ====================================================================
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.record.formula;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
* Common superclass of 2-D area refs
*/
public abstract class Area2DPtgBase extends AreaPtgBase {
private final static int SIZE = 9;
protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
}
protected Area2DPtgBase(AreaReference ar) {
super(ar);
}
protected Area2DPtgBase(LittleEndianInput in) {
readCoordinates(in);
}
protected abstract byte getSid();
public final void write(LittleEndianOutput out) {
out.writeByte(getSid() + getPtgClass());
writeCoordinates(out);
}
public final int getSize() {
return SIZE;
}
public final String toFormulaString() {
return formatReferenceAsString();
}
public final String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" [");
sb.append(formatReferenceAsString());
sb.append("]");
return sb.toString();
}
}
/* ====================================================================
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.record.formula;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
* Common superclass of 2-D area refs
*/
public abstract class Area2DPtgBase extends AreaPtgBase {
private final static int SIZE = 9;
protected Area2DPtgBase(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
}
protected Area2DPtgBase(AreaReference ar) {
super(ar);
}
protected Area2DPtgBase(LittleEndianInput in) {
readCoordinates(in);
}
protected abstract byte getSid();
public final void write(LittleEndianOutput out) {
out.writeByte(getSid() + getPtgClass());
writeCoordinates(out);
}
public final int getSize() {
return SIZE;
}
public final String toFormulaString() {
return formatReferenceAsString();
}
public final String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName());
sb.append(" [");
sb.append(formatReferenceAsString());
sb.append("]");
return sb.toString();
}
}

+ 54
- 54
src/java/org/apache/poi/hssf/record/formula/RefPtg.java Ver arquivo

@@ -1,54 +1,54 @@
/* ====================================================================
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.record.formula;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LittleEndianInput;
/**
* ReferencePtg - handles references (such as A1, A2, IA4)
* @author Andrew C. Oliver (acoliver@apache.org)
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class RefPtg extends Ref2DPtgBase {
public final static byte sid = 0x24;
/**
* Takes in a String representation of a cell reference and fills out the
* numeric fields.
*/
public RefPtg(String cellref) {
super(new CellReference(cellref));
}
public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
super(row, column, isRowRelative, isColumnRelative);
}
public RefPtg(LittleEndianInput in) {
super(in);
}
public RefPtg(CellReference cr) {
super(cr);
}
protected byte getSid() {
return sid;
}
}
/* ====================================================================
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.record.formula;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LittleEndianInput;
/**
* ReferencePtg - handles references (such as A1, A2, IA4)
* @author Andrew C. Oliver (acoliver@apache.org)
* @author Jason Height (jheight at chariot dot net dot au)
*/
public final class RefPtg extends Ref2DPtgBase {
public final static byte sid = 0x24;
/**
* Takes in a String representation of a cell reference and fills out the
* numeric fields.
*/
public RefPtg(String cellref) {
super(new CellReference(cellref));
}
public RefPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
super(row, column, isRowRelative, isColumnRelative);
}
public RefPtg(LittleEndianInput in) {
super(in);
}
public RefPtg(CellReference cr) {
super(cr);
}
protected byte getSid() {
return sid;
}
}

+ 40
- 40
src/java/org/apache/poi/hssf/record/formula/ScalarConstantPtg.java Ver arquivo

@@ -1,40 +1,40 @@
/* ====================================================================
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.record.formula;
/**
* @author Josh Micich
*/
abstract class ScalarConstantPtg extends Ptg {
public boolean isBaseToken() {
return true;
}
public final byte getDefaultOperandClass() {
return Ptg.CLASS_VALUE;
}
public final String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(toFormulaString());
sb.append("]");
return sb.toString();
}
}
/* ====================================================================
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.record.formula;
/**
* @author Josh Micich
*/
abstract class ScalarConstantPtg extends Ptg {
public boolean isBaseToken() {
return true;
}
public final byte getDefaultOperandClass() {
return Ptg.CLASS_VALUE;
}
public final String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(toFormulaString());
sb.append("]");
return sb.toString();
}
}

+ 40
- 40
src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java Ver arquivo

@@ -1,40 +1,40 @@
/* ====================================================================
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.record.formula.eval;
/**
* Common base class for implementors of {@link RefEval}
*
* @author Josh Micich
*/
public abstract class RefEvalBase implements RefEval {
private final int _rowIndex;
private final int _columnIndex;
protected RefEvalBase(int rowIndex, int columnIndex) {
_rowIndex = rowIndex;
_columnIndex = columnIndex;
}
public final int getRow() {
return _rowIndex;
}
public final int getColumn() {
return _columnIndex;
}
}
/* ====================================================================
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.record.formula.eval;
/**
* Common base class for implementors of {@link RefEval}
*
* @author Josh Micich
*/
public abstract class RefEvalBase implements RefEval {
private final int _rowIndex;
private final int _columnIndex;
protected RefEvalBase(int rowIndex, int columnIndex) {
_rowIndex = rowIndex;
_columnIndex = columnIndex;
}
public final int getRow() {
return _rowIndex;
}
public final int getColumn() {
return _columnIndex;
}
}

+ 162
- 162
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java Ver arquivo

@@ -1,162 +1,162 @@
/* ====================================================================
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.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.SpreadsheetVersion;
/**
* Internal POI use only
*
* @author Josh Micich
*/
public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
private final HSSFWorkbook _uBook;
private final Workbook _iBook;
public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
if (book == null) {
return null;
}
return new HSSFEvaluationWorkbook(book);
}
private HSSFEvaluationWorkbook(HSSFWorkbook book) {
_uBook = book;
_iBook = book.getWorkbook();
}
public int getExternalSheetIndex(String sheetName) {
int sheetIndex = _uBook.getSheetIndex(sheetName);
return _iBook.checkExternSheet(sheetIndex);
}
public int getExternalSheetIndex(String workbookName, String sheetName) {
return _iBook.getExternalSheetIndex(workbookName, sheetName);
}
public NameXPtg getNameXPtg(String name) {
return _iBook.getNameXPtg(name);
}
/**
* Lookup a named range by its name.
*
* @param name the name to search
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
* The sheet index is required to resolve sheet-level names. <code>-1</code> means workbook-global names
*/
public EvaluationName getName(String name, int sheetIndex) {
for(int i=0; i < _iBook.getNumNames(); i++) {
NameRecord nr = _iBook.getNameRecord(i);
if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
return new Name(nr, i);
}
}
return sheetIndex == -1 ? null : getName(name, -1);
}
public int getSheetIndex(EvaluationSheet evalSheet) {
HSSFSheet sheet = ((HSSFEvaluationSheet)evalSheet).getHSSFSheet();
return _uBook.getSheetIndex(sheet);
}
public int getSheetIndex(String sheetName) {
return _uBook.getSheetIndex(sheetName);
}
public String getSheetName(int sheetIndex) {
return _uBook.getSheetName(sheetIndex);
}
public EvaluationSheet getSheet(int sheetIndex) {
return new HSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
}
public int convertFromExternSheetIndex(int externSheetIndex) {
return _iBook.getSheetIndexFromExternSheetIndex(externSheetIndex);
}
public ExternalSheet getExternalSheet(int externSheetIndex) {
return _iBook.getExternalSheet(externSheetIndex);
}
public String resolveNameXText(NameXPtg n) {
return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
}
public String getSheetNameByExternSheet(int externSheetIndex) {
return _iBook.findSheetNameFromExternSheet(externSheetIndex);
}
public String getNameText(NamePtg namePtg) {
return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
}
public EvaluationName getName(NamePtg namePtg) {
int ix = namePtg.getIndex();
return new Name(_iBook.getNameRecord(ix), ix);
}
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
if (false) {
// re-parsing the formula text also works, but is a waste of time
// It is useful from time to time to run all unit tests with this code
// to make sure that all formulas POI can evaluate can also be parsed.
return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
}
FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
return fra.getFormulaTokens();
}
private static final class Name implements EvaluationName {
private final NameRecord _nameRecord;
private final int _index;
public Name(NameRecord nameRecord, int index) {
_nameRecord = nameRecord;
_index = index;
}
public Ptg[] getNameDefinition() {
return _nameRecord.getNameDefinition();
}
public String getNameText() {
return _nameRecord.getNameText();
}
public boolean hasFormula() {
return _nameRecord.hasFormula();
}
public boolean isFunctionName() {
return _nameRecord.isFunctionName();
}
public boolean isRange() {
return _nameRecord.hasFormula(); // TODO - is this right?
}
public NamePtg createPtg() {
return new NamePtg(_index);
}
}
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL97;
}
}
/* ====================================================================
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.model.HSSFFormulaParser;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.SpreadsheetVersion;
/**
* Internal POI use only
*
* @author Josh Micich
*/
public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
private final HSSFWorkbook _uBook;
private final Workbook _iBook;
public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
if (book == null) {
return null;
}
return new HSSFEvaluationWorkbook(book);
}
private HSSFEvaluationWorkbook(HSSFWorkbook book) {
_uBook = book;
_iBook = book.getWorkbook();
}
public int getExternalSheetIndex(String sheetName) {
int sheetIndex = _uBook.getSheetIndex(sheetName);
return _iBook.checkExternSheet(sheetIndex);
}
public int getExternalSheetIndex(String workbookName, String sheetName) {
return _iBook.getExternalSheetIndex(workbookName, sheetName);
}
public NameXPtg getNameXPtg(String name) {
return _iBook.getNameXPtg(name);
}
/**
* Lookup a named range by its name.
*
* @param name the name to search
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
* The sheet index is required to resolve sheet-level names. <code>-1</code> means workbook-global names
*/
public EvaluationName getName(String name, int sheetIndex) {
for(int i=0; i < _iBook.getNumNames(); i++) {
NameRecord nr = _iBook.getNameRecord(i);
if (nr.getSheetNumber() == sheetIndex+1 && name.equalsIgnoreCase(nr.getNameText())) {
return new Name(nr, i);
}
}
return sheetIndex == -1 ? null : getName(name, -1);
}
public int getSheetIndex(EvaluationSheet evalSheet) {
HSSFSheet sheet = ((HSSFEvaluationSheet)evalSheet).getHSSFSheet();
return _uBook.getSheetIndex(sheet);
}
public int getSheetIndex(String sheetName) {
return _uBook.getSheetIndex(sheetName);
}
public String getSheetName(int sheetIndex) {
return _uBook.getSheetName(sheetIndex);
}
public EvaluationSheet getSheet(int sheetIndex) {
return new HSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
}
public int convertFromExternSheetIndex(int externSheetIndex) {
return _iBook.getSheetIndexFromExternSheetIndex(externSheetIndex);
}
public ExternalSheet getExternalSheet(int externSheetIndex) {
return _iBook.getExternalSheet(externSheetIndex);
}
public String resolveNameXText(NameXPtg n) {
return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
}
public String getSheetNameByExternSheet(int externSheetIndex) {
return _iBook.findSheetNameFromExternSheet(externSheetIndex);
}
public String getNameText(NamePtg namePtg) {
return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
}
public EvaluationName getName(NamePtg namePtg) {
int ix = namePtg.getIndex();
return new Name(_iBook.getNameRecord(ix), ix);
}
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
if (false) {
// re-parsing the formula text also works, but is a waste of time
// It is useful from time to time to run all unit tests with this code
// to make sure that all formulas POI can evaluate can also be parsed.
return HSSFFormulaParser.parse(cell.getCellFormula(), _uBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
}
FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
return fra.getFormulaTokens();
}
private static final class Name implements EvaluationName {
private final NameRecord _nameRecord;
private final int _index;
public Name(NameRecord nameRecord, int index) {
_nameRecord = nameRecord;
_index = index;
}
public Ptg[] getNameDefinition() {
return _nameRecord.getNameDefinition();
}
public String getNameText() {
return _nameRecord.getNameText();
}
public boolean hasFormula() {
return _nameRecord.hasFormula();
}
public boolean isFunctionName() {
return _nameRecord.isFunctionName();
}
public boolean isRange() {
return _nameRecord.hasFormula(); // TODO - is this right?
}
public NamePtg createPtg() {
return new NamePtg(_index);
}
}
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL97;
}
}

+ 316
- 315
src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java Ver arquivo

@@ -1,315 +1,316 @@
/* ====================================================================
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 java.util.Iterator;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
/**
* Evaluates formula cells.<p/>
*
* For performance reasons, this class keeps a cache of all previously calculated intermediate
* cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between
* calls to evaluate~ methods on this class.
*
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* @author Josh Micich
*/
public class HSSFFormulaEvaluator implements FormulaEvaluator {
private WorkbookEvaluator _bookEvaluator;
/**
* @deprecated (Sep 2008) HSSFSheet parameter is ignored
*/
public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) {
this(workbook);
if (false) {
sheet.toString(); // suppress unused parameter compiler warning
}
}
public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
this(workbook, null);
}
/**
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins.
*/
public HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier) {
_bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier);
}
/**
* Coordinates several formula evaluators together so that formulas that involve external
* references can be evaluated.
* @param workbookNames the simple file names used to identify the workbooks in formulas
* with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
* @param evaluators all evaluators for the full set of workbooks required by the formulas.
*/
public static void setupEnvironment(String[] workbookNames, HSSFFormulaEvaluator[] evaluators) {
WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length];
for (int i = 0; i < wbEvals.length; i++) {
wbEvals[i] = evaluators[i]._bookEvaluator;
}
CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
}
/**
* Does nothing
* @deprecated (Aug 2008) - not needed, since the current row can be derived from the cell
*/
public void setCurrentRow(HSSFRow row) {
// do nothing
if (false) {
row.getClass(); // suppress unused parameter compiler warning
}
}
/**
* Should be called whenever there are major changes (e.g. moving sheets) to input cells
* in the evaluated workbook. If performance is not critical, a single call to this method
* may be used instead of many specific calls to the notify~ methods.
*
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void clearAllCachedResultValues() {
_bookEvaluator.clearAllCachedResultValues();
}
/**
* Should be called to tell the cell value cache that the specified (value or formula) cell
* has changed.
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void notifyUpdateCell(HSSFCell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell));
}
/**
* Should be called to tell the cell value cache that the specified cell has just been
* deleted.
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void notifyDeleteCell(HSSFCell cell) {
_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell));
}
public void notifyDeleteCell(Cell cell) {
_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell));
}
/**
* Should be called to tell the cell value cache that the specified (value or formula) cell
* has changed.
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void notifySetFormula(Cell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
}
/**
* If cell contains a formula, the formula is evaluated and returned,
* else the CellValue simply copies the appropriate cell value from
* the cell and also its cell type. This method should be preferred over
* evaluateInCell() when the call should not modify the contents of the
* original cell.
*
* @param cell may be <code>null</code> signifying that the cell is not present (or blank)
* @return <code>null</code> if the supplied cell is <code>null</code> or blank
*/
public CellValue evaluate(Cell cell) {
if (cell == null) {
return null;
}
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
return CellValue.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_ERROR:
return CellValue.getError(cell.getErrorCellValue());
case HSSFCell.CELL_TYPE_FORMULA:
return evaluateFormulaCellValue(cell);
case HSSFCell.CELL_TYPE_NUMERIC:
return new CellValue(cell.getNumericCellValue());
case HSSFCell.CELL_TYPE_STRING:
return new CellValue(cell.getRichStringCellValue().getString());
case HSSFCell.CELL_TYPE_BLANK:
return null;
}
throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
}
/**
* If cell contains formula, it evaluates the formula, and saves the result of the formula. The
* cell remains as a formula cell. If the cell does not contain formula, this method returns -1
* and leaves the cell unchanged.
*
* Note that the type of the <em>formula result</em> is returned, so you know what kind of
* cached formula result is also stored with the formula.
* <pre>
* int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
* </pre>
* Be aware that your cell will hold both the formula, and the result. If you want the cell
* replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
* @param cell The cell to evaluate
* @return -1 for non-formula cells, or the type of the <em>formula result</em>
*/
public int evaluateFormulaCell(Cell cell) {
if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
return -1;
}
CellValue cv = evaluateFormulaCellValue(cell);
// cell remains a formula cell, but the cached value is changed
setCellValue(cell, cv);
return cv.getCellType();
}
/**
* If cell contains formula, it evaluates the formula, and
* puts the formula result back into the cell, in place
* of the old formula.
* Else if cell does not contain formula, this method leaves
* the cell unchanged.
* Note that the same instance of HSSFCell is returned to
* allow chained calls like:
* <pre>
* int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
* </pre>
* Be aware that your cell value will be changed to hold the
* result of the formula. If you simply want the formula
* value computed for you, use {@link #evaluateFormulaCell(Cell)}}
*/
public HSSFCell evaluateInCell(Cell cell) {
if (cell == null) {
return null;
}
HSSFCell result = (HSSFCell) cell;
if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
CellValue cv = evaluateFormulaCellValue(cell);
setCellValue(cell, cv);
setCellType(cell, cv); // cell will no longer be a formula cell
}
return result;
}
private static void setCellType(Cell cell, CellValue cv) {
int cellType = cv.getCellType();
switch (cellType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
case HSSFCell.CELL_TYPE_ERROR:
case HSSFCell.CELL_TYPE_NUMERIC:
case HSSFCell.CELL_TYPE_STRING:
cell.setCellType(cellType);
return;
case HSSFCell.CELL_TYPE_BLANK:
// never happens - blanks eventually get translated to zero
case HSSFCell.CELL_TYPE_FORMULA:
// this will never happen, we have already evaluated the formula
}
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}
private static void setCellValue(Cell cell, CellValue cv) {
int cellType = cv.getCellType();
switch (cellType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
cell.setCellValue(cv.getBooleanValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
cell.setCellErrorValue(cv.getErrorValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
cell.setCellValue(cv.getNumberValue());
break;
case HSSFCell.CELL_TYPE_STRING:
cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
break;
case HSSFCell.CELL_TYPE_BLANK:
// never happens - blanks eventually get translated to zero
case HSSFCell.CELL_TYPE_FORMULA:
// this will never happen, we have already evaluated the formula
default:
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}
}
/**
* Loops over all cells in all sheets of the supplied
* workbook.
* For cells that contain formulas, their formulas are
* evaluated, and the results are saved. These cells
* remain as formula cells.
* For cells that do not contain formulas, no changes
* are made.
* This is a helpful wrapper around looping over all
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
for(int i=0; i<wb.getNumberOfSheets(); i++) {
HSSFSheet sheet = wb.getSheetAt(i);
for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
HSSFRow r = (HSSFRow)rit.next();
for (Iterator cit = r.cellIterator(); cit.hasNext();) {
HSSFCell c = (HSSFCell)cit.next();
if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
evaluator.evaluateFormulaCell(c);
}
}
}
}
/**
* Returns a CellValue wrapper around the supplied ValueEval instance.
* @param eval
*/
private CellValue evaluateFormulaCellValue(Cell cell) {
ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
if (eval instanceof NumberEval) {
NumberEval ne = (NumberEval) eval;
return new CellValue(ne.getNumberValue());
}
if (eval instanceof BoolEval) {
BoolEval be = (BoolEval) eval;
return CellValue.valueOf(be.getBooleanValue());
}
if (eval instanceof StringEval) {
StringEval ne = (StringEval) eval;
return new CellValue(ne.getStringValue());
}
if (eval instanceof ErrorEval) {
return CellValue.getError(((ErrorEval)eval).getErrorCode());
}
throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
}
/* ====================================================================
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 java.util.Iterator;

import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;

/**
* Evaluates formula cells.<p/>
*
* For performance reasons, this class keeps a cache of all previously calculated intermediate
* cell values. Be sure to call {@link #clearAllCachedResultValues()} if any workbook cells are changed between
* calls to evaluate~ methods on this class.
*
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* @author Josh Micich
*/
public class HSSFFormulaEvaluator implements FormulaEvaluator {

private WorkbookEvaluator _bookEvaluator;

/**
* @deprecated (Sep 2008) HSSFSheet parameter is ignored
*/
public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) {
this(workbook);
if (false) {
sheet.toString(); // suppress unused parameter compiler warning
}
}
public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
this(workbook, null);
}
/**
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins.
*/
public HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier) {
_bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier);
}

/**
* Coordinates several formula evaluators together so that formulas that involve external
* references can be evaluated.
* @param workbookNames the simple file names used to identify the workbooks in formulas
* with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
* @param evaluators all evaluators for the full set of workbooks required by the formulas.
*/
public static void setupEnvironment(String[] workbookNames, HSSFFormulaEvaluator[] evaluators) {
WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length];
for (int i = 0; i < wbEvals.length; i++) {
wbEvals[i] = evaluators[i]._bookEvaluator;
}
CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
}

/**
* Does nothing
* @deprecated (Aug 2008) - not needed, since the current row can be derived from the cell
*/
public void setCurrentRow(HSSFRow row) {
// do nothing
if (false) {
row.getClass(); // suppress unused parameter compiler warning
}
}

/**
* Should be called whenever there are major changes (e.g. moving sheets) to input cells
* in the evaluated workbook. If performance is not critical, a single call to this method
* may be used instead of many specific calls to the notify~ methods.
*
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void clearAllCachedResultValues() {
_bookEvaluator.clearAllCachedResultValues();
}
/**
* Should be called to tell the cell value cache that the specified (value or formula) cell
* has changed.
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void notifyUpdateCell(HSSFCell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell));
}
/**
* Should be called to tell the cell value cache that the specified cell has just been
* deleted.
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void notifyDeleteCell(HSSFCell cell) {
_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell));
}
public void notifyDeleteCell(Cell cell) {
_bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell));
}

/**
* Should be called to tell the cell value cache that the specified (value or formula) cell
* has changed.
* Failure to call this method after changing cell values will cause incorrect behaviour
* of the evaluate~ methods of this class
*/
public void notifySetFormula(Cell cell) {
_bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
}

/**
* If cell contains a formula, the formula is evaluated and returned,
* else the CellValue simply copies the appropriate cell value from
* the cell and also its cell type. This method should be preferred over
* evaluateInCell() when the call should not modify the contents of the
* original cell.
*
* @param cell may be <code>null</code> signifying that the cell is not present (or blank)
* @return <code>null</code> if the supplied cell is <code>null</code> or blank
*/
public CellValue evaluate(Cell cell) {
if (cell == null) {
return null;
}

switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
return CellValue.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_ERROR:
return CellValue.getError(cell.getErrorCellValue());
case HSSFCell.CELL_TYPE_FORMULA:
return evaluateFormulaCellValue(cell);
case HSSFCell.CELL_TYPE_NUMERIC:
return new CellValue(cell.getNumericCellValue());
case HSSFCell.CELL_TYPE_STRING:
return new CellValue(cell.getRichStringCellValue().getString());
case HSSFCell.CELL_TYPE_BLANK:
return null;
}
throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
}


/**
* If cell contains formula, it evaluates the formula, and saves the result of the formula. The
* cell remains as a formula cell. If the cell does not contain formula, this method returns -1
* and leaves the cell unchanged.
*
* Note that the type of the <em>formula result</em> is returned, so you know what kind of
* cached formula result is also stored with the formula.
* <pre>
* int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
* </pre>
* Be aware that your cell will hold both the formula, and the result. If you want the cell
* replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)}
* @param cell The cell to evaluate
* @return -1 for non-formula cells, or the type of the <em>formula result</em>
*/
public int evaluateFormulaCell(Cell cell) {
if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
return -1;
}
CellValue cv = evaluateFormulaCellValue(cell);
// cell remains a formula cell, but the cached value is changed
setCellValue(cell, cv);
return cv.getCellType();
}

/**
* If cell contains formula, it evaluates the formula, and
* puts the formula result back into the cell, in place
* of the old formula.
* Else if cell does not contain formula, this method leaves
* the cell unchanged.
* Note that the same instance of HSSFCell is returned to
* allow chained calls like:
* <pre>
* int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
* </pre>
* Be aware that your cell value will be changed to hold the
* result of the formula. If you simply want the formula
* value computed for you, use {@link #evaluateFormulaCell(Cell)}}
*/
public HSSFCell evaluateInCell(Cell cell) {
if (cell == null) {
return null;
}
HSSFCell result = (HSSFCell) cell;
if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
CellValue cv = evaluateFormulaCellValue(cell);
setCellValue(cell, cv);
setCellType(cell, cv); // cell will no longer be a formula cell
}
return result;
}
private static void setCellType(Cell cell, CellValue cv) {
int cellType = cv.getCellType();
switch (cellType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
case HSSFCell.CELL_TYPE_ERROR:
case HSSFCell.CELL_TYPE_NUMERIC:
case HSSFCell.CELL_TYPE_STRING:
cell.setCellType(cellType);
return;
case HSSFCell.CELL_TYPE_BLANK:
// never happens - blanks eventually get translated to zero
case HSSFCell.CELL_TYPE_FORMULA:
// this will never happen, we have already evaluated the formula
}
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}

private static void setCellValue(Cell cell, CellValue cv) {
int cellType = cv.getCellType();
switch (cellType) {
case HSSFCell.CELL_TYPE_BOOLEAN:
cell.setCellValue(cv.getBooleanValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
cell.setCellErrorValue(cv.getErrorValue());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
cell.setCellValue(cv.getNumberValue());
break;
case HSSFCell.CELL_TYPE_STRING:
cell.setCellValue(new HSSFRichTextString(cv.getStringValue()));
break;
case HSSFCell.CELL_TYPE_BLANK:
// never happens - blanks eventually get translated to zero
case HSSFCell.CELL_TYPE_FORMULA:
// this will never happen, we have already evaluated the formula
default:
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}
}

/**
* Loops over all cells in all sheets of the supplied
* workbook.
* For cells that contain formulas, their formulas are
* evaluated, and the results are saved. These cells
* remain as formula cells.
* For cells that do not contain formulas, no changes
* are made.
* This is a helpful wrapper around looping over all
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
for(int i=0; i<wb.getNumberOfSheets(); i++) {
HSSFSheet sheet = wb.getSheetAt(i);

for (Iterator<Row> rit = sheet.rowIterator(); rit.hasNext();) {
Row r = rit.next();

for (Iterator<Cell> cit = r.cellIterator(); cit.hasNext();) {
Cell c = cit.next();
if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
evaluator.evaluateFormulaCell(c);
}
}
}
}

/**
* Returns a CellValue wrapper around the supplied ValueEval instance.
* @param eval
*/
private CellValue evaluateFormulaCellValue(Cell cell) {
ValueEval eval = _bookEvaluator.evaluate(new HSSFEvaluationCell((HSSFCell)cell));
if (eval instanceof NumberEval) {
NumberEval ne = (NumberEval) eval;
return new CellValue(ne.getNumberValue());
}
if (eval instanceof BoolEval) {
BoolEval be = (BoolEval) eval;
return CellValue.valueOf(be.getBooleanValue());
}
if (eval instanceof StringEval) {
StringEval ne = (StringEval) eval;
return new CellValue(ne.getStringValue());
}
if (eval instanceof ErrorEval) {
return CellValue.getError(((ErrorEval)eval).getErrorCode());
}
throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
}

+ 220
- 220
src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java Ver arquivo

@@ -1,220 +1,220 @@
/* ====================================================================
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.HyperlinkRecord;
import org.apache.poi.ss.usermodel.Hyperlink;
/**
* Represents an Excel hyperlink.
*
* @author Yegor Kozlov (yegor at apache dot org)
*/
public class HSSFHyperlink implements Hyperlink {
/**
* 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;
/**
* Link to a file
*/
public static final int LINK_FILE = 4;
/**
* Low-level record object that stores the actual hyperlink data
*/
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 <code>HyperlinkRecord</code> record
*
* @param record
*/
protected HSSFHyperlink( HyperlinkRecord record )
{
this.record = record;
}
/**
* 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 getFirstRow(){
return record.getFirstRow();
}
/**
* Set the row of the first cell that contains the hyperlink
*
* @param row the 0-based row of the first cell that contains the hyperlink
*/
public void setFirstRow(int row){
record.setFirstRow(row);
}
/**
* Return the row of the last cell that contains the hyperlink
*
* @return the 0-based row of the last cell that contains the hyperlink
*/
public int getLastRow(){
return record.getLastRow();
}
/**
* Set the row of the last cell that contains the hyperlink
*
* @param row the 0-based row of the last cell that contains the hyperlink
*/
public void setLastRow(int row){
record.setLastRow(row);
}
/**
* 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 int 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(int col){
record.setFirstColumn((short)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 int 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(int col){
record.setLastColumn((short)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.getAddress();
}
public String getTextMark(){
return record.getTextMark();
}
public void setTextMark(String textMark) {
record.setTextMark(textMark);
}
public String getShortFilename(){
return record.getShortFilename();
}
public void setShortFilename(String shortFilename) {
record.setShortFilename(shortFilename);
}
/**
* 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
*/
public String getLabel(){
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(){
return link_type;
}
}
/* ====================================================================
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.HyperlinkRecord;
import org.apache.poi.ss.usermodel.Hyperlink;
/**
* Represents an Excel hyperlink.
*
* @author Yegor Kozlov (yegor at apache dot org)
*/
public class HSSFHyperlink implements Hyperlink {
/**
* 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;
/**
* Link to a file
*/
public static final int LINK_FILE = 4;
/**
* Low-level record object that stores the actual hyperlink data
*/
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 <code>HyperlinkRecord</code> record
*
* @param record
*/
protected HSSFHyperlink( HyperlinkRecord record )
{
this.record = record;
}
/**
* 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 getFirstRow(){
return record.getFirstRow();
}
/**
* Set the row of the first cell that contains the hyperlink
*
* @param row the 0-based row of the first cell that contains the hyperlink
*/
public void setFirstRow(int row){
record.setFirstRow(row);
}
/**
* Return the row of the last cell that contains the hyperlink
*
* @return the 0-based row of the last cell that contains the hyperlink
*/
public int getLastRow(){
return record.getLastRow();
}
/**
* Set the row of the last cell that contains the hyperlink
*
* @param row the 0-based row of the last cell that contains the hyperlink
*/
public void setLastRow(int row){
record.setLastRow(row);
}
/**
* 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 int 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(int col){
record.setFirstColumn((short)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 int 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(int col){
record.setLastColumn((short)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.getAddress();
}
public String getTextMark(){
return record.getTextMark();
}
public void setTextMark(String textMark) {
record.setTextMark(textMark);
}
public String getShortFilename(){
return record.getShortFilename();
}
public void setShortFilename(String shortFilename) {
record.setShortFilename(shortFilename);
}
/**
* 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
*/
public String getLabel(){
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(){
return link_type;
}
}

+ 193
- 194
src/java/org/apache/poi/hssf/usermodel/HSSFSheetConditionalFormatting.java Ver arquivo

@@ -1,194 +1,193 @@
/* ====================================================================
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.model.Sheet;
import org.apache.poi.hssf.record.CFRuleRecord;
import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
import org.apache.poi.ss.util.Region;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.SpreadsheetVersion;
/**
* The 'Conditional Formatting' facet of <tt>HSSFSheet</tt>
*
* @author Dmitriy Kumshayev
*/
public final class HSSFSheetConditionalFormatting {
private final HSSFSheet _sheet;
private final ConditionalFormattingTable _conditionalFormattingTable;
/* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) {
_sheet = sheet;
_conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable();
}
/**
* A factory method allowing to create a conditional formatting rule
* with a cell comparison operator<p/>
* TODO - formulas containing cell references are currently not parsed properly
*
* @param comparisonOperation - a constant value from
* <tt>{@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}</tt>: <p>
* <ul>
* <li>BETWEEN</li>
* <li>NOT_BETWEEN</li>
* <li>EQUAL</li>
* <li>NOT_EQUAL</li>
* <li>GT</li>
* <li>LT</li>
* <li>GE</li>
* <li>LE</li>
* </ul>
* </p>
* @param formula1 - formula for the valued, compared with the cell
* @param formula2 - second formula (only used with
* {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#BETWEEN}) and
* {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#NOT_BETWEEN} operations)
*/
public HSSFConditionalFormattingRule createConditionalFormattingRule(
byte comparisonOperation,
String formula1,
String formula2) {
HSSFWorkbook wb = _sheet.getWorkbook();
CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2);
return new HSSFConditionalFormattingRule(wb, rr);
}
/**
* A factory method allowing to create a conditional formatting rule with a formula.<br>
*
* The formatting rules are applied by Excel when the value of the formula not equal to 0.<p/>
* TODO - formulas containing cell references are currently not parsed properly
* @param formula - formula for the valued, compared with the cell
*/
public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {
HSSFWorkbook wb = _sheet.getWorkbook();
CFRuleRecord rr = CFRuleRecord.create(_sheet, formula);
return new HSSFConditionalFormattingRule(wb, rr);
}
/**
* Adds a copy of HSSFConditionalFormatting object to the sheet
* <p>This method could be used to copy HSSFConditionalFormatting object
* from one sheet to another. For example:
* <pre>
* HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
* newSheet.addConditionalFormatting(cf);
* </pre>
*
* @param cf HSSFConditionalFormatting object
* @return index of the new Conditional Formatting object
*/
public int addConditionalFormatting( HSSFConditionalFormatting cf ) {
CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate();
return _conditionalFormattingTable.add(cfraClone);
}
/**
* @deprecated use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
*/
public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) {
return addConditionalFormatting(Region.convertRegionsToCellRanges(regions), cfRules);
}
/**
* Allows to add a new Conditional Formatting set to the sheet.
*
* @param regions - list of rectangular regions to apply conditional formatting rules
* @param cfRules - set of up to three conditional formatting rules
*
* @return index of the newly created Conditional Formatting object
*/
public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) {
if (regions == null) {
throw new IllegalArgumentException("regions must not be null");
}
for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97);
if (cfRules == null) {
throw new IllegalArgumentException("cfRules must not be null");
}
if (cfRules.length == 0) {
throw new IllegalArgumentException("cfRules must not be empty");
}
if (cfRules.length > 3) {
throw new IllegalArgumentException("Number of rules must not exceed 3");
}
CFRuleRecord[] rules = new CFRuleRecord[cfRules.length];
for (int i = 0; i != cfRules.length; i++) {
rules[i] = cfRules[i].getCfRuleRecord();
}
CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules);
return _conditionalFormattingTable.add(cfra);
}
public int addConditionalFormatting(CellRangeAddress[] regions,
HSSFConditionalFormattingRule rule1)
{
return addConditionalFormatting(regions,
new HSSFConditionalFormattingRule[]
{
rule1
});
}
public int addConditionalFormatting(CellRangeAddress[] regions,
HSSFConditionalFormattingRule rule1,
HSSFConditionalFormattingRule rule2)
{
return addConditionalFormatting(regions,
new HSSFConditionalFormattingRule[]
{
rule1, rule2
});
}
/**
* gets Conditional Formatting object at a particular index
*
* @param index
* of the Conditional Formatting object to fetch
* @return Conditional Formatting object
*/
public HSSFConditionalFormatting getConditionalFormattingAt(int index) {
CFRecordsAggregate cf = _conditionalFormattingTable.get(index);
if (cf == null) {
return null;
}
return new HSSFConditionalFormatting(_sheet.getWorkbook(), cf);
}
/**
* @return number of Conditional Formatting objects of the sheet
*/
public int getNumConditionalFormattings() {
return _conditionalFormattingTable.size();
}
/**
* removes a Conditional Formatting object by index
* @param index of a Conditional Formatting object to remove
*/
public void removeConditionalFormatting(int index) {
_conditionalFormattingTable.remove(index);
}
}
/* ====================================================================
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.CFRuleRecord;
import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
import org.apache.poi.ss.util.Region;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.SpreadsheetVersion;

/**
* The 'Conditional Formatting' facet of <tt>HSSFSheet</tt>
*
* @author Dmitriy Kumshayev
*/
public final class HSSFSheetConditionalFormatting {

private final HSSFSheet _sheet;
private final ConditionalFormattingTable _conditionalFormattingTable;

/* package */ HSSFSheetConditionalFormatting(HSSFSheet sheet) {
_sheet = sheet;
_conditionalFormattingTable = sheet.getSheet().getConditionalFormattingTable();
}

/**
* A factory method allowing to create a conditional formatting rule
* with a cell comparison operator<p/>
* TODO - formulas containing cell references are currently not parsed properly
*
* @param comparisonOperation - a constant value from
* <tt>{@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator}</tt>: <p>
* <ul>
* <li>BETWEEN</li>
* <li>NOT_BETWEEN</li>
* <li>EQUAL</li>
* <li>NOT_EQUAL</li>
* <li>GT</li>
* <li>LT</li>
* <li>GE</li>
* <li>LE</li>
* </ul>
* </p>
* @param formula1 - formula for the valued, compared with the cell
* @param formula2 - second formula (only used with
* {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#BETWEEN}) and
* {@link org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator#NOT_BETWEEN} operations)
*/
public HSSFConditionalFormattingRule createConditionalFormattingRule(
byte comparisonOperation,
String formula1,
String formula2) {

HSSFWorkbook wb = _sheet.getWorkbook();
CFRuleRecord rr = CFRuleRecord.create(_sheet, comparisonOperation, formula1, formula2);
return new HSSFConditionalFormattingRule(wb, rr);
}

/**
* A factory method allowing to create a conditional formatting rule with a formula.<br>
*
* The formatting rules are applied by Excel when the value of the formula not equal to 0.<p/>
* TODO - formulas containing cell references are currently not parsed properly
* @param formula - formula for the valued, compared with the cell
*/
public HSSFConditionalFormattingRule createConditionalFormattingRule(String formula) {
HSSFWorkbook wb = _sheet.getWorkbook();
CFRuleRecord rr = CFRuleRecord.create(_sheet, formula);
return new HSSFConditionalFormattingRule(wb, rr);
}

/**
* Adds a copy of HSSFConditionalFormatting object to the sheet
* <p>This method could be used to copy HSSFConditionalFormatting object
* from one sheet to another. For example:
* <pre>
* HSSFConditionalFormatting cf = sheet.getConditionalFormattingAt(index);
* newSheet.addConditionalFormatting(cf);
* </pre>
*
* @param cf HSSFConditionalFormatting object
* @return index of the new Conditional Formatting object
*/
public int addConditionalFormatting( HSSFConditionalFormatting cf ) {
CFRecordsAggregate cfraClone = cf.getCFRecordsAggregate().cloneCFAggregate();

return _conditionalFormattingTable.add(cfraClone);
}
/**
* @deprecated use <tt>CellRangeAddress</tt> instead of <tt>Region</tt>
*/
public int addConditionalFormatting(Region[] regions, HSSFConditionalFormattingRule[] cfRules) {
return addConditionalFormatting(Region.convertRegionsToCellRanges(regions), cfRules);
}
/**
* Allows to add a new Conditional Formatting set to the sheet.
*
* @param regions - list of rectangular regions to apply conditional formatting rules
* @param cfRules - set of up to three conditional formatting rules
*
* @return index of the newly created Conditional Formatting object
*/
public int addConditionalFormatting(CellRangeAddress[] regions, HSSFConditionalFormattingRule[] cfRules) {
if (regions == null) {
throw new IllegalArgumentException("regions must not be null");
}
for(CellRangeAddress range : regions) range.validate(SpreadsheetVersion.EXCEL97);

if (cfRules == null) {
throw new IllegalArgumentException("cfRules must not be null");
}
if (cfRules.length == 0) {
throw new IllegalArgumentException("cfRules must not be empty");
}
if (cfRules.length > 3) {
throw new IllegalArgumentException("Number of rules must not exceed 3");
}

CFRuleRecord[] rules = new CFRuleRecord[cfRules.length];
for (int i = 0; i != cfRules.length; i++) {
rules[i] = cfRules[i].getCfRuleRecord();
}
CFRecordsAggregate cfra = new CFRecordsAggregate(regions, rules);
return _conditionalFormattingTable.add(cfra);
}

public int addConditionalFormatting(CellRangeAddress[] regions,
HSSFConditionalFormattingRule rule1)
{
return addConditionalFormatting(regions,
new HSSFConditionalFormattingRule[]
{
rule1
});
}

public int addConditionalFormatting(CellRangeAddress[] regions,
HSSFConditionalFormattingRule rule1,
HSSFConditionalFormattingRule rule2)
{
return addConditionalFormatting(regions,
new HSSFConditionalFormattingRule[]
{
rule1, rule2
});
}

/**
* gets Conditional Formatting object at a particular index
*
* @param index
* of the Conditional Formatting object to fetch
* @return Conditional Formatting object
*/
public HSSFConditionalFormatting getConditionalFormattingAt(int index) {
CFRecordsAggregate cf = _conditionalFormattingTable.get(index);
if (cf == null) {
return null;
}
return new HSSFConditionalFormatting(_sheet.getWorkbook(), cf);
}

/**
* @return number of Conditional Formatting objects of the sheet
*/
public int getNumConditionalFormattings() {
return _conditionalFormattingTable.size();
}

/**
* removes a Conditional Formatting object by index
* @param index of a Conditional Formatting object to remove
*/
public void removeConditionalFormatting(int index) {
_conditionalFormattingTable.remove(index);
}
}

+ 38
- 38
src/java/org/apache/poi/hssf/util/CellRangeAddress.java Ver arquivo

@@ -1,38 +1,38 @@
/* ====================================================================
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.util;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.SelectionRecord;
/**
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
*
* Note - {@link SelectionRecord} uses the BIFF5 version of this structure
* @deprecated use {@link org.apache.poi.ss.util.CellRangeAddress}
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
*/
public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress {
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
super(firstRow, lastRow, firstCol, lastCol);
}
public CellRangeAddress(RecordInputStream in) {
super(in);
}
}
/* ====================================================================
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.util;
import org.apache.poi.hssf.record.RecordInputStream;
import org.apache.poi.hssf.record.SelectionRecord;
/**
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
*
* Note - {@link SelectionRecord} uses the BIFF5 version of this structure
* @deprecated use {@link org.apache.poi.ss.util.CellRangeAddress}
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
*/
public class CellRangeAddress extends org.apache.poi.ss.util.CellRangeAddress {
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
super(firstRow, lastRow, firstCol, lastCol);
}
public CellRangeAddress(RecordInputStream in) {
super(in);
}
}

+ 73
- 73
src/java/org/apache/poi/hssf/util/CellRangeAddress8Bit.java Ver arquivo

@@ -1,73 +1,73 @@
/* ====================================================================
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.util;
import org.apache.poi.ss.util.CellRangeAddressBase;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
*
* Like {@link CellRangeAddress} except column fields are 8-bit.
*
* @author Josh Micich
*/
public final class CellRangeAddress8Bit extends CellRangeAddressBase {
public static final int ENCODED_SIZE = 6;
public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) {
super(firstRow, lastRow, firstCol, lastCol);
}
public CellRangeAddress8Bit(LittleEndianInput in) {
super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte());
}
private static int readUShortAndCheck(LittleEndianInput in) {
if (in.available() < ENCODED_SIZE) {
// Ran out of data
throw new RuntimeException("Ran out of data reading CellRangeAddress");
}
return in.readUShort();
}
/**
* @deprecated use {@link #serialize(LittleEndianOutput)}
*/
public int serialize(int offset, byte[] data) {
serialize(new LittleEndianByteArrayOutputStream(data, offset, ENCODED_SIZE));
return ENCODED_SIZE;
}
public void serialize(LittleEndianOutput out) {
out.writeShort(getFirstRow());
out.writeShort(getLastRow());
out.writeByte(getFirstColumn());
out.writeByte(getLastColumn());
}
public CellRangeAddress8Bit copy() {
return new CellRangeAddress8Bit(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn());
}
public static int getEncodedSize(int numberOfItems) {
return numberOfItems * ENCODED_SIZE;
}
}
/* ====================================================================
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.util;
import org.apache.poi.ss.util.CellRangeAddressBase;
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
*
* Like {@link CellRangeAddress} except column fields are 8-bit.
*
* @author Josh Micich
*/
public final class CellRangeAddress8Bit extends CellRangeAddressBase {
public static final int ENCODED_SIZE = 6;
public CellRangeAddress8Bit(int firstRow, int lastRow, int firstCol, int lastCol) {
super(firstRow, lastRow, firstCol, lastCol);
}
public CellRangeAddress8Bit(LittleEndianInput in) {
super(readUShortAndCheck(in), in.readUShort(), in.readUByte(), in.readUByte());
}
private static int readUShortAndCheck(LittleEndianInput in) {
if (in.available() < ENCODED_SIZE) {
// Ran out of data
throw new RuntimeException("Ran out of data reading CellRangeAddress");
}
return in.readUShort();
}
/**
* @deprecated use {@link #serialize(LittleEndianOutput)}
*/
public int serialize(int offset, byte[] data) {
serialize(new LittleEndianByteArrayOutputStream(data, offset, ENCODED_SIZE));
return ENCODED_SIZE;
}
public void serialize(LittleEndianOutput out) {
out.writeShort(getFirstRow());
out.writeShort(getLastRow());
out.writeByte(getFirstColumn());
out.writeByte(getLastColumn());
}
public CellRangeAddress8Bit copy() {
return new CellRangeAddress8Bit(getFirstRow(), getLastRow(), getFirstColumn(), getLastColumn());
}
public static int getEncodedSize(int numberOfItems) {
return numberOfItems * ENCODED_SIZE;
}
}

+ 74
- 74
src/java/org/apache/poi/poifs/dev/POIFSDump.java Ver arquivo

@@ -1,74 +1,74 @@
/* ====================================================================
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.poifs.dev;
import org.apache.poi.poifs.filesystem.*;
import java.io.FileInputStream;
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.util.Iterator;
/**
*
* Dump internal structure of a OLE2 file into file system
*
* @author Yegor Kozlov
*/
public class POIFSDump {
public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
System.out.println("Dumping " + args[i]);
FileInputStream is = new FileInputStream(args[i]);
POIFSFileSystem fs = new POIFSFileSystem(is);
is.close();
DirectoryEntry root = fs.getRoot();
File file = new File(root.getName());
file.mkdir();
dump(root, file);
}
}
public static void dump(DirectoryEntry root, File parent) throws IOException {
for(Iterator it = root.getEntries(); it.hasNext();){
Entry entry = (Entry)it.next();
if(entry instanceof DocumentNode){
DocumentNode node = (DocumentNode)entry;
DocumentInputStream is = new DocumentInputStream(node);
byte[] bytes = new byte[node.getSize()];
is.read(bytes);
is.close();
FileOutputStream out = new FileOutputStream(new File(parent, node.getName().trim()));
out.write(bytes);
out.close();
} else if (entry instanceof DirectoryEntry){
DirectoryEntry dir = (DirectoryEntry)entry;
File file = new File(parent, entry.getName());
file.mkdir();
dump(dir, file);
} else {
System.err.println("Skipping unsupported POIFS entry: " + entry);
}
}
}
}
/* ====================================================================
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.poifs.dev;
import org.apache.poi.poifs.filesystem.*;
import java.io.FileInputStream;
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import java.util.Iterator;
/**
*
* Dump internal structure of a OLE2 file into file system
*
* @author Yegor Kozlov
*/
public class POIFSDump {
public static void main(String[] args) throws Exception {
for (int i = 0; i < args.length; i++) {
System.out.println("Dumping " + args[i]);
FileInputStream is = new FileInputStream(args[i]);
POIFSFileSystem fs = new POIFSFileSystem(is);
is.close();
DirectoryEntry root = fs.getRoot();
File file = new File(root.getName());
file.mkdir();
dump(root, file);
}
}
public static void dump(DirectoryEntry root, File parent) throws IOException {
for(Iterator it = root.getEntries(); it.hasNext();){
Entry entry = (Entry)it.next();
if(entry instanceof DocumentNode){
DocumentNode node = (DocumentNode)entry;
DocumentInputStream is = new DocumentInputStream(node);
byte[] bytes = new byte[node.getSize()];
is.read(bytes);
is.close();
FileOutputStream out = new FileOutputStream(new File(parent, node.getName().trim()));
out.write(bytes);
out.close();
} else if (entry instanceof DirectoryEntry){
DirectoryEntry dir = (DirectoryEntry)entry;
File file = new File(parent, entry.getName());
file.mkdir();
dump(dir, file);
} else {
System.err.println("Skipping unsupported POIFS entry: " + entry);
}
}
}
}

+ 119
- 120
src/java/org/apache/poi/ss/SpreadsheetVersion.java Ver arquivo

@@ -1,120 +1,119 @@
/* ====================================================================
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.ss;
import org.apache.poi.ss.util.CellReference;
/**
* This enum allows spreadsheets from multiple Excel versions to be handled by the common code.
* Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily
* discernable to the user. It is not intended to deal with low-level issues like file formats.
* <p/>
*
* @author Josh Micich
* @author Yegor Kozlov
*/
public enum SpreadsheetVersion {
/**
* Excel97 format aka BIFF8
* <ul>
* <li>The total number of available columns is 256 (2^8)</li>
* <li>The total number of available rows is 64k (2^16)</li>
* <li>The maximum number of arguments to a function is 30</li>
* <li>Number of conditional format conditions on a cell is 3</li>
* </ul>
*/
EXCEL97(0x10000, 0x0100, 30, 3),
/**
* Excel2007
*
* <ul>
* <li>The total number of available columns is 16K (2^14)</li>
* <li>The total number of available rows is 1M (2^20)</li>
* <li>The maximum number of arguments to a function is 255</li>
* <li>Number of conditional format conditions on a cell is unlimited
* (actually limited by available memory in Excel)</li>
* <ul>
*/
EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE);
private final int _maxRows;
private final int _maxColumns;
private final int _maxFunctionArgs;
private final int _maxCondFormats;
private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats) {
_maxRows = maxRows;
_maxColumns = maxColumns;
_maxFunctionArgs = maxFunctionArgs;
_maxCondFormats = maxCondFormats;
}
/**
* @return the maximum number of usable rows in each spreadsheet
*/
public int getMaxRows() {
return _maxRows;
}
/**
* @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code>
*/
public int getLastRowIndex() {
return _maxRows - 1;
}
/**
* @return the maximum number of usable columns in each spreadsheet
*/
public int getMaxColumns() {
return _maxColumns;
}
/**
* @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code>
*/
public int getLastColumnIndex() {
return _maxColumns - 1;
}
/**
* @return the maximum number arguments that can be passed to a multi-arg
* function (e.g. COUNTIF)
*/
public int getMaxFunctionArgs() {
return _maxFunctionArgs;
}
/**
*
* @return the maximum number of conditional format conditions on a cell
*/
public int getMaxConditionalFormats() {
return _maxCondFormats;
}
/**
*
* @return the last valid column index in a ALPHA-26 representation
* ( <code>IV</code> or <code>XFD</code>).
*/
public String getLastColumnName() {
return CellReference.convertNumToColString(getLastColumnIndex());
}
}
/* ====================================================================
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.ss;

import org.apache.poi.ss.util.CellReference;

/**
* This enum allows spreadsheets from multiple Excel versions to be handled by the common code.
* Properties of this enum correspond to attributes of the <i>spreadsheet</i> that are easily
* discernable to the user. It is not intended to deal with low-level issues like file formats.
* <p/>
*
* @author Josh Micich
* @author Yegor Kozlov
*/
public enum SpreadsheetVersion {
/**
* Excel97 format aka BIFF8
* <ul>
* <li>The total number of available columns is 256 (2^8)</li>
* <li>The total number of available rows is 64k (2^16)</li>
* <li>The maximum number of arguments to a function is 30</li>
* <li>Number of conditional format conditions on a cell is 3</li>
* </ul>
*/
EXCEL97(0x10000, 0x0100, 30, 3),

/**
* Excel2007
*
* <ul>
* <li>The total number of available columns is 16K (2^14)</li>
* <li>The total number of available rows is 1M (2^20)</li>
* <li>The maximum number of arguments to a function is 255</li>
* <li>Number of conditional format conditions on a cell is unlimited
* (actually limited by available memory in Excel)</li>
* <ul>
*/
EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE);

private final int _maxRows;
private final int _maxColumns;
private final int _maxFunctionArgs;
private final int _maxCondFormats;

private SpreadsheetVersion(int maxRows, int maxColumns, int maxFunctionArgs, int maxCondFormats) {
_maxRows = maxRows;
_maxColumns = maxColumns;
_maxFunctionArgs = maxFunctionArgs;
_maxCondFormats = maxCondFormats;
}

/**
* @return the maximum number of usable rows in each spreadsheet
*/
public int getMaxRows() {
return _maxRows;
}

/**
* @return the last (maximum) valid row index, equals to <code> getMaxRows() - 1 </code>
*/
public int getLastRowIndex() {
return _maxRows - 1;
}

/**
* @return the maximum number of usable columns in each spreadsheet
*/
public int getMaxColumns() {
return _maxColumns;
}

/**
* @return the last (maximum) valid column index, equals to <code> getMaxColumns() - 1 </code>
*/
public int getLastColumnIndex() {
return _maxColumns - 1;
}

/**
* @return the maximum number arguments that can be passed to a multi-arg function (e.g. COUNTIF)
*/
public int getMaxFunctionArgs() {
return _maxFunctionArgs;
}

/**
*
* @return the maximum number of conditional format conditions on a cell
*/
public int getMaxConditionalFormats() {
return _maxCondFormats;
}

/**
*
* @return the last valid column index in a ALPHA-26 representation
* (<code>IV</code> or <code>XFD</code>).
*/
public String getLastColumnName() {
return CellReference.convertNumToColString(getLastColumnIndex());
}
}

+ 77
- 77
src/java/org/apache/poi/ss/formula/CellEvaluationFrame.java Ver arquivo

@@ -1,77 +1,77 @@
/* ====================================================================
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.ss.formula;
import java.util.HashSet;
import java.util.Set;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Stores details about the current evaluation of a cell.<br/>
*/
final class CellEvaluationFrame {
private final FormulaCellCacheEntry _cce;
private final Set<CellCacheEntry> _sensitiveInputCells;
private FormulaUsedBlankCellSet _usedBlankCellGroup;
public CellEvaluationFrame(FormulaCellCacheEntry cce) {
_cce = cce;
_sensitiveInputCells = new HashSet<CellCacheEntry>();
}
public CellCacheEntry getCCE() {
return _cce;
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append("]");
return sb.toString();
}
/**
* @param inputCell a cell directly used by the formula of this evaluation frame
*/
public void addSensitiveInputCell(CellCacheEntry inputCell) {
_sensitiveInputCells.add(inputCell);
}
/**
* @return never <code>null</code>, (possibly empty) array of all cells directly used while
* evaluating the formula of this frame.
*/
private CellCacheEntry[] getSensitiveInputCells() {
int nItems = _sensitiveInputCells.size();
if (nItems < 1) {
return CellCacheEntry.EMPTY_ARRAY;
}
CellCacheEntry[] result = new CellCacheEntry[nItems];
_sensitiveInputCells.toArray(result);
return result;
}
public void addUsedBlankCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) {
if (_usedBlankCellGroup == null) {
_usedBlankCellGroup = new FormulaUsedBlankCellSet();
}
_usedBlankCellGroup.addCell(bookIndex, sheetIndex, rowIndex, columnIndex);
}
public void updateFormulaResult(ValueEval result) {
_cce.updateFormulaResult(result, getSensitiveInputCells(), _usedBlankCellGroup);
}
}
/* ====================================================================
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.ss.formula;
import java.util.HashSet;
import java.util.Set;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
* Stores details about the current evaluation of a cell.<br/>
*/
final class CellEvaluationFrame {
private final FormulaCellCacheEntry _cce;
private final Set<CellCacheEntry> _sensitiveInputCells;
private FormulaUsedBlankCellSet _usedBlankCellGroup;
public CellEvaluationFrame(FormulaCellCacheEntry cce) {
_cce = cce;
_sensitiveInputCells = new HashSet<CellCacheEntry>();
}
public CellCacheEntry getCCE() {
return _cce;
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append("]");
return sb.toString();
}
/**
* @param inputCell a cell directly used by the formula of this evaluation frame
*/
public void addSensitiveInputCell(CellCacheEntry inputCell) {
_sensitiveInputCells.add(inputCell);
}
/**
* @return never <code>null</code>, (possibly empty) array of all cells directly used while
* evaluating the formula of this frame.
*/
private CellCacheEntry[] getSensitiveInputCells() {
int nItems = _sensitiveInputCells.size();
if (nItems < 1) {
return CellCacheEntry.EMPTY_ARRAY;
}
CellCacheEntry[] result = new CellCacheEntry[nItems];
_sensitiveInputCells.toArray(result);
return result;
}
public void addUsedBlankCell(int bookIndex, int sheetIndex, int rowIndex, int columnIndex) {
if (_usedBlankCellGroup == null) {
_usedBlankCellGroup = new FormulaUsedBlankCellSet();
}
_usedBlankCellGroup.addCell(bookIndex, sheetIndex, rowIndex, columnIndex);
}
public void updateFormulaResult(ValueEval result) {
_cce.updateFormulaResult(result, getSensitiveInputCells(), _usedBlankCellGroup);
}
}

+ 41
- 41
src/java/org/apache/poi/ss/formula/EvaluationName.java Ver arquivo

@@ -1,41 +1,41 @@
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Abstracts a name record for formula evaluation.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface EvaluationName {
String getNameText();
boolean isFunctionName();
boolean hasFormula();
Ptg[] getNameDefinition();
boolean isRange();
NamePtg createPtg();
}
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Abstracts a name record for formula evaluation.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface EvaluationName {
String getNameText();
boolean isFunctionName();
boolean hasFormula();
Ptg[] getNameDefinition();
boolean isRange();
NamePtg createPtg();
}

+ 65
- 65
src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java Ver arquivo

@@ -1,65 +1,65 @@
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Abstracts a workbook for the purpose of formula evaluation.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface EvaluationWorkbook {
String getSheetName(int sheetIndex);
/**
* @return -1 if the specified sheet is from a different book
*/
int getSheetIndex(EvaluationSheet sheet);
int getSheetIndex(String sheetName);
EvaluationSheet getSheet(int sheetIndex);
/**
* @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
*/
ExternalSheet getExternalSheet(int externSheetIndex);
int convertFromExternSheetIndex(int externSheetIndex);
EvaluationName getName(NamePtg namePtg);
String resolveNameXText(NameXPtg ptg);
Ptg[] getFormulaTokens(EvaluationCell cell);
class ExternalSheet {
private final String _workbookName;
private final String _sheetName;
public ExternalSheet(String workbookName, String sheetName) {
_workbookName = workbookName;
_sheetName = sheetName;
}
public String getWorkbookName() {
return _workbookName;
}
public String getSheetName() {
return _sheetName;
}
}
}
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Abstracts a workbook for the purpose of formula evaluation.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface EvaluationWorkbook {
String getSheetName(int sheetIndex);
/**
* @return -1 if the specified sheet is from a different book
*/
int getSheetIndex(EvaluationSheet sheet);
int getSheetIndex(String sheetName);
EvaluationSheet getSheet(int sheetIndex);
/**
* @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
*/
ExternalSheet getExternalSheet(int externSheetIndex);
int convertFromExternSheetIndex(int externSheetIndex);
EvaluationName getName(NamePtg namePtg);
String resolveNameXText(NameXPtg ptg);
Ptg[] getFormulaTokens(EvaluationCell cell);
class ExternalSheet {
private final String _workbookName;
private final String _sheetName;
public ExternalSheet(String workbookName, String sheetName) {
_workbookName = workbookName;
_sheetName = sheetName;
}
public String getWorkbookName() {
return _workbookName;
}
public String getSheetName() {
return _sheetName;
}
}
}

+ 197
- 197
src/java/org/apache/poi/ss/formula/Formula.java Ver arquivo

@@ -1,197 +1,197 @@
/* ====================================================================
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.ss.formula;
import java.util.Arrays;
import org.apache.poi.hssf.record.ArrayRecord;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.TableRecord;
import org.apache.poi.hssf.record.formula.ExpPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.TblPtg;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
* Encapsulates an encoded formula token array.
*
* @author Josh Micich
*/
public class Formula {
private static final Formula EMPTY = new Formula(new byte[0], 0);
/** immutable */
private final byte[] _byteEncoding;
private final int _encodedTokenLen;
private Formula(byte[] byteEncoding, int encodedTokenLen) {
_byteEncoding = byteEncoding;
_encodedTokenLen = encodedTokenLen;
if (false) { // set to true to eagerly check Ptg decoding
LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding);
Ptg.readTokens(encodedTokenLen, in);
int nUnusedBytes = _byteEncoding.length - in.getReadIndex();
if (nUnusedBytes > 0) {
// TODO - this seems to occur when IntersectionPtg is present
// This example file "IntersectionPtg.xls"
// used by test: TestIntersectionPtg.testReading()
// has 10 bytes unused at the end of the formula
// 10 extra bytes are just 0x01 and 0x00
System.out.println(nUnusedBytes + " unused bytes at end of formula");
}
}
}
/**
* Convenience method for {@link #read(int, LittleEndianInput, int)}
*/
public static Formula read(int encodedTokenLen, LittleEndianInput in) {
return read(encodedTokenLen, in, encodedTokenLen);
}
/**
* When there are no array constants present, <tt>encodedTokenLen</tt>==<tt>totalEncodedLen</tt>
* @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens
* @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding
* for array constants, but does not include 2 bytes for initial <tt>ushort encodedTokenLen</tt> field.
* @return A new formula object as read from the stream. Possibly empty, never <code>null</code>.
*/
public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) {
byte[] byteEncoding = new byte[totalEncodedLen];
in.readFully(byteEncoding);
return new Formula(byteEncoding, encodedTokenLen);
}
public Ptg[] getTokens() {
LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding);
return Ptg.readTokens(_encodedTokenLen, in);
}
/**
* Writes The formula encoding is includes:
* <ul>
* <li>ushort tokenDataLen</li>
* <li>tokenData</li>
* <li>arrayConstantData (if present)</li>
* </ul>
*/
public void serialize(LittleEndianOutput out) {
out.writeShort(_encodedTokenLen);
out.write(_byteEncoding);
}
public void serializeTokens(LittleEndianOutput out) {
out.write(_byteEncoding, 0, _encodedTokenLen);
}
public void serializeArrayConstantData(LittleEndianOutput out) {
int len = _byteEncoding.length-_encodedTokenLen;
out.write(_byteEncoding, _encodedTokenLen, len);
}
/**
* @return total formula encoding length. The formula encoding includes:
* <ul>
* <li>ushort tokenDataLen</li>
* <li>tokenData</li>
* <li>arrayConstantData (optional)</li>
* </ul>
* Note - this value is different to <tt>tokenDataLength</tt>
*/
public int getEncodedSize() {
return 2 + _byteEncoding.length;
}
/**
* This method is often used when the formula length does not appear immediately before
* the encoded token data.
*
* @return the encoded length of the plain formula tokens. This does <em>not</em> include
* the leading ushort field, nor any trailing array constant data.
*/
public int getEncodedTokenSize() {
return _encodedTokenLen;
}
/**
* Creates a {@link Formula} object from a supplied {@link Ptg} array.
* Handles <code>null</code>s OK.
* @param ptgs may be <code>null</code>
* @return Never <code>null</code> (Possibly empty if the supplied <tt>ptgs</tt> is <code>null</code>)
*/
public static Formula create(Ptg[] ptgs) {
if (ptgs == null || ptgs.length < 1) {
return EMPTY;
}
int totalSize = Ptg.getEncodedSize(ptgs);
byte[] encodedData = new byte[totalSize];
Ptg.serializePtgs(ptgs, encodedData, 0);
int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs);
return new Formula(encodedData, encodedTokenLen);
}
/**
* Gets the {@link Ptg} array from the supplied {@link Formula}.
* Handles <code>null</code>s OK.
*
* @param formula may be <code>null</code>
* @return possibly <code>null</code> (if the supplied <tt>formula</tt> is <code>null</code>)
*/
public static Ptg[] getTokens(Formula formula) {
if (formula == null) {
return null;
}
return formula.getTokens();
}
public Formula copy() {
// OK to return this because immutable
return this;
}
/**
* Gets the locator for the corresponding {@link SharedFormulaRecord}, {@link ArrayRecord} or
* {@link TableRecord} if this formula belongs to such a grouping. The {@link CellReference}
* returned by this method will match the top left corner of the range of that grouping.
* The return value is usually not the same as the location of the cell containing this formula.
*
* @return the firstRow & firstColumn of an array formula or shared formula that this formula
* belongs to. <code>null</code> if this formula is not part of an array or shared formula.
*/
public CellReference getExpReference() {
byte[] data = _byteEncoding;
if (data.length != 5) {
// tExp and tTbl are always 5 bytes long, and the only ptg in the formula
return null;
}
switch (data[0]) {
case ExpPtg.sid:
break;
case TblPtg.sid:
break;
default:
return null;
}
int firstRow = LittleEndian.getUShort(data, 1);
int firstColumn = LittleEndian.getUShort(data, 3);
return new CellReference(firstRow, firstColumn);
}
public boolean isSame(Formula other) {
return Arrays.equals(_byteEncoding, other._byteEncoding);
}
}
/* ====================================================================
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.ss.formula;
import java.util.Arrays;
import org.apache.poi.hssf.record.ArrayRecord;
import org.apache.poi.hssf.record.SharedFormulaRecord;
import org.apache.poi.hssf.record.TableRecord;
import org.apache.poi.hssf.record.formula.ExpPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.TblPtg;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
* Encapsulates an encoded formula token array.
*
* @author Josh Micich
*/
public class Formula {
private static final Formula EMPTY = new Formula(new byte[0], 0);
/** immutable */
private final byte[] _byteEncoding;
private final int _encodedTokenLen;
private Formula(byte[] byteEncoding, int encodedTokenLen) {
_byteEncoding = byteEncoding;
_encodedTokenLen = encodedTokenLen;
if (false) { // set to true to eagerly check Ptg decoding
LittleEndianByteArrayInputStream in = new LittleEndianByteArrayInputStream(byteEncoding);
Ptg.readTokens(encodedTokenLen, in);
int nUnusedBytes = _byteEncoding.length - in.getReadIndex();
if (nUnusedBytes > 0) {
// TODO - this seems to occur when IntersectionPtg is present
// This example file "IntersectionPtg.xls"
// used by test: TestIntersectionPtg.testReading()
// has 10 bytes unused at the end of the formula
// 10 extra bytes are just 0x01 and 0x00
System.out.println(nUnusedBytes + " unused bytes at end of formula");
}
}
}
/**
* Convenience method for {@link #read(int, LittleEndianInput, int)}
*/
public static Formula read(int encodedTokenLen, LittleEndianInput in) {
return read(encodedTokenLen, in, encodedTokenLen);
}
/**
* When there are no array constants present, <tt>encodedTokenLen</tt>==<tt>totalEncodedLen</tt>
* @param encodedTokenLen number of bytes in the stream taken by the plain formula tokens
* @param totalEncodedLen the total number of bytes in the formula (includes trailing encoding
* for array constants, but does not include 2 bytes for initial <tt>ushort encodedTokenLen</tt> field.
* @return A new formula object as read from the stream. Possibly empty, never <code>null</code>.
*/
public static Formula read(int encodedTokenLen, LittleEndianInput in, int totalEncodedLen) {
byte[] byteEncoding = new byte[totalEncodedLen];
in.readFully(byteEncoding);
return new Formula(byteEncoding, encodedTokenLen);
}
public Ptg[] getTokens() {
LittleEndianInput in = new LittleEndianByteArrayInputStream(_byteEncoding);
return Ptg.readTokens(_encodedTokenLen, in);
}
/**
* Writes The formula encoding is includes:
* <ul>
* <li>ushort tokenDataLen</li>
* <li>tokenData</li>
* <li>arrayConstantData (if present)</li>
* </ul>
*/
public void serialize(LittleEndianOutput out) {
out.writeShort(_encodedTokenLen);
out.write(_byteEncoding);
}
public void serializeTokens(LittleEndianOutput out) {
out.write(_byteEncoding, 0, _encodedTokenLen);
}
public void serializeArrayConstantData(LittleEndianOutput out) {
int len = _byteEncoding.length-_encodedTokenLen;
out.write(_byteEncoding, _encodedTokenLen, len);
}
/**
* @return total formula encoding length. The formula encoding includes:
* <ul>
* <li>ushort tokenDataLen</li>
* <li>tokenData</li>
* <li>arrayConstantData (optional)</li>
* </ul>
* Note - this value is different to <tt>tokenDataLength</tt>
*/
public int getEncodedSize() {
return 2 + _byteEncoding.length;
}
/**
* This method is often used when the formula length does not appear immediately before
* the encoded token data.
*
* @return the encoded length of the plain formula tokens. This does <em>not</em> include
* the leading ushort field, nor any trailing array constant data.
*/
public int getEncodedTokenSize() {
return _encodedTokenLen;
}
/**
* Creates a {@link Formula} object from a supplied {@link Ptg} array.
* Handles <code>null</code>s OK.
* @param ptgs may be <code>null</code>
* @return Never <code>null</code> (Possibly empty if the supplied <tt>ptgs</tt> is <code>null</code>)
*/
public static Formula create(Ptg[] ptgs) {
if (ptgs == null || ptgs.length < 1) {
return EMPTY;
}
int totalSize = Ptg.getEncodedSize(ptgs);
byte[] encodedData = new byte[totalSize];
Ptg.serializePtgs(ptgs, encodedData, 0);
int encodedTokenLen = Ptg.getEncodedSizeWithoutArrayData(ptgs);
return new Formula(encodedData, encodedTokenLen);
}
/**
* Gets the {@link Ptg} array from the supplied {@link Formula}.
* Handles <code>null</code>s OK.
*
* @param formula may be <code>null</code>
* @return possibly <code>null</code> (if the supplied <tt>formula</tt> is <code>null</code>)
*/
public static Ptg[] getTokens(Formula formula) {
if (formula == null) {
return null;
}
return formula.getTokens();
}
public Formula copy() {
// OK to return this because immutable
return this;
}
/**
* Gets the locator for the corresponding {@link SharedFormulaRecord}, {@link ArrayRecord} or
* {@link TableRecord} if this formula belongs to such a grouping. The {@link CellReference}
* returned by this method will match the top left corner of the range of that grouping.
* The return value is usually not the same as the location of the cell containing this formula.
*
* @return the firstRow & firstColumn of an array formula or shared formula that this formula
* belongs to. <code>null</code> if this formula is not part of an array or shared formula.
*/
public CellReference getExpReference() {
byte[] data = _byteEncoding;
if (data.length != 5) {
// tExp and tTbl are always 5 bytes long, and the only ptg in the formula
return null;
}
switch (data[0]) {
case ExpPtg.sid:
break;
case TblPtg.sid:
break;
default:
return null;
}
int firstRow = LittleEndian.getUShort(data, 1);
int firstColumn = LittleEndian.getUShort(data, 3);
return new CellReference(firstRow, firstColumn);
}
public boolean isSame(Formula other) {
return Arrays.equals(_byteEncoding, other._byteEncoding);
}
}

+ 55
- 55
src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java Ver arquivo

@@ -1,55 +1,55 @@
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.ss.SpreadsheetVersion;
/**
* Abstracts a workbook for the purpose of formula parsing.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface FormulaParsingWorkbook {
/**
* named range name matching is case insensitive
*/
EvaluationName getName(String name, int sheetIndex);
NameXPtg getNameXPtg(String name);
/**
* gets the externSheet index for a sheet from this workbook
*/
int getExternalSheetIndex(String sheetName);
/**
* gets the externSheet index for a sheet from an external workbook
* @param workbookName e.g. "Budget.xls"
* @param sheetName a name of a sheet in that workbook
*/
int getExternalSheetIndex(String workbookName, String sheetName);
/**
* Returns an enum holding spreadhseet properties specific to an Excel version (
* max column and row numbers, max arguments to a function, etc.)
*/
SpreadsheetVersion getSpreadsheetVersion();
}
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.ss.SpreadsheetVersion;
/**
* Abstracts a workbook for the purpose of formula parsing.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface FormulaParsingWorkbook {
/**
* named range name matching is case insensitive
*/
EvaluationName getName(String name, int sheetIndex);
NameXPtg getNameXPtg(String name);
/**
* gets the externSheet index for a sheet from this workbook
*/
int getExternalSheetIndex(String sheetName);
/**
* gets the externSheet index for a sheet from an external workbook
* @param workbookName e.g. "Budget.xls"
* @param sheetName a name of a sheet in that workbook
*/
int getExternalSheetIndex(String workbookName, String sheetName);
/**
* Returns an enum holding spreadhseet properties specific to an Excel version (
* max column and row numbers, max arguments to a function, etc.)
*/
SpreadsheetVersion getSpreadsheetVersion();
}

+ 131
- 131
src/java/org/apache/poi/ss/formula/FormulaRenderer.java Ver arquivo

@@ -1,131 +1,131 @@
/* ====================================================================
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.ss.formula;
import java.util.Stack;
import org.apache.poi.hssf.record.formula.AttrPtg;
import org.apache.poi.hssf.record.formula.MemAreaPtg;
import org.apache.poi.hssf.record.formula.MemErrPtg;
import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.OperationPtg;
import org.apache.poi.hssf.record.formula.ParenthesisPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Common logic for rendering formulas.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public class FormulaRenderer {
/**
* Static method to convert an array of {@link Ptg}s in RPN order
* to a human readable string format in infix mode.
* @param book used for defined names and 3D references
* @param ptgs must not be <code>null</code>
* @return a human readable String
*/
public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) {
if (ptgs == null || ptgs.length == 0) {
throw new IllegalArgumentException("ptgs must not be null");
}
Stack<String> stack = new Stack<String>();
for (int i=0 ; i < ptgs.length; i++) {
Ptg ptg = ptgs[i];
// TODO - what about MemNoMemPtg?
if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {
// marks the start of a list of area expressions which will be naturally combined
// by their trailing operators (e.g. UnionPtg)
// TODO - put comment and throw exception in toFormulaString() of these classes
continue;
}
if (ptg instanceof ParenthesisPtg) {
String contents = stack.pop();
stack.push ("(" + contents + ")");
continue;
}
if (ptg instanceof AttrPtg) {
AttrPtg attrPtg = ((AttrPtg) ptg);
if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {
continue;
}
if (attrPtg.isSpace()) {
// POI currently doesn't render spaces in formulas
continue;
// but if it ever did, care must be taken:
// tAttrSpace comes *before* the operand it applies to, which may be consistent
// with how the formula text appears but is against the RPN ordering assumed here
}
if (attrPtg.isSemiVolatile()) {
// similar to tAttrSpace - RPN is violated
continue;
}
if (attrPtg.isSum()) {
String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());
stack.push(attrPtg.toFormulaString(operands));
continue;
}
throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());
}
if (ptg instanceof WorkbookDependentFormula) {
WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg;
stack.push(optg.toFormulaString(book));
continue;
}
if (! (ptg instanceof OperationPtg)) {
stack.push(ptg.toFormulaString());
continue;
}
OperationPtg o = (OperationPtg) ptg;
String[] operands = getOperands(stack, o.getNumberOfOperands());
stack.push(o.toFormulaString(operands));
}
if(stack.isEmpty()) {
// inspection of the code above reveals that every stack.pop() is followed by a
// stack.push(). So this is either an internal error or impossible.
throw new IllegalStateException("Stack underflow");
}
String result = stack.pop();
if(!stack.isEmpty()) {
// Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't
// put anything on the stack
throw new IllegalStateException("too much stuff left on the stack");
}
return result;
}
private static String[] getOperands(Stack<String> stack, int nOperands) {
String[] operands = new String[nOperands];
for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order
if(stack.isEmpty()) {
String msg = "Too few arguments supplied to operation. Expected (" + nOperands
+ ") operands but got (" + (nOperands - j - 1) + ")";
throw new IllegalStateException(msg);
}
operands[j] = stack.pop();
}
return operands;
}
}
/* ====================================================================
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.ss.formula;
import java.util.Stack;
import org.apache.poi.hssf.record.formula.AttrPtg;
import org.apache.poi.hssf.record.formula.MemAreaPtg;
import org.apache.poi.hssf.record.formula.MemErrPtg;
import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.OperationPtg;
import org.apache.poi.hssf.record.formula.ParenthesisPtg;
import org.apache.poi.hssf.record.formula.Ptg;
/**
* Common logic for rendering formulas.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public class FormulaRenderer {
/**
* Static method to convert an array of {@link Ptg}s in RPN order
* to a human readable string format in infix mode.
* @param book used for defined names and 3D references
* @param ptgs must not be <code>null</code>
* @return a human readable String
*/
public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) {
if (ptgs == null || ptgs.length == 0) {
throw new IllegalArgumentException("ptgs must not be null");
}
Stack<String> stack = new Stack<String>();
for (int i=0 ; i < ptgs.length; i++) {
Ptg ptg = ptgs[i];
// TODO - what about MemNoMemPtg?
if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {
// marks the start of a list of area expressions which will be naturally combined
// by their trailing operators (e.g. UnionPtg)
// TODO - put comment and throw exception in toFormulaString() of these classes
continue;
}
if (ptg instanceof ParenthesisPtg) {
String contents = stack.pop();
stack.push ("(" + contents + ")");
continue;
}
if (ptg instanceof AttrPtg) {
AttrPtg attrPtg = ((AttrPtg) ptg);
if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {
continue;
}
if (attrPtg.isSpace()) {
// POI currently doesn't render spaces in formulas
continue;
// but if it ever did, care must be taken:
// tAttrSpace comes *before* the operand it applies to, which may be consistent
// with how the formula text appears but is against the RPN ordering assumed here
}
if (attrPtg.isSemiVolatile()) {
// similar to tAttrSpace - RPN is violated
continue;
}
if (attrPtg.isSum()) {
String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());
stack.push(attrPtg.toFormulaString(operands));
continue;
}
throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());
}
if (ptg instanceof WorkbookDependentFormula) {
WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg;
stack.push(optg.toFormulaString(book));
continue;
}
if (! (ptg instanceof OperationPtg)) {
stack.push(ptg.toFormulaString());
continue;
}
OperationPtg o = (OperationPtg) ptg;
String[] operands = getOperands(stack, o.getNumberOfOperands());
stack.push(o.toFormulaString(operands));
}
if(stack.isEmpty()) {
// inspection of the code above reveals that every stack.pop() is followed by a
// stack.push(). So this is either an internal error or impossible.
throw new IllegalStateException("Stack underflow");
}
String result = stack.pop();
if(!stack.isEmpty()) {
// Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't
// put anything on the stack
throw new IllegalStateException("too much stuff left on the stack");
}
return result;
}
private static String[] getOperands(Stack<String> stack, int nOperands) {
String[] operands = new String[nOperands];
for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order
if(stack.isEmpty()) {
String msg = "Too few arguments supplied to operation. Expected (" + nOperands
+ ") operands but got (" + (nOperands - j - 1) + ")";
throw new IllegalStateException(msg);
}
operands[j] = stack.pop();
}
return operands;
}
}

+ 40
- 40
src/java/org/apache/poi/ss/formula/FormulaRenderingWorkbook.java Ver arquivo

@@ -1,40 +1,40 @@
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
/**
* Abstracts a workbook for the purpose of converting formula to text.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface FormulaRenderingWorkbook {
/**
* @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
*/
ExternalSheet getExternalSheet(int externSheetIndex);
String getSheetNameByExternSheet(int externSheetIndex);
String resolveNameXText(NameXPtg nameXPtg);
String getNameText(NamePtg namePtg);
}
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
/**
* Abstracts a workbook for the purpose of converting formula to text.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface FormulaRenderingWorkbook {
/**
* @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
*/
ExternalSheet getExternalSheet(int externSheetIndex);
String getSheetNameByExternSheet(int externSheetIndex);
String resolveNameXText(NameXPtg nameXPtg);
String getNameText(NamePtg namePtg);
}

+ 40
- 40
src/java/org/apache/poi/ss/formula/FormulaType.java Ver arquivo

@@ -1,40 +1,40 @@
/* ====================================================================
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.ss.formula;
/**
* Enumeration of various formula types.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public final class FormulaType {
private FormulaType() {
// no instances of this class
}
public static final int CELL = 0;
public static final int SHARED = 1;
public static final int ARRAY =2;
public static final int CONDFORMAT = 3;
public static final int NAMEDRANGE = 4;
// this constant is currently very specific. The exact differences from general data
// validation formulas or conditional format formulas is not known yet
public static final int DATAVALIDATION_LIST = 5;
}
/* ====================================================================
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.ss.formula;
/**
* Enumeration of various formula types.<br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public final class FormulaType {
private FormulaType() {
// no instances of this class
}
public static final int CELL = 0;
public static final int SHARED = 1;
public static final int ARRAY =2;
public static final int CONDFORMAT = 3;
public static final int NAMEDRANGE = 4;
// this constant is currently very specific. The exact differences from general data
// validation formulas or conditional format formulas is not known yet
public static final int DATAVALIDATION_LIST = 5;
}

+ 68
- 68
src/java/org/apache/poi/ss/formula/LazyRefEval.java Ver arquivo

@@ -1,68 +1,68 @@
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.AreaI;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.RefEvalBase;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.util.CellReference;
/**
*
* @author Josh Micich
*/
final class LazyRefEval extends RefEvalBase {
private final SheetRefEvaluator _evaluator;
public LazyRefEval(RefPtg ptg, SheetRefEvaluator sre) {
super(ptg.getRow(), ptg.getColumn());
_evaluator = sre;
}
public LazyRefEval(Ref3DPtg ptg, SheetRefEvaluator sre) {
super(ptg.getRow(), ptg.getColumn());
_evaluator = sre;
}
public ValueEval getInnerValueEval() {
return _evaluator.getEvalForCell(getRow(), getColumn());
}
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
AreaI area = new OffsetArea(getRow(), getColumn(),
relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
return new LazyAreaEval(area, _evaluator);
}
public String toString() {
CellReference cr = new CellReference(getRow(), getColumn());
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName()).append("[");
sb.append(_evaluator.getSheetName());
sb.append('!');
sb.append(cr.formatAsString());
sb.append("]");
return sb.toString();
}
}
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.AreaI;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
import org.apache.poi.hssf.record.formula.RefPtg;
import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
import org.apache.poi.hssf.record.formula.eval.AreaEval;
import org.apache.poi.hssf.record.formula.eval.RefEvalBase;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.util.CellReference;
/**
*
* @author Josh Micich
*/
final class LazyRefEval extends RefEvalBase {
private final SheetRefEvaluator _evaluator;
public LazyRefEval(RefPtg ptg, SheetRefEvaluator sre) {
super(ptg.getRow(), ptg.getColumn());
_evaluator = sre;
}
public LazyRefEval(Ref3DPtg ptg, SheetRefEvaluator sre) {
super(ptg.getRow(), ptg.getColumn());
_evaluator = sre;
}
public ValueEval getInnerValueEval() {
return _evaluator.getEvalForCell(getRow(), getColumn());
}
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
AreaI area = new OffsetArea(getRow(), getColumn(),
relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
return new LazyAreaEval(area, _evaluator);
}
public String toString() {
CellReference cr = new CellReference(getRow(), getColumn());
StringBuffer sb = new StringBuffer();
sb.append(getClass().getName()).append("[");
sb.append(_evaluator.getSheetName());
sb.append('!');
sb.append(cr.formatAsString());
sb.append("]");
return sb.toString();
}
}

+ 48
- 48
src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java Ver arquivo

@@ -1,48 +1,48 @@
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
*
*
* @author Josh Micich
*/
final class SheetRefEvaluator {
private final WorkbookEvaluator _bookEvaluator;
private final EvaluationTracker _tracker;
private final EvaluationSheet _sheet;
private final int _sheetIndex;
public SheetRefEvaluator(WorkbookEvaluator bookEvaluator, EvaluationTracker tracker,
EvaluationWorkbook _workbook, int sheetIndex) {
_bookEvaluator = bookEvaluator;
_tracker = tracker;
_sheet = _workbook.getSheet(sheetIndex);
_sheetIndex = sheetIndex;
}
public String getSheetName() {
return _bookEvaluator.getSheetName(_sheetIndex);
}
public ValueEval getEvalForCell(int rowIndex, int columnIndex) {
return _bookEvaluator.evaluateReference(_sheet, _sheetIndex, rowIndex, columnIndex, _tracker);
}
}
/* ====================================================================
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.ss.formula;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
/**
*
*
* @author Josh Micich
*/
final class SheetRefEvaluator {
private final WorkbookEvaluator _bookEvaluator;
private final EvaluationTracker _tracker;
private final EvaluationSheet _sheet;
private final int _sheetIndex;
public SheetRefEvaluator(WorkbookEvaluator bookEvaluator, EvaluationTracker tracker,
EvaluationWorkbook _workbook, int sheetIndex) {
_bookEvaluator = bookEvaluator;
_tracker = tracker;
_sheet = _workbook.getSheet(sheetIndex);
_sheetIndex = sheetIndex;
}
public String getSheetName() {
return _bookEvaluator.getSheetName(_sheetIndex);
}
public ValueEval getEvalForCell(int rowIndex, int columnIndex) {
return _bookEvaluator.evaluateReference(_sheet, _sheetIndex, rowIndex, columnIndex, _tracker);
}
}

+ 30
- 30
src/java/org/apache/poi/ss/formula/WorkbookDependentFormula.java Ver arquivo

@@ -1,30 +1,30 @@
/* ====================================================================
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.ss.formula;
/**
* Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs a workbook to render its formula.
* <br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface WorkbookDependentFormula {
String toFormulaString(FormulaRenderingWorkbook book);
}
/* ====================================================================
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.ss.formula;
/**
* Should be implemented by any {@link org.apache.poi.hssf.record.formula.Ptg} subclass that needs a workbook to render its formula.
* <br/>
*
* For POI internal use only
*
* @author Josh Micich
*/
public interface WorkbookDependentFormula {
String toFormulaString(FormulaRenderingWorkbook book);
}

+ 36
- 36
src/java/org/apache/poi/ss/formula/eval/NotImplementedException.java Ver arquivo

@@ -1,36 +1,36 @@
/* ====================================================================
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.ss.formula.eval;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
/**
* An exception thrown by implementors of {@link FormulaEvaluator} when attempting to evaluate
* a formula which requires features that POI does not (yet) support.
*
* @author Josh Micich
*/
public final class NotImplementedException extends RuntimeException {
public NotImplementedException(String message) {
super(message);
}
public NotImplementedException(String message, NotImplementedException cause) {
super(message, cause);
}
}
/* ====================================================================
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.ss.formula.eval;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
/**
* An exception thrown by implementors of {@link FormulaEvaluator} when attempting to evaluate
* a formula which requires features that POI does not (yet) support.
*
* @author Josh Micich
*/
public final class NotImplementedException extends RuntimeException {
public NotImplementedException(String message) {
super(message);
}
public NotImplementedException(String message, NotImplementedException cause) {
super(message, cause);
}
}

+ 132
- 132
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationCell.java Ver arquivo

@@ -1,132 +1,132 @@
/* ====================================================================
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.ss.formula.eval.forked;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.usermodel.Cell;
/**
* Represents a cell being used for forked evaluation that has had a value set different from the
* corresponding cell in the shared master workbook.
*
* @author Josh Micich
*/
final class ForkedEvaluationCell implements EvaluationCell {
private final EvaluationSheet _sheet;
/** corresponding cell from master workbook */
private final EvaluationCell _masterCell;
private boolean _booleanValue;
private int _cellType;
private int _errorValue;
private double _numberValue;
private String _stringValue;
public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) {
_sheet = sheet;
_masterCell = masterCell;
// start with value blank, but expect construction to be immediately
setValue(BlankEval.INSTANCE); // followed by a proper call to setValue()
}
public Object getIdentityKey() {
return _masterCell.getIdentityKey();
}
public void setValue(ValueEval value) {
Class<? extends ValueEval> cls = value.getClass();
if (cls == NumberEval.class) {
_cellType = HSSFCell.CELL_TYPE_NUMERIC;
_numberValue = ((NumberEval)value).getNumberValue();
return;
}
if (cls == StringEval.class) {
_cellType = HSSFCell.CELL_TYPE_STRING;
_stringValue = ((StringEval)value).getStringValue();
return;
}
if (cls == BoolEval.class) {
_cellType = HSSFCell.CELL_TYPE_BOOLEAN;
_booleanValue = ((BoolEval)value).getBooleanValue();
return;
}
if (cls == ErrorEval.class) {
_cellType = HSSFCell.CELL_TYPE_ERROR;
_errorValue = ((ErrorEval)value).getErrorCode();
return;
}
if (cls == BlankEval.class) {
_cellType = HSSFCell.CELL_TYPE_BLANK;
return;
}
throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")");
}
public void copyValue(Cell destCell) {
switch (_cellType) {
case Cell.CELL_TYPE_BLANK: destCell.setCellType(Cell.CELL_TYPE_BLANK); return;
case Cell.CELL_TYPE_NUMERIC: destCell.setCellValue(_numberValue); return;
case Cell.CELL_TYPE_BOOLEAN: destCell.setCellValue(_booleanValue); return;
case Cell.CELL_TYPE_STRING: destCell.setCellValue(_stringValue); return;
case Cell.CELL_TYPE_ERROR: destCell.setCellErrorValue((byte)_errorValue); return;
}
throw new IllegalStateException("Unexpected data type (" + _cellType + ")");
}
private void checkCellType(int expectedCellType) {
if (_cellType != expectedCellType) {
throw new RuntimeException("Wrong data type (" + _cellType + ")");
}
}
public int getCellType() {
return _cellType;
}
public boolean getBooleanCellValue() {
checkCellType(HSSFCell.CELL_TYPE_BOOLEAN);
return _booleanValue;
}
public int getErrorCellValue() {
checkCellType(HSSFCell.CELL_TYPE_ERROR);
return _errorValue;
}
public double getNumericCellValue() {
checkCellType(HSSFCell.CELL_TYPE_NUMERIC);
return _numberValue;
}
public String getStringCellValue() {
checkCellType(HSSFCell.CELL_TYPE_STRING);
return _stringValue;
}
public EvaluationSheet getSheet() {
return _sheet;
}
public int getRowIndex() {
return _masterCell.getRowIndex();
}
public int getColumnIndex() {
return _masterCell.getColumnIndex();
}
}
/* ====================================================================
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.ss.formula.eval.forked;
import org.apache.poi.hssf.record.formula.eval.BlankEval;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.usermodel.Cell;
/**
* Represents a cell being used for forked evaluation that has had a value set different from the
* corresponding cell in the shared master workbook.
*
* @author Josh Micich
*/
final class ForkedEvaluationCell implements EvaluationCell {
private final EvaluationSheet _sheet;
/** corresponding cell from master workbook */
private final EvaluationCell _masterCell;
private boolean _booleanValue;
private int _cellType;
private int _errorValue;
private double _numberValue;
private String _stringValue;
public ForkedEvaluationCell(ForkedEvaluationSheet sheet, EvaluationCell masterCell) {
_sheet = sheet;
_masterCell = masterCell;
// start with value blank, but expect construction to be immediately
setValue(BlankEval.INSTANCE); // followed by a proper call to setValue()
}
public Object getIdentityKey() {
return _masterCell.getIdentityKey();
}
public void setValue(ValueEval value) {
Class<? extends ValueEval> cls = value.getClass();
if (cls == NumberEval.class) {
_cellType = HSSFCell.CELL_TYPE_NUMERIC;
_numberValue = ((NumberEval)value).getNumberValue();
return;
}
if (cls == StringEval.class) {
_cellType = HSSFCell.CELL_TYPE_STRING;
_stringValue = ((StringEval)value).getStringValue();
return;
}
if (cls == BoolEval.class) {
_cellType = HSSFCell.CELL_TYPE_BOOLEAN;
_booleanValue = ((BoolEval)value).getBooleanValue();
return;
}
if (cls == ErrorEval.class) {
_cellType = HSSFCell.CELL_TYPE_ERROR;
_errorValue = ((ErrorEval)value).getErrorCode();
return;
}
if (cls == BlankEval.class) {
_cellType = HSSFCell.CELL_TYPE_BLANK;
return;
}
throw new IllegalArgumentException("Unexpected value class (" + cls.getName() + ")");
}
public void copyValue(Cell destCell) {
switch (_cellType) {
case Cell.CELL_TYPE_BLANK: destCell.setCellType(Cell.CELL_TYPE_BLANK); return;
case Cell.CELL_TYPE_NUMERIC: destCell.setCellValue(_numberValue); return;
case Cell.CELL_TYPE_BOOLEAN: destCell.setCellValue(_booleanValue); return;
case Cell.CELL_TYPE_STRING: destCell.setCellValue(_stringValue); return;
case Cell.CELL_TYPE_ERROR: destCell.setCellErrorValue((byte)_errorValue); return;
}
throw new IllegalStateException("Unexpected data type (" + _cellType + ")");
}
private void checkCellType(int expectedCellType) {
if (_cellType != expectedCellType) {
throw new RuntimeException("Wrong data type (" + _cellType + ")");
}
}
public int getCellType() {
return _cellType;
}
public boolean getBooleanCellValue() {
checkCellType(HSSFCell.CELL_TYPE_BOOLEAN);
return _booleanValue;
}
public int getErrorCellValue() {
checkCellType(HSSFCell.CELL_TYPE_ERROR);
return _errorValue;
}
public double getNumericCellValue() {
checkCellType(HSSFCell.CELL_TYPE_NUMERIC);
return _numberValue;
}
public String getStringCellValue() {
checkCellType(HSSFCell.CELL_TYPE_STRING);
return _stringValue;
}
public EvaluationSheet getSheet() {
return _sheet;
}
public int getRowIndex() {
return _masterCell.getRowIndex();
}
public int getColumnIndex() {
return _masterCell.getColumnIndex();
}
}

+ 129
- 129
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java Ver arquivo

@@ -1,129 +1,129 @@
/* ====================================================================
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.ss.formula.eval.forked;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/**
* Represents a sheet being used for forked evaluation. Initially, objects of this class contain
* only the cells from the master workbook. By calling {@link #getOrCreateUpdatableCell(int, int)},
* the master cell object is logically replaced with a {@link ForkedEvaluationCell} instance, which
* will be used in all subsequent evaluations.
*
* @author Josh Micich
*/
final class ForkedEvaluationSheet implements EvaluationSheet {
private final EvaluationSheet _masterSheet;
/**
* Only cells which have been split are put in this map. (This has been done to conserve memory).
*/
private final Map<RowColKey, ForkedEvaluationCell> _sharedCellsByRowCol;
public ForkedEvaluationSheet(EvaluationSheet masterSheet) {
_masterSheet = masterSheet;
_sharedCellsByRowCol = new HashMap<RowColKey, ForkedEvaluationCell>();
}
public EvaluationCell getCell(int rowIndex, int columnIndex) {
RowColKey key = new RowColKey(rowIndex, columnIndex);
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
if (result == null) {
return _masterSheet.getCell(rowIndex, columnIndex);
}
return result;
}
public ForkedEvaluationCell getOrCreateUpdatableCell(int rowIndex, int columnIndex) {
RowColKey key = new RowColKey(rowIndex, columnIndex);
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
if (result == null) {
EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex);
result = new ForkedEvaluationCell(this, mcell);
_sharedCellsByRowCol.put(key, result);
}
return result;
}
public void copyUpdatedCells(Sheet sheet) {
RowColKey[] keys = new RowColKey[_sharedCellsByRowCol.size()];
_sharedCellsByRowCol.keySet().toArray(keys);
Arrays.sort(keys);
for (int i = 0; i < keys.length; i++) {
RowColKey key = keys[i];
Row row = sheet.getRow(key.getRowIndex());
if (row == null) {
row = sheet.createRow(key.getRowIndex());
}
Cell destCell = row.getCell(key.getColumnIndex());
if (destCell == null) {
destCell = row.createCell(key.getColumnIndex());
}
ForkedEvaluationCell srcCell = _sharedCellsByRowCol.get(key);
srcCell.copyValue(destCell);
}
}
public int getSheetIndex(EvaluationWorkbook mewb) {
return mewb.getSheetIndex(_masterSheet);
}
private static final class RowColKey implements Comparable<RowColKey>{
private final int _rowIndex;
private final int _columnIndex;
public RowColKey(int rowIndex, int columnIndex) {
_rowIndex = rowIndex;
_columnIndex = columnIndex;
}
@Override
public boolean equals(Object obj) {
RowColKey other = (RowColKey) obj;
return _rowIndex == other._rowIndex && _columnIndex == other._columnIndex;
}
@Override
public int hashCode() {
return _rowIndex ^ _columnIndex;
}
public int compareTo(RowColKey o) {
int cmp = _rowIndex - o._rowIndex;
if (cmp != 0) {
return cmp;
}
return _columnIndex - o._columnIndex;
}
public int getRowIndex() {
return _rowIndex;
}
public int getColumnIndex() {
return _columnIndex;
}
}
}
/* ====================================================================
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.ss.formula.eval.forked;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/**
* Represents a sheet being used for forked evaluation. Initially, objects of this class contain
* only the cells from the master workbook. By calling {@link #getOrCreateUpdatableCell(int, int)},
* the master cell object is logically replaced with a {@link ForkedEvaluationCell} instance, which
* will be used in all subsequent evaluations.
*
* @author Josh Micich
*/
final class ForkedEvaluationSheet implements EvaluationSheet {
private final EvaluationSheet _masterSheet;
/**
* Only cells which have been split are put in this map. (This has been done to conserve memory).
*/
private final Map<RowColKey, ForkedEvaluationCell> _sharedCellsByRowCol;
public ForkedEvaluationSheet(EvaluationSheet masterSheet) {
_masterSheet = masterSheet;
_sharedCellsByRowCol = new HashMap<RowColKey, ForkedEvaluationCell>();
}
public EvaluationCell getCell(int rowIndex, int columnIndex) {
RowColKey key = new RowColKey(rowIndex, columnIndex);
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
if (result == null) {
return _masterSheet.getCell(rowIndex, columnIndex);
}
return result;
}
public ForkedEvaluationCell getOrCreateUpdatableCell(int rowIndex, int columnIndex) {
RowColKey key = new RowColKey(rowIndex, columnIndex);
ForkedEvaluationCell result = _sharedCellsByRowCol.get(key);
if (result == null) {
EvaluationCell mcell = _masterSheet.getCell(rowIndex, columnIndex);
result = new ForkedEvaluationCell(this, mcell);
_sharedCellsByRowCol.put(key, result);
}
return result;
}
public void copyUpdatedCells(Sheet sheet) {
RowColKey[] keys = new RowColKey[_sharedCellsByRowCol.size()];
_sharedCellsByRowCol.keySet().toArray(keys);
Arrays.sort(keys);
for (int i = 0; i < keys.length; i++) {
RowColKey key = keys[i];
Row row = sheet.getRow(key.getRowIndex());
if (row == null) {
row = sheet.createRow(key.getRowIndex());
}
Cell destCell = row.getCell(key.getColumnIndex());
if (destCell == null) {
destCell = row.createCell(key.getColumnIndex());
}
ForkedEvaluationCell srcCell = _sharedCellsByRowCol.get(key);
srcCell.copyValue(destCell);
}
}
public int getSheetIndex(EvaluationWorkbook mewb) {
return mewb.getSheetIndex(_masterSheet);
}
private static final class RowColKey implements Comparable<RowColKey>{
private final int _rowIndex;
private final int _columnIndex;
public RowColKey(int rowIndex, int columnIndex) {
_rowIndex = rowIndex;
_columnIndex = columnIndex;
}
@Override
public boolean equals(Object obj) {
RowColKey other = (RowColKey) obj;
return _rowIndex == other._rowIndex && _columnIndex == other._columnIndex;
}
@Override
public int hashCode() {
return _rowIndex ^ _columnIndex;
}
public int compareTo(RowColKey o) {
int cmp = _rowIndex - o._rowIndex;
if (cmp != 0) {
return cmp;
}
return _columnIndex - o._columnIndex;
}
public int getRowIndex() {
return _rowIndex;
}
public int getColumnIndex() {
return _columnIndex;
}
}
}

+ 144
- 144
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java Ver arquivo

@@ -1,144 +1,144 @@
/* ====================================================================
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.ss.formula.eval.forked;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationName;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
/**
* Represents a workbook being used for forked evaluation. Most operations are delegated to the
* shared master workbook, except those that potentially involve cell values that may have been
* updated after a call to {@link #getOrCreateUpdatableCell(String, int, int)}.
*
* @author Josh Micich
*/
final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
private final EvaluationWorkbook _masterBook;
private final Map<String, ForkedEvaluationSheet> _sharedSheetsByName;
public ForkedEvaluationWorkbook(EvaluationWorkbook master) {
_masterBook = master;
_sharedSheetsByName = new HashMap<String, ForkedEvaluationSheet>();
}
public ForkedEvaluationCell getOrCreateUpdatableCell(String sheetName, int rowIndex,
int columnIndex) {
ForkedEvaluationSheet sheet = getSharedSheet(sheetName);
return sheet.getOrCreateUpdatableCell(rowIndex, columnIndex);
}
public EvaluationCell getEvaluationCell(String sheetName, int rowIndex, int columnIndex) {
ForkedEvaluationSheet sheet = getSharedSheet(sheetName);
return sheet.getCell(rowIndex, columnIndex);
}
private ForkedEvaluationSheet getSharedSheet(String sheetName) {
ForkedEvaluationSheet result = _sharedSheetsByName.get(sheetName);
if (result == null) {
result = new ForkedEvaluationSheet(_masterBook.getSheet(_masterBook
.getSheetIndex(sheetName)));
_sharedSheetsByName.put(sheetName, result);
}
return result;
}
public void copyUpdatedCells(Workbook workbook) {
String[] sheetNames = new String[_sharedSheetsByName.size()];
_sharedSheetsByName.keySet().toArray(sheetNames);
OrderedSheet[] oss = new OrderedSheet[sheetNames.length];
for (int i = 0; i < sheetNames.length; i++) {
String sheetName = sheetNames[i];
oss[i] = new OrderedSheet(sheetName, _masterBook.getSheetIndex(sheetName));
}
for (int i = 0; i < oss.length; i++) {
String sheetName = oss[i].getSheetName();
ForkedEvaluationSheet sheet = _sharedSheetsByName.get(sheetName);
sheet.copyUpdatedCells(workbook.getSheet(sheetName));
}
}
public int convertFromExternSheetIndex(int externSheetIndex) {
return _masterBook.convertFromExternSheetIndex(externSheetIndex);
}
public ExternalSheet getExternalSheet(int externSheetIndex) {
return _masterBook.getExternalSheet(externSheetIndex);
}
public Ptg[] getFormulaTokens(EvaluationCell cell) {
if (cell instanceof ForkedEvaluationCell) {
// doesn't happen yet because formulas cannot be modified from the master workbook
throw new RuntimeException("Updated formulas not supported yet");
}
return _masterBook.getFormulaTokens(cell);
}
public EvaluationName getName(NamePtg namePtg) {
return _masterBook.getName(namePtg);
}
public EvaluationSheet getSheet(int sheetIndex) {
return getSharedSheet(getSheetName(sheetIndex));
}
public int getSheetIndex(EvaluationSheet sheet) {
if (sheet instanceof ForkedEvaluationSheet) {
ForkedEvaluationSheet mes = (ForkedEvaluationSheet) sheet;
return mes.getSheetIndex(_masterBook);
}
return _masterBook.getSheetIndex(sheet);
}
public int getSheetIndex(String sheetName) {
return _masterBook.getSheetIndex(sheetName);
}
public String getSheetName(int sheetIndex) {
return _masterBook.getSheetName(sheetIndex);
}
public String resolveNameXText(NameXPtg ptg) {
return _masterBook.resolveNameXText(ptg);
}
private static final class OrderedSheet implements Comparable<OrderedSheet> {
private final String _sheetName;
private final int _index;
public OrderedSheet(String sheetName, int index) {
_sheetName = sheetName;
_index = index;
}
public String getSheetName() {
return _sheetName;
}
public int compareTo(OrderedSheet o) {
return _index - o._index;
}
}
}
/* ====================================================================
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.ss.formula.eval.forked;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.record.formula.NamePtg;
import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationName;
import org.apache.poi.ss.formula.EvaluationSheet;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
/**
* Represents a workbook being used for forked evaluation. Most operations are delegated to the
* shared master workbook, except those that potentially involve cell values that may have been
* updated after a call to {@link #getOrCreateUpdatableCell(String, int, int)}.
*
* @author Josh Micich
*/
final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
private final EvaluationWorkbook _masterBook;
private final Map<String, ForkedEvaluationSheet> _sharedSheetsByName;
public ForkedEvaluationWorkbook(EvaluationWorkbook master) {
_masterBook = master;
_sharedSheetsByName = new HashMap<String, ForkedEvaluationSheet>();
}
public ForkedEvaluationCell getOrCreateUpdatableCell(String sheetName, int rowIndex,
int columnIndex) {
ForkedEvaluationSheet sheet = getSharedSheet(sheetName);
return sheet.getOrCreateUpdatableCell(rowIndex, columnIndex);
}
public EvaluationCell getEvaluationCell(String sheetName, int rowIndex, int columnIndex) {
ForkedEvaluationSheet sheet = getSharedSheet(sheetName);
return sheet.getCell(rowIndex, columnIndex);
}
private ForkedEvaluationSheet getSharedSheet(String sheetName) {
ForkedEvaluationSheet result = _sharedSheetsByName.get(sheetName);
if (result == null) {
result = new ForkedEvaluationSheet(_masterBook.getSheet(_masterBook
.getSheetIndex(sheetName)));
_sharedSheetsByName.put(sheetName, result);
}
return result;
}
public void copyUpdatedCells(Workbook workbook) {
String[] sheetNames = new String[_sharedSheetsByName.size()];
_sharedSheetsByName.keySet().toArray(sheetNames);
OrderedSheet[] oss = new OrderedSheet[sheetNames.length];
for (int i = 0; i < sheetNames.length; i++) {
String sheetName = sheetNames[i];
oss[i] = new OrderedSheet(sheetName, _masterBook.getSheetIndex(sheetName));
}
for (int i = 0; i < oss.length; i++) {
String sheetName = oss[i].getSheetName();
ForkedEvaluationSheet sheet = _sharedSheetsByName.get(sheetName);
sheet.copyUpdatedCells(workbook.getSheet(sheetName));
}
}
public int convertFromExternSheetIndex(int externSheetIndex) {
return _masterBook.convertFromExternSheetIndex(externSheetIndex);
}
public ExternalSheet getExternalSheet(int externSheetIndex) {
return _masterBook.getExternalSheet(externSheetIndex);
}
public Ptg[] getFormulaTokens(EvaluationCell cell) {
if (cell instanceof ForkedEvaluationCell) {
// doesn't happen yet because formulas cannot be modified from the master workbook
throw new RuntimeException("Updated formulas not supported yet");
}
return _masterBook.getFormulaTokens(cell);
}
public EvaluationName getName(NamePtg namePtg) {
return _masterBook.getName(namePtg);
}
public EvaluationSheet getSheet(int sheetIndex) {
return getSharedSheet(getSheetName(sheetIndex));
}
public int getSheetIndex(EvaluationSheet sheet) {
if (sheet instanceof ForkedEvaluationSheet) {
ForkedEvaluationSheet mes = (ForkedEvaluationSheet) sheet;
return mes.getSheetIndex(_masterBook);
}
return _masterBook.getSheetIndex(sheet);
}
public int getSheetIndex(String sheetName) {
return _masterBook.getSheetIndex(sheetName);
}
public String getSheetName(int sheetIndex) {
return _masterBook.getSheetName(sheetIndex);
}
public String resolveNameXText(NameXPtg ptg) {
return _masterBook.resolveNameXText(ptg);
}
private static final class OrderedSheet implements Comparable<OrderedSheet> {
private final String _sheetName;
private final int _index;
public OrderedSheet(String sheetName, int index) {
_sheetName = sheetName;
_index = index;
}
public String getSheetName() {
return _sheetName;
}
public int compareTo(OrderedSheet o) {
return _index - o._index;
}
}
}

+ 133
- 133
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluator.java Ver arquivo

@@ -1,133 +1,133 @@
/* ====================================================================
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.ss.formula.eval.forked;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.usermodel.Workbook;
/**
* An alternative workbook evaluator that saves memory in situations where a single workbook is
* concurrently and independently evaluated many times. With standard formula evaluation, around
* 90% of memory consumption is due to loading of the {@link HSSFWorkbook} or {@link org.apache.poi.xssf.usermodel.XSSFWorkbook}.
* This class enables a 'master workbook' to be loaded just once and shared between many evaluation
* clients. Each evaluation client creates its own {@link ForkedEvaluator} and can set cell values
* that will be used for local evaluations (and don't disturb evaluations on other evaluators).
*
* @author Josh Micich
*/
public final class ForkedEvaluator {
private WorkbookEvaluator _evaluator;
private ForkedEvaluationWorkbook _sewb;
private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier) {
_sewb = new ForkedEvaluationWorkbook(masterWorkbook);
_evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier);
}
private static EvaluationWorkbook createEvaluationWorkbook(Workbook wb) {
if (wb instanceof HSSFWorkbook) {
return HSSFEvaluationWorkbook.create((HSSFWorkbook) wb);
}
// TODO rearrange POI build to allow this
// if (wb instanceof XSSFWorkbook) {
// return XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
// }
throw new IllegalArgumentException("Unexpected workbook type (" + wb.getClass().getName() + ")");
}
public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier) {
return new ForkedEvaluator(createEvaluationWorkbook(wb), stabilityClassifier);
}
/**
* Sets the specified cell to the supplied <tt>value</tt>
* @param sheetName the name of the sheet containing the cell
* @param rowIndex zero based
* @param columnIndex zero based
*/
public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) {
ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex);
cell.setValue(value);
_evaluator.notifyUpdateCell(cell);
}
/**
* Copies the values of all updated cells (modified by calls to {@link
* #updateCell(String, int, int, ValueEval)}) to the supplied <tt>workbook</tt>.<br/>
* Typically, the supplied <tt>workbook</tt> is a writable copy of the 'master workbook',
* but at the very least it must contain sheets with the same names.
*/
public void copyUpdatedCells(Workbook workbook) {
_sewb.copyUpdatedCells(workbook);
}
/**
* If cell contains a formula, the formula is evaluated and returned,
* else the CellValue simply copies the appropriate cell value from
* the cell and also its cell type. This method should be preferred over
* evaluateInCell() when the call should not modify the contents of the
* original cell.
*
* @param cell may be <code>null</code> signifying that the cell is not present (or blank)
* @return <code>null</code> if the supplied cell is <code>null</code> or blank
*/
public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) {
EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex);
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
return BoolEval.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_ERROR:
return ErrorEval.valueOf(cell.getErrorCellValue());
case HSSFCell.CELL_TYPE_FORMULA:
return _evaluator.evaluate(cell);
case HSSFCell.CELL_TYPE_NUMERIC:
return new NumberEval(cell.getNumericCellValue());
case HSSFCell.CELL_TYPE_STRING:
return new StringEval(cell.getStringCellValue());
case HSSFCell.CELL_TYPE_BLANK:
return null;
}
throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
}
/**
* Coordinates several formula evaluators together so that formulas that involve external
* references can be evaluated.
* @param workbookNames the simple file names used to identify the workbooks in formulas
* with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
* @param evaluators all evaluators for the full set of workbooks required by the formulas.
*/
public static void setupEnvironment(String[] workbookNames, ForkedEvaluator[] evaluators) {
WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length];
for (int i = 0; i < wbEvals.length; i++) {
wbEvals[i] = evaluators[i]._evaluator;
}
CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
}
}
/* ====================================================================
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.ss.formula.eval.forked;
import org.apache.poi.hssf.record.formula.eval.BoolEval;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
import org.apache.poi.hssf.record.formula.eval.StringEval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.usermodel.Workbook;
/**
* An alternative workbook evaluator that saves memory in situations where a single workbook is
* concurrently and independently evaluated many times. With standard formula evaluation, around
* 90% of memory consumption is due to loading of the {@link HSSFWorkbook} or {@link org.apache.poi.xssf.usermodel.XSSFWorkbook}.
* This class enables a 'master workbook' to be loaded just once and shared between many evaluation
* clients. Each evaluation client creates its own {@link ForkedEvaluator} and can set cell values
* that will be used for local evaluations (and don't disturb evaluations on other evaluators).
*
* @author Josh Micich
*/
public final class ForkedEvaluator {
private WorkbookEvaluator _evaluator;
private ForkedEvaluationWorkbook _sewb;
private ForkedEvaluator(EvaluationWorkbook masterWorkbook, IStabilityClassifier stabilityClassifier) {
_sewb = new ForkedEvaluationWorkbook(masterWorkbook);
_evaluator = new WorkbookEvaluator(_sewb, stabilityClassifier);
}
private static EvaluationWorkbook createEvaluationWorkbook(Workbook wb) {
if (wb instanceof HSSFWorkbook) {
return HSSFEvaluationWorkbook.create((HSSFWorkbook) wb);
}
// TODO rearrange POI build to allow this
// if (wb instanceof XSSFWorkbook) {
// return XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
// }
throw new IllegalArgumentException("Unexpected workbook type (" + wb.getClass().getName() + ")");
}
public static ForkedEvaluator create(Workbook wb, IStabilityClassifier stabilityClassifier) {
return new ForkedEvaluator(createEvaluationWorkbook(wb), stabilityClassifier);
}
/**
* Sets the specified cell to the supplied <tt>value</tt>
* @param sheetName the name of the sheet containing the cell
* @param rowIndex zero based
* @param columnIndex zero based
*/
public void updateCell(String sheetName, int rowIndex, int columnIndex, ValueEval value) {
ForkedEvaluationCell cell = _sewb.getOrCreateUpdatableCell(sheetName, rowIndex, columnIndex);
cell.setValue(value);
_evaluator.notifyUpdateCell(cell);
}
/**
* Copies the values of all updated cells (modified by calls to {@link
* #updateCell(String, int, int, ValueEval)}) to the supplied <tt>workbook</tt>.<br/>
* Typically, the supplied <tt>workbook</tt> is a writable copy of the 'master workbook',
* but at the very least it must contain sheets with the same names.
*/
public void copyUpdatedCells(Workbook workbook) {
_sewb.copyUpdatedCells(workbook);
}
/**
* If cell contains a formula, the formula is evaluated and returned,
* else the CellValue simply copies the appropriate cell value from
* the cell and also its cell type. This method should be preferred over
* evaluateInCell() when the call should not modify the contents of the
* original cell.
*
* @param cell may be <code>null</code> signifying that the cell is not present (or blank)
* @return <code>null</code> if the supplied cell is <code>null</code> or blank
*/
public ValueEval evaluate(String sheetName, int rowIndex, int columnIndex) {
EvaluationCell cell = _sewb.getEvaluationCell(sheetName, rowIndex, columnIndex);
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
return BoolEval.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_ERROR:
return ErrorEval.valueOf(cell.getErrorCellValue());
case HSSFCell.CELL_TYPE_FORMULA:
return _evaluator.evaluate(cell);
case HSSFCell.CELL_TYPE_NUMERIC:
return new NumberEval(cell.getNumericCellValue());
case HSSFCell.CELL_TYPE_STRING:
return new StringEval(cell.getStringCellValue());
case HSSFCell.CELL_TYPE_BLANK:
return null;
}
throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
}
/**
* Coordinates several formula evaluators together so that formulas that involve external
* references can be evaluated.
* @param workbookNames the simple file names used to identify the workbooks in formulas
* with external links (for example "MyData.xls" as used in a formula "[MyData.xls]Sheet1!A1")
* @param evaluators all evaluators for the full set of workbooks required by the formulas.
*/
public static void setupEnvironment(String[] workbookNames, ForkedEvaluator[] evaluators) {
WorkbookEvaluator[] wbEvals = new WorkbookEvaluator[evaluators.length];
for (int i = 0; i < wbEvals.length; i++) {
wbEvals[i] = evaluators[i]._evaluator;
}
CollaboratingWorkbooksEnvironment.setup(workbookNames, wbEvals);
}
}

+ 114
- 114
src/java/org/apache/poi/ss/usermodel/CellValue.java Ver arquivo

@@ -1,114 +1,114 @@
/* ====================================================================
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.ss.usermodel;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.ss.usermodel.Cell;
/**
* Mimics the 'data view' of a cell. This allows formula evaluator
* to return a CellValue instead of precasting the value to String
* or Number or boolean type.
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*/
public final class CellValue {
public static final CellValue TRUE = new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0);
public static final CellValue FALSE= new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0);
private final int _cellType;
private final double _numberValue;
private final boolean _booleanValue;
private final String _textValue;
private final int _errorCode;
private CellValue(int cellType, double numberValue, boolean booleanValue,
String textValue, int errorCode) {
_cellType = cellType;
_numberValue = numberValue;
_booleanValue = booleanValue;
_textValue = textValue;
_errorCode = errorCode;
}
public CellValue(double numberValue) {
this(Cell.CELL_TYPE_NUMERIC, numberValue, false, null, 0);
}
public static CellValue valueOf(boolean booleanValue) {
return booleanValue ? TRUE : FALSE;
}
public CellValue(String stringValue) {
this(Cell.CELL_TYPE_STRING, 0.0, false, stringValue, 0);
}
public static CellValue getError(int errorCode) {
return new CellValue(Cell.CELL_TYPE_ERROR, 0.0, false, null, errorCode);
}
/**
* @return Returns the booleanValue.
*/
public boolean getBooleanValue() {
return _booleanValue;
}
/**
* @return Returns the numberValue.
*/
public double getNumberValue() {
return _numberValue;
}
/**
* @return Returns the stringValue.
*/
public String getStringValue() {
return _textValue;
}
/**
* @return Returns the cellType.
*/
public int getCellType() {
return _cellType;
}
/**
* @return Returns the errorValue.
*/
public byte getErrorValue() {
return (byte) _errorCode;
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
}
public String formatAsString() {
switch (_cellType) {
case Cell.CELL_TYPE_NUMERIC:
return String.valueOf(_numberValue);
case Cell.CELL_TYPE_STRING:
return '"' + _textValue + '"';
case Cell.CELL_TYPE_BOOLEAN:
return _booleanValue ? "TRUE" : "FALSE";
case Cell.CELL_TYPE_ERROR:
return ErrorEval.getText(_errorCode);
}
return "<error unexpected cell type " + _cellType + ">";
}
}
/* ====================================================================
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.ss.usermodel;
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.ss.usermodel.Cell;
/**
* Mimics the 'data view' of a cell. This allows formula evaluator
* to return a CellValue instead of precasting the value to String
* or Number or boolean type.
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
*/
public final class CellValue {
public static final CellValue TRUE = new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0);
public static final CellValue FALSE= new CellValue(Cell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0);
private final int _cellType;
private final double _numberValue;
private final boolean _booleanValue;
private final String _textValue;
private final int _errorCode;
private CellValue(int cellType, double numberValue, boolean booleanValue,
String textValue, int errorCode) {
_cellType = cellType;
_numberValue = numberValue;
_booleanValue = booleanValue;
_textValue = textValue;
_errorCode = errorCode;
}
public CellValue(double numberValue) {
this(Cell.CELL_TYPE_NUMERIC, numberValue, false, null, 0);
}
public static CellValue valueOf(boolean booleanValue) {
return booleanValue ? TRUE : FALSE;
}
public CellValue(String stringValue) {
this(Cell.CELL_TYPE_STRING, 0.0, false, stringValue, 0);
}
public static CellValue getError(int errorCode) {
return new CellValue(Cell.CELL_TYPE_ERROR, 0.0, false, null, errorCode);
}
/**
* @return Returns the booleanValue.
*/
public boolean getBooleanValue() {
return _booleanValue;
}
/**
* @return Returns the numberValue.
*/
public double getNumberValue() {
return _numberValue;
}
/**
* @return Returns the stringValue.
*/
public String getStringValue() {
return _textValue;
}
/**
* @return Returns the cellType.
*/
public int getCellType() {
return _cellType;
}
/**
* @return Returns the errorValue.
*/
public byte getErrorValue() {
return (byte) _errorCode;
}
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
}
public String formatAsString() {
switch (_cellType) {
case Cell.CELL_TYPE_NUMERIC:
return String.valueOf(_numberValue);
case Cell.CELL_TYPE_STRING:
return '"' + _textValue + '"';
case Cell.CELL_TYPE_BOOLEAN:
return _booleanValue ? "TRUE" : "FALSE";
case Cell.CELL_TYPE_ERROR:
return ErrorEval.getText(_errorCode);
}
return "<error unexpected cell type " + _cellType + ">";
}
}

+ 202
- 202
src/java/org/apache/poi/ss/usermodel/ClientAnchor.java Ver arquivo

@@ -1,202 +1,202 @@
/* ====================================================================
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.ss.usermodel;
/**
* A client anchor is attached to an excel worksheet. It anchors against a
* top-left and bottom-right cell.
*
* @author Yegor Kozlov
*/
public interface ClientAnchor {
/**
* Move and Resize With Anchor Cells
* <p>
* Specifies that the current drawing shall move and
* resize to maintain its row and column anchors (i.e. the
* object is anchored to the actual from and to row and column)
* </p>
*/
public static final int MOVE_AND_RESIZE = 0;
/**
* Move With Cells but Do Not Resize
* <p>
* Specifies that the current drawing shall move with its
* row and column (i.e. the object is anchored to the
* actual from row and column), but that the size shall remain absolute.
* </p>
* <p>
* If additional rows/columns are added between the from and to locations of the drawing,
* the drawing shall move its to anchors as needed to maintain this same absolute size.
* </p>
*/
public static final int MOVE_DONT_RESIZE = 2;
/**
* Do Not Move or Resize With Underlying Rows/Columns
* <p>
* Specifies that the current start and end positions shall
* be maintained with respect to the distances from the
* absolute start point of the worksheet.
* </p>
* <p>
* If additional rows/columns are added before the
* drawing, the drawing shall move its anchors as needed
* to maintain this same absolute position.
* </p>
*/
public static final int DONT_MOVE_AND_RESIZE = 3;
/**
* Returns the column (0 based) of the first cell.
*
* @return 0-based column of the first cell.
*/
public short getCol1();
/**
* Sets the column (0 based) of the first cell.
*
* @param col1 0-based column of the first cell.
*/
public void setCol1(int col1);
/**
* Returns the column (0 based) of the second cell.
*
* @return 0-based column of the second cell.
*/
public short getCol2();
/**
* Returns the column (0 based) of the second cell.
*
* @param col2 0-based column of the second cell.
*/
public void setCol2(int col2);
/**
* Returns the row (0 based) of the first cell.
*
* @return 0-based row of the first cell.
*/
public int getRow1();
/**
* Returns the row (0 based) of the first cell.
*
* @param row1 0-based row of the first cell.
*/
public void setRow1(int row1);
/**
* Returns the row (0 based) of the second cell.
*
* @return 0-based row of the second cell.
*/
public int getRow2();
/**
* Returns the row (0 based) of the first cell.
*
* @param row2 0-based row of the first cell.
*/
public void setRow2(int row2);
/**
* Returns the x coordinate within the first cell
*
* @return the x coordinate within the first cell
*/
public int getDx1();
/**
* Sets the x coordinate within the first cell
*
* @param dx1 the x coordinate within the first cell
*/
public void setDx1(int dx1);
/**
* Returns the y coordinate within the first cell
*
* @return the y coordinate within the first cell
*/
public int getDy1();
/**
* Sets the y coordinate within the first cell
*
* @param dy1 the y coordinate within the first cell
*/
public void setDy1(int dy1);
/**
* Sets the y coordinate within the second cell
*
* @return the y coordinate within the second cell
*/
public int getDy2();
/**
* Sets the y coordinate within the second cell
*
* @param dy2 the y coordinate within the second cell
*/
public void setDy2(int dy2);
/**
* Returns the x coordinate within the second cell
*
* @return the x coordinate within the second cell
*/
public int getDx2();
/**
* Sets the x coordinate within the second cell
*
* @param dx2 the x coordinate within the second cell
*/
public void setDx2(int dx2);
/**
* Sets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
* </p>
* @param anchorType the anchor type
* @see #MOVE_AND_RESIZE
* @see #MOVE_DONT_RESIZE
* @see #DONT_MOVE_AND_RESIZE
*/
public void setAnchorType( int anchorType );
/**
* Gets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
* </p>
* @return the anchor type
* @see #MOVE_AND_RESIZE
* @see #MOVE_DONT_RESIZE
* @see #DONT_MOVE_AND_RESIZE
*/
public int getAnchorType();
}
/* ====================================================================
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.ss.usermodel;
/**
* A client anchor is attached to an excel worksheet. It anchors against a
* top-left and bottom-right cell.
*
* @author Yegor Kozlov
*/
public interface ClientAnchor {
/**
* Move and Resize With Anchor Cells
* <p>
* Specifies that the current drawing shall move and
* resize to maintain its row and column anchors (i.e. the
* object is anchored to the actual from and to row and column)
* </p>
*/
public static final int MOVE_AND_RESIZE = 0;
/**
* Move With Cells but Do Not Resize
* <p>
* Specifies that the current drawing shall move with its
* row and column (i.e. the object is anchored to the
* actual from row and column), but that the size shall remain absolute.
* </p>
* <p>
* If additional rows/columns are added between the from and to locations of the drawing,
* the drawing shall move its to anchors as needed to maintain this same absolute size.
* </p>
*/
public static final int MOVE_DONT_RESIZE = 2;
/**
* Do Not Move or Resize With Underlying Rows/Columns
* <p>
* Specifies that the current start and end positions shall
* be maintained with respect to the distances from the
* absolute start point of the worksheet.
* </p>
* <p>
* If additional rows/columns are added before the
* drawing, the drawing shall move its anchors as needed
* to maintain this same absolute position.
* </p>
*/
public static final int DONT_MOVE_AND_RESIZE = 3;
/**
* Returns the column (0 based) of the first cell.
*
* @return 0-based column of the first cell.
*/
public short getCol1();
/**
* Sets the column (0 based) of the first cell.
*
* @param col1 0-based column of the first cell.
*/
public void setCol1(int col1);
/**
* Returns the column (0 based) of the second cell.
*
* @return 0-based column of the second cell.
*/
public short getCol2();
/**
* Returns the column (0 based) of the second cell.
*
* @param col2 0-based column of the second cell.
*/
public void setCol2(int col2);
/**
* Returns the row (0 based) of the first cell.
*
* @return 0-based row of the first cell.
*/
public int getRow1();
/**
* Returns the row (0 based) of the first cell.
*
* @param row1 0-based row of the first cell.
*/
public void setRow1(int row1);
/**
* Returns the row (0 based) of the second cell.
*
* @return 0-based row of the second cell.
*/
public int getRow2();
/**
* Returns the row (0 based) of the first cell.
*
* @param row2 0-based row of the first cell.
*/
public void setRow2(int row2);
/**
* Returns the x coordinate within the first cell
*
* @return the x coordinate within the first cell
*/
public int getDx1();
/**
* Sets the x coordinate within the first cell
*
* @param dx1 the x coordinate within the first cell
*/
public void setDx1(int dx1);
/**
* Returns the y coordinate within the first cell
*
* @return the y coordinate within the first cell
*/
public int getDy1();
/**
* Sets the y coordinate within the first cell
*
* @param dy1 the y coordinate within the first cell
*/
public void setDy1(int dy1);
/**
* Sets the y coordinate within the second cell
*
* @return the y coordinate within the second cell
*/
public int getDy2();
/**
* Sets the y coordinate within the second cell
*
* @param dy2 the y coordinate within the second cell
*/
public void setDy2(int dy2);
/**
* Returns the x coordinate within the second cell
*
* @return the x coordinate within the second cell
*/
public int getDx2();
/**
* Sets the x coordinate within the second cell
*
* @param dx2 the x coordinate within the second cell
*/
public void setDx2(int dx2);
/**
* Sets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
* </p>
* @param anchorType the anchor type
* @see #MOVE_AND_RESIZE
* @see #MOVE_DONT_RESIZE
* @see #DONT_MOVE_AND_RESIZE
*/
public void setAnchorType( int anchorType );
/**
* Gets the anchor type
* <p>
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
* </p>
* @return the anchor type
* @see #MOVE_AND_RESIZE
* @see #MOVE_DONT_RESIZE
* @see #DONT_MOVE_AND_RESIZE
*/
public int getAnchorType();
}

+ 665
- 665
src/java/org/apache/poi/ss/usermodel/DataFormatter.java
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 24
- 24
src/java/org/apache/poi/ss/usermodel/Drawing.java Ver arquivo

@@ -1,24 +1,24 @@
/* ====================================================================
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.ss.usermodel;
/**
* @author Yegor Kozlov
*/
public interface Drawing {
Picture createPicture(ClientAnchor anchor, int pictureIndex);
}
/* ====================================================================
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.ss.usermodel;
/**
* @author Yegor Kozlov
*/
public interface Drawing {
Picture createPicture(ClientAnchor anchor, int pictureIndex);
}

+ 140
- 140
src/java/org/apache/poi/ss/usermodel/FormulaError.java Ver arquivo

@@ -1,140 +1,140 @@
/* ====================================================================
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.ss.usermodel;
import java.util.Map;
import java.util.HashMap;
/**
* Enumerates error values in SpreadsheetML formula calculations.
*
* @author Yegor Kozlov
*/
public enum FormulaError {
/**
* Intended to indicate when two areas are required to intersect, but do not.
* <p>Example:
* In the case of SUM(B1 C1), the space between B1 and C1 is treated as the binary
* intersection operator, when a comma was intended. end example]
* </p>
*/
NULL(0x00, "#NULL!"),
/**
* Intended to indicate when any number, including zero, is divided by zero.
* Note: However, any error code divided by zero results in that error code.
*/
DIV0(0x07, "#DIV/0!"),
/**
* Intended to indicate when an incompatible type argument is passed to a function, or
* an incompatible type operand is used with an operator.
* <p>Example:
* In the case of a function argument, text was expected, but a number was provided
* </p>
*/
VALUE(0x0F, "#VALUE!"),
/**
* Intended to indicate when a cell reference is invalid.
* <p>Example:
* If a formula contains a reference to a cell, and then the row or column containing that cell is deleted,
* a #REF! error results. If a worksheet does not support 20,001 columns,
* OFFSET(A1,0,20000) will result in a #REF! error.
* </p>
*/
REF(0x1D, "#REF!"),
/**
* Intended to indicate when what looks like a name is used, but no such name has been defined.
* <p>Example:
* XYZ/3, where XYZ is not a defined name. Total is & A10,
* where neither Total nor is is a defined name. Presumably, "Total is " & A10
* was intended. SUM(A1C10), where the range A1:C10 was intended.
* </p>
*/
NAME(0x1D, "#NAME?"),
/**
* Intended to indicate when an argument to a function has a compatible type, but has a
* value that is outside the domain over which that function is defined. (This is known as
* a domain error.)
* <p>Example:
* Certain calls to ASIN, ATANH, FACT, and SQRT might result in domain errors.
* </p>
* Intended to indicate that the result of a function cannot be represented in a value of
* the specified type, typically due to extreme magnitude. (This is known as a range
* error.)
* <p>Example: FACT(1000) might result in a range error. </p>
*/
NUM(0x24, "#NUM!"),
/**
* Intended to indicate when a designated value is not available.
* <p>Example:
* Some functions, such as SUMX2MY2, perform a series of operations on corresponding
* elements in two arrays. If those arrays do not have the same number of elements, then
* for some elements in the longer array, there are no corresponding elements in the
* shorter one; that is, one or more values in the shorter array are not available.
* </p>
* This error value can be produced by calling the function NA
*/
NA(0x2A, "#N/A");
private byte type;
private String repr;
private FormulaError(int type, String repr) {
this.type = (byte) type;
this.repr = repr;
}
/**
* @return numeric code of the error
*/
public byte getCode() {
return type;
}
/**
* @return string representation of the error
*/
public String getString() {
return repr;
}
private static Map<String, FormulaError> smap = new HashMap<String, FormulaError>();
private static Map<Byte, FormulaError> imap = new HashMap<Byte, FormulaError>();
static{
for (FormulaError error : values()) {
imap.put(error.getCode(), error);
smap.put(error.getString(), error);
}
}
public static FormulaError forInt(byte type){
FormulaError err = imap.get(type);
if(err == null) throw new IllegalArgumentException("Unknown error type: " + type);
return err;
}
public static FormulaError forString(String code){
FormulaError err = smap.get(code);
if(err == null) throw new IllegalArgumentException("Unknown error code: " + code);
return err;
}
}
/* ====================================================================
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.ss.usermodel;
import java.util.Map;
import java.util.HashMap;
/**
* Enumerates error values in SpreadsheetML formula calculations.
*
* @author Yegor Kozlov
*/
public enum FormulaError {
/**
* Intended to indicate when two areas are required to intersect, but do not.
* <p>Example:
* In the case of SUM(B1 C1), the space between B1 and C1 is treated as the binary
* intersection operator, when a comma was intended. end example]
* </p>
*/
NULL(0x00, "#NULL!"),
/**
* Intended to indicate when any number, including zero, is divided by zero.
* Note: However, any error code divided by zero results in that error code.
*/
DIV0(0x07, "#DIV/0!"),
/**
* Intended to indicate when an incompatible type argument is passed to a function, or
* an incompatible type operand is used with an operator.
* <p>Example:
* In the case of a function argument, text was expected, but a number was provided
* </p>
*/
VALUE(0x0F, "#VALUE!"),
/**
* Intended to indicate when a cell reference is invalid.
* <p>Example:
* If a formula contains a reference to a cell, and then the row or column containing that cell is deleted,
* a #REF! error results. If a worksheet does not support 20,001 columns,
* OFFSET(A1,0,20000) will result in a #REF! error.
* </p>
*/
REF(0x1D, "#REF!"),
/**
* Intended to indicate when what looks like a name is used, but no such name has been defined.
* <p>Example:
* XYZ/3, where XYZ is not a defined name. Total is & A10,
* where neither Total nor is is a defined name. Presumably, "Total is " & A10
* was intended. SUM(A1C10), where the range A1:C10 was intended.
* </p>
*/
NAME(0x1D, "#NAME?"),
/**
* Intended to indicate when an argument to a function has a compatible type, but has a
* value that is outside the domain over which that function is defined. (This is known as
* a domain error.)
* <p>Example:
* Certain calls to ASIN, ATANH, FACT, and SQRT might result in domain errors.
* </p>
* Intended to indicate that the result of a function cannot be represented in a value of
* the specified type, typically due to extreme magnitude. (This is known as a range
* error.)
* <p>Example: FACT(1000) might result in a range error. </p>
*/
NUM(0x24, "#NUM!"),
/**
* Intended to indicate when a designated value is not available.
* <p>Example:
* Some functions, such as SUMX2MY2, perform a series of operations on corresponding
* elements in two arrays. If those arrays do not have the same number of elements, then
* for some elements in the longer array, there are no corresponding elements in the
* shorter one; that is, one or more values in the shorter array are not available.
* </p>
* This error value can be produced by calling the function NA
*/
NA(0x2A, "#N/A");
private byte type;
private String repr;
private FormulaError(int type, String repr) {
this.type = (byte) type;
this.repr = repr;
}
/**
* @return numeric code of the error
*/
public byte getCode() {
return type;
}
/**
* @return string representation of the error
*/
public String getString() {
return repr;
}
private static Map<String, FormulaError> smap = new HashMap<String, FormulaError>();
private static Map<Byte, FormulaError> imap = new HashMap<Byte, FormulaError>();
static{
for (FormulaError error : values()) {
imap.put(error.getCode(), error);
smap.put(error.getString(), error);
}
}
public static FormulaError forInt(byte type){
FormulaError err = imap.get(type);
if(err == null) throw new IllegalArgumentException("Unknown error type: " + type);
return err;
}
public static FormulaError forString(String code){
FormulaError err = smap.get(code);
if(err == null) throw new IllegalArgumentException("Unknown error code: " + code);
return err;
}
}

+ 95
- 95
src/java/org/apache/poi/ss/usermodel/HorizontalAlignment.java Ver arquivo

@@ -1,95 +1,95 @@
/* ====================================================================
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.ss.usermodel;
/**
* The enumeration value indicating horizontal alignment of a cell,
* i.e., whether it is aligned general, left, right, horizontally centered, filled (replicated),
* justified, centered across multiple cells, or distributed.
*/
public enum HorizontalAlignment {
/**
* The horizontal alignment is general-aligned. Text data is left-aligned.
* Numbers, dates, and times are rightaligned. Boolean types are centered.
* Changing the alignment does not change the type of data.
*/
GENERAL,
/**
* The horizontal alignment is left-aligned, even in Rightto-Left mode.
* Aligns contents at the left edge of the cell. If an indent amount is specified, the contents of
* the cell is indented from the left by the specified number of character spaces. The character spaces are
* based on the default font and font size for the workbook.
*/
LEFT,
/**
* The horizontal alignment is centered, meaning the text is centered across the cell.
*/
CENTER,
/**
* The horizontal alignment is right-aligned, meaning that cell contents are aligned at the right edge of the cell,
* even in Right-to-Left mode.
*/
RIGHT,
/**
* Indicates that the value of the cell should be filled
* across the entire width of the cell. If blank cells to the right also have the fill alignment,
* they are also filled with the value, using a convention similar to centerContinuous.
* <p>
* Additional rules:
* <ol>
* <li>Only whole values can be appended, not partial values.</li>
* <li>The column will not be widened to 'best fit' the filled value</li>
* <li>If appending an additional occurrence of the value exceeds the boundary of the cell
* left/right edge, don't append the additional occurrence of the value.</li>
* <li>The display value of the cell is filled, not the underlying raw number.</li>
* </ol>
* </p>
*/
FILL,
/**
* The horizontal alignment is justified (flush left and right).
* For each line of text, aligns each line of the wrapped text in a cell to the right and left
* (except the last line). If no single line of text wraps in the cell, then the text is not justified.
*/
JUSTIFY,
/**
* The horizontal alignment is centered across multiple cells.
* The information about how many cells to span is expressed in the Sheet Part,
* in the row of the cell in question. For each cell that is spanned in the alignment,
* a cell element needs to be written out, with the same style Id which references the centerContinuous alignment.
*/
CENTER_SELECTION,
/**
* Indicates that each 'word' in each line of text inside the cell is evenly distributed
* across the width of the cell, with flush right and left margins.
* <p>
* When there is also an indent value to apply, both the left and right side of the cell
* are padded by the indent value.
* </p>
* <p> A 'word' is a set of characters with no space character in them. </p>
* <p> Two lines inside a cell are separated by a carriage return. </p>
*/
DISTRIBUTED
}
/* ====================================================================
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.ss.usermodel;
/**
* The enumeration value indicating horizontal alignment of a cell,
* i.e., whether it is aligned general, left, right, horizontally centered, filled (replicated),
* justified, centered across multiple cells, or distributed.
*/
public enum HorizontalAlignment {
/**
* The horizontal alignment is general-aligned. Text data is left-aligned.
* Numbers, dates, and times are rightaligned. Boolean types are centered.
* Changing the alignment does not change the type of data.
*/
GENERAL,
/**
* The horizontal alignment is left-aligned, even in Rightto-Left mode.
* Aligns contents at the left edge of the cell. If an indent amount is specified, the contents of
* the cell is indented from the left by the specified number of character spaces. The character spaces are
* based on the default font and font size for the workbook.
*/
LEFT,
/**
* The horizontal alignment is centered, meaning the text is centered across the cell.
*/
CENTER,
/**
* The horizontal alignment is right-aligned, meaning that cell contents are aligned at the right edge of the cell,
* even in Right-to-Left mode.
*/
RIGHT,
/**
* Indicates that the value of the cell should be filled
* across the entire width of the cell. If blank cells to the right also have the fill alignment,
* they are also filled with the value, using a convention similar to centerContinuous.
* <p>
* Additional rules:
* <ol>
* <li>Only whole values can be appended, not partial values.</li>
* <li>The column will not be widened to 'best fit' the filled value</li>
* <li>If appending an additional occurrence of the value exceeds the boundary of the cell
* left/right edge, don't append the additional occurrence of the value.</li>
* <li>The display value of the cell is filled, not the underlying raw number.</li>
* </ol>
* </p>
*/
FILL,
/**
* The horizontal alignment is justified (flush left and right).
* For each line of text, aligns each line of the wrapped text in a cell to the right and left
* (except the last line). If no single line of text wraps in the cell, then the text is not justified.
*/
JUSTIFY,
/**
* The horizontal alignment is centered across multiple cells.
* The information about how many cells to span is expressed in the Sheet Part,
* in the row of the cell in question. For each cell that is spanned in the alignment,
* a cell element needs to be written out, with the same style Id which references the centerContinuous alignment.
*/
CENTER_SELECTION,
/**
* Indicates that each 'word' in each line of text inside the cell is evenly distributed
* across the width of the cell, with flush right and left margins.
* <p>
* When there is also an indent value to apply, both the left and right side of the cell
* are padded by the indent value.
* </p>
* <p> A 'word' is a set of characters with no space character in them. </p>
* <p> Two lines inside a cell are separated by a carriage return. </p>
*/
DISTRIBUTED
}

+ 42
- 42
src/java/org/apache/poi/ss/usermodel/Picture.java Ver arquivo

@@ -1,42 +1,42 @@
/* ====================================================================
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.ss.usermodel;
/**
* Repersents a picture in a SpreadsheetML document
*
* @author Yegor Kozlov
*/
public interface Picture {
/**
* Reset the image to the original size.
*/
void resize();
/**
* Reset the image to the original size.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original,
* <code>resize(2.0)</code> resizes to 200% of the original.
*/
void resize(double scale);
ClientAnchor getPreferredSize();
}
/* ====================================================================
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.ss.usermodel;
/**
* Repersents a picture in a SpreadsheetML document
*
* @author Yegor Kozlov
*/
public interface Picture {
/**
* Reset the image to the original size.
*/
void resize();
/**
* Reset the image to the original size.
*
* @param scale the amount by which image dimensions are multiplied relative to the original size.
* <code>resize(1.0)</code> sets the original size, <code>resize(0.5)</code> resize to 50% of the original,
* <code>resize(2.0)</code> resizes to 200% of the original.
*/
void resize(double scale);
ClientAnchor getPreferredSize();
}

+ 212
- 212
src/java/org/apache/poi/ss/usermodel/ShapeTypes.java Ver arquivo

@@ -1,212 +1,212 @@
/* ====================================================================
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.ss.usermodel;
/**
* All known types of automatic shapes in DrawingML
*
* @author Yegor Kozlov
*/
public class ShapeTypes {
public static final int LINE = 1;
public static final int LINE_INV = 2;
public static final int TRIANGLE = 3;
public static final int RT_TRIANGLE = 4;
public static final int RECT = 5;
public static final int DIAMOND = 6;
public static final int PARALLELOGRAM = 7;
public static final int TRAPEZOID = 8;
public static final int NON_ISOSCELES_TRAPEZOID = 9;
public static final int PENTAGON = 10;
public static final int HEXAGON = 11;
public static final int HEPTAGON = 12;
public static final int OCTAGON = 13;
public static final int DECAGON = 14;
public static final int DODECAGON = 15;
public static final int STAR_4 = 16;
public static final int STAR_5 = 17;
public static final int STAR_6 = 18;
public static final int STAR_7 = 19;
public static final int STAR_8 = 20;
public static final int STAR_10 = 21;
public static final int STAR_12 = 22;
public static final int STAR_16 = 23;
public static final int STAR_24 = 24;
public static final int STAR_32 = 25;
public static final int ROUND_RECT = 26;
public static final int ROUND_1_RECT = 27;
public static final int ROUND_2_SAME_RECT = 28;
public static final int ROUND_2_DIAG_RECT = 29;
public static final int SNIP_ROUND_RECT = 30;
public static final int SNIP_1_RECT = 31;
public static final int SNIP_2_SAME_RECT = 32;
public static final int SNIP_2_DIAG_RECT = 33;
public static final int PLAQUE = 34;
public static final int ELLIPSE = 35;
public static final int TEARDROP = 36;
public static final int HOME_PLATE = 37;
public static final int CHEVRON = 38;
public static final int PIE_WEDGE = 39;
public static final int PIE = 40;
public static final int BLOCK_ARC = 41;
public static final int DONUT = 42;
public static final int NO_SMOKING = 43;
public static final int RIGHT_ARROW = 44;
public static final int LEFT_ARROW = 45;
public static final int UP_ARROW = 46;
public static final int DOWN_ARROW = 47;
public static final int STRIPED_RIGHT_ARROW = 48;
public static final int NOTCHED_RIGHT_ARROW = 49;
public static final int BENT_UP_ARROW = 50;
public static final int LEFT_RIGHT_ARROW = 51;
public static final int UP_DOWN_ARROW = 52;
public static final int LEFT_UP_ARROW = 53;
public static final int LEFT_RIGHT_UP_ARROW = 54;
public static final int QUAD_ARROW = 55;
public static final int LEFT_ARROW_CALLOUT = 56;
public static final int RIGHT_ARROW_CALLOUT = 57;
public static final int UP_ARROW_CALLOUT = 58;
public static final int DOWN_ARROW_CALLOUT = 59;
public static final int LEFT_RIGHT_ARROW_CALLOUT = 60;
public static final int UP_DOWN_ARROW_CALLOUT = 61;
public static final int QUAD_ARROW_CALLOUT = 62;
public static final int BENT_ARROW = 63;
public static final int UTURN_ARROW = 64;
public static final int CIRCULAR_ARROW = 65;
public static final int LEFT_CIRCULAR_ARROW = 66;
public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67;
public static final int CURVED_RIGHT_ARROW = 68;
public static final int CURVED_LEFT_ARROW = 69;
public static final int CURVED_UP_ARROW = 70;
public static final int CURVED_DOWN_ARROW = 71;
public static final int SWOOSH_ARROW = 72;
public static final int CUBE = 73;
public static final int CAN = 74;
public static final int LIGHTNING_BOLT = 75;
public static final int HEART = 76;
public static final int SUN = 77;
public static final int MOON = 78;
public static final int SMILEY_FACE = 79;
public static final int IRREGULAR_SEAL_1 = 80;
public static final int IRREGULAR_SEAL_2 = 81;
public static final int FOLDED_CORNER = 82;
public static final int BEVEL = 83;
public static final int FRAME = 84;
public static final int HALF_FRAME = 85;
public static final int CORNER = 86;
public static final int DIAG_STRIPE = 87;
public static final int CHORD = 88;
public static final int ARC = 89;
public static final int LEFT_BRACKET = 90;
public static final int RIGHT_BRACKET = 91;
public static final int LEFT_BRACE = 92;
public static final int RIGHT_BRACE = 93;
public static final int BRACKET_PAIR = 94;
public static final int BRACE_PAIR = 95;
public static final int STRAIGHT_CONNECTOR_1 = 96;
public static final int BENT_CONNECTOR_2 = 97;
public static final int BENT_CONNECTOR_3 = 98;
public static final int BENT_CONNECTOR_4 = 99;
public static final int BENT_CONNECTOR_5 = 100;
public static final int CURVED_CONNECTOR_2 = 101;
public static final int CURVED_CONNECTOR_3 = 102;
public static final int CURVED_CONNECTOR_4 = 103;
public static final int CURVED_CONNECTOR_5 = 104;
public static final int CALLOUT_1 = 105;
public static final int CALLOUT_2 = 106;
public static final int CALLOUT_3 = 107;
public static final int ACCENT_CALLOUT_1 = 108;
public static final int ACCENT_CALLOUT_2 = 109;
public static final int ACCENT_CALLOUT_3 = 110;
public static final int BORDER_CALLOUT_1 = 111;
public static final int BORDER_CALLOUT_2 = 112;
public static final int BORDER_CALLOUT_3 = 113;
public static final int ACCENT_BORDER_CALLOUT_1 = 114;
public static final int ACCENT_BORDER_CALLOUT_2 = 115;
public static final int ACCENT_BORDER_CALLOUT_3 = 116;
public static final int WEDGE_RECT_CALLOUT = 117;
public static final int WEDGE_ROUND_RECT_CALLOUT = 118;
public static final int WEDGE_ELLIPSE_CALLOUT = 119;
public static final int CLOUD_CALLOUT = 120;
public static final int CLOUD = 121;
public static final int RIBBON = 122;
public static final int RIBBON_2 = 123;
public static final int ELLIPSE_RIBBON = 124;
public static final int ELLIPSE_RIBBON_2 = 125;
public static final int LEFT_RIGHT_RIBBON = 126;
public static final int VERTICAL_SCROLL = 127;
public static final int HORIZONTAL_SCROLL = 128;
public static final int WAVE = 129;
public static final int DOUBLE_WAVE = 130;
public static final int PLUS = 131;
public static final int FLOW_CHART_PROCESS = 132;
public static final int FLOW_CHART_DECISION = 133;
public static final int FLOW_CHART_INPUT_OUTPUT = 134;
public static final int FLOW_CHART_PREDEFINED_PROCESS = 135;
public static final int FLOW_CHART_INTERNAL_STORAGE = 136;
public static final int FLOW_CHART_DOCUMENT = 137;
public static final int FLOW_CHART_MULTIDOCUMENT = 138;
public static final int FLOW_CHART_TERMINATOR = 139;
public static final int FLOW_CHART_PREPARATION = 140;
public static final int FLOW_CHART_MANUAL_INPUT = 141;
public static final int FLOW_CHART_MANUAL_OPERATION = 142;
public static final int FLOW_CHART_CONNECTOR = 143;
public static final int FLOW_CHART_PUNCHED_CARD = 144;
public static final int FLOW_CHART_PUNCHED_TAPE = 145;
public static final int FLOW_CHART_SUMMING_JUNCTION = 146;
public static final int FLOW_CHART_OR = 147;
public static final int FLOW_CHART_COLLATE = 148;
public static final int FLOW_CHART_SORT = 149;
public static final int FLOW_CHART_EXTRACT = 150;
public static final int FLOW_CHART_MERGE = 151;
public static final int FLOW_CHART_OFFLINE_STORAGE = 152;
public static final int FLOW_CHART_ONLINE_STORAGE = 153;
public static final int FLOW_CHART_MAGNETIC_TAPE = 154;
public static final int FLOW_CHART_MAGNETIC_DISK = 155;
public static final int FLOW_CHART_MAGNETIC_DRUM = 156;
public static final int FLOW_CHART_DISPLAY = 157;
public static final int FLOW_CHART_DELAY = 158;
public static final int FLOW_CHART_ALTERNATE_PROCESS = 159;
public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160;
public static final int ACTION_BUTTON_BLANK = 161;
public static final int ACTION_BUTTON_HOME = 162;
public static final int ACTION_BUTTON_HELP = 163;
public static final int ACTION_BUTTON_INFORMATION = 164;
public static final int ACTION_BUTTON_FORWARD_NEXT = 165;
public static final int ACTION_BUTTON_BACK_PREVIOUS = 166;
public static final int ACTION_BUTTON_END = 167;
public static final int ACTION_BUTTON_BEGINNING = 168;
public static final int ACTION_BUTTON_RETURN = 169;
public static final int ACTION_BUTTON_DOCUMENT = 170;
public static final int ACTION_BUTTON_SOUND = 171;
public static final int ACTION_BUTTON_MOVIE = 172;
public static final int GEAR_6 = 173;
public static final int GEAR_9 = 174;
public static final int FUNNEL = 175;
public static final int MATH_PLUS = 176;
public static final int MATH_MINUS = 177;
public static final int MATH_MULTIPLY = 178;
public static final int MATH_DIVIDE = 179;
public static final int MATH_EQUAL = 180;
public static final int MATH_NOT_EQUAL = 181;
public static final int CORNER_TABS = 182;
public static final int SQUARE_TABS = 183;
public static final int PLAQUE_TABS = 184;
public static final int CHART_X = 185;
public static final int CHART_STAR = 186;
public static final int CHART_PLUS = 187;
}
/* ====================================================================
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.ss.usermodel;
/**
* All known types of automatic shapes in DrawingML
*
* @author Yegor Kozlov
*/
public class ShapeTypes {
public static final int LINE = 1;
public static final int LINE_INV = 2;
public static final int TRIANGLE = 3;
public static final int RT_TRIANGLE = 4;
public static final int RECT = 5;
public static final int DIAMOND = 6;
public static final int PARALLELOGRAM = 7;
public static final int TRAPEZOID = 8;
public static final int NON_ISOSCELES_TRAPEZOID = 9;
public static final int PENTAGON = 10;
public static final int HEXAGON = 11;
public static final int HEPTAGON = 12;
public static final int OCTAGON = 13;
public static final int DECAGON = 14;
public static final int DODECAGON = 15;
public static final int STAR_4 = 16;
public static final int STAR_5 = 17;
public static final int STAR_6 = 18;
public static final int STAR_7 = 19;
public static final int STAR_8 = 20;
public static final int STAR_10 = 21;
public static final int STAR_12 = 22;
public static final int STAR_16 = 23;
public static final int STAR_24 = 24;
public static final int STAR_32 = 25;
public static final int ROUND_RECT = 26;
public static final int ROUND_1_RECT = 27;
public static final int ROUND_2_SAME_RECT = 28;
public static final int ROUND_2_DIAG_RECT = 29;
public static final int SNIP_ROUND_RECT = 30;
public static final int SNIP_1_RECT = 31;
public static final int SNIP_2_SAME_RECT = 32;
public static final int SNIP_2_DIAG_RECT = 33;
public static final int PLAQUE = 34;
public static final int ELLIPSE = 35;
public static final int TEARDROP = 36;
public static final int HOME_PLATE = 37;
public static final int CHEVRON = 38;
public static final int PIE_WEDGE = 39;
public static final int PIE = 40;
public static final int BLOCK_ARC = 41;
public static final int DONUT = 42;
public static final int NO_SMOKING = 43;
public static final int RIGHT_ARROW = 44;
public static final int LEFT_ARROW = 45;
public static final int UP_ARROW = 46;
public static final int DOWN_ARROW = 47;
public static final int STRIPED_RIGHT_ARROW = 48;
public static final int NOTCHED_RIGHT_ARROW = 49;
public static final int BENT_UP_ARROW = 50;
public static final int LEFT_RIGHT_ARROW = 51;
public static final int UP_DOWN_ARROW = 52;
public static final int LEFT_UP_ARROW = 53;
public static final int LEFT_RIGHT_UP_ARROW = 54;
public static final int QUAD_ARROW = 55;
public static final int LEFT_ARROW_CALLOUT = 56;
public static final int RIGHT_ARROW_CALLOUT = 57;
public static final int UP_ARROW_CALLOUT = 58;
public static final int DOWN_ARROW_CALLOUT = 59;
public static final int LEFT_RIGHT_ARROW_CALLOUT = 60;
public static final int UP_DOWN_ARROW_CALLOUT = 61;
public static final int QUAD_ARROW_CALLOUT = 62;
public static final int BENT_ARROW = 63;
public static final int UTURN_ARROW = 64;
public static final int CIRCULAR_ARROW = 65;
public static final int LEFT_CIRCULAR_ARROW = 66;
public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67;
public static final int CURVED_RIGHT_ARROW = 68;
public static final int CURVED_LEFT_ARROW = 69;
public static final int CURVED_UP_ARROW = 70;
public static final int CURVED_DOWN_ARROW = 71;
public static final int SWOOSH_ARROW = 72;
public static final int CUBE = 73;
public static final int CAN = 74;
public static final int LIGHTNING_BOLT = 75;
public static final int HEART = 76;
public static final int SUN = 77;
public static final int MOON = 78;
public static final int SMILEY_FACE = 79;
public static final int IRREGULAR_SEAL_1 = 80;
public static final int IRREGULAR_SEAL_2 = 81;
public static final int FOLDED_CORNER = 82;
public static final int BEVEL = 83;
public static final int FRAME = 84;
public static final int HALF_FRAME = 85;
public static final int CORNER = 86;
public static final int DIAG_STRIPE = 87;
public static final int CHORD = 88;
public static final int ARC = 89;
public static final int LEFT_BRACKET = 90;
public static final int RIGHT_BRACKET = 91;
public static final int LEFT_BRACE = 92;
public static final int RIGHT_BRACE = 93;
public static final int BRACKET_PAIR = 94;
public static final int BRACE_PAIR = 95;
public static final int STRAIGHT_CONNECTOR_1 = 96;
public static final int BENT_CONNECTOR_2 = 97;
public static final int BENT_CONNECTOR_3 = 98;
public static final int BENT_CONNECTOR_4 = 99;
public static final int BENT_CONNECTOR_5 = 100;
public static final int CURVED_CONNECTOR_2 = 101;
public static final int CURVED_CONNECTOR_3 = 102;
public static final int CURVED_CONNECTOR_4 = 103;
public static final int CURVED_CONNECTOR_5 = 104;
public static final int CALLOUT_1 = 105;
public static final int CALLOUT_2 = 106;
public static final int CALLOUT_3 = 107;
public static final int ACCENT_CALLOUT_1 = 108;
public static final int ACCENT_CALLOUT_2 = 109;
public static final int ACCENT_CALLOUT_3 = 110;
public static final int BORDER_CALLOUT_1 = 111;
public static final int BORDER_CALLOUT_2 = 112;
public static final int BORDER_CALLOUT_3 = 113;
public static final int ACCENT_BORDER_CALLOUT_1 = 114;
public static final int ACCENT_BORDER_CALLOUT_2 = 115;
public static final int ACCENT_BORDER_CALLOUT_3 = 116;
public static final int WEDGE_RECT_CALLOUT = 117;
public static final int WEDGE_ROUND_RECT_CALLOUT = 118;
public static final int WEDGE_ELLIPSE_CALLOUT = 119;
public static final int CLOUD_CALLOUT = 120;
public static final int CLOUD = 121;
public static final int RIBBON = 122;
public static final int RIBBON_2 = 123;
public static final int ELLIPSE_RIBBON = 124;
public static final int ELLIPSE_RIBBON_2 = 125;
public static final int LEFT_RIGHT_RIBBON = 126;
public static final int VERTICAL_SCROLL = 127;
public static final int HORIZONTAL_SCROLL = 128;
public static final int WAVE = 129;
public static final int DOUBLE_WAVE = 130;
public static final int PLUS = 131;
public static final int FLOW_CHART_PROCESS = 132;
public static final int FLOW_CHART_DECISION = 133;
public static final int FLOW_CHART_INPUT_OUTPUT = 134;
public static final int FLOW_CHART_PREDEFINED_PROCESS = 135;
public static final int FLOW_CHART_INTERNAL_STORAGE = 136;
public static final int FLOW_CHART_DOCUMENT = 137;
public static final int FLOW_CHART_MULTIDOCUMENT = 138;
public static final int FLOW_CHART_TERMINATOR = 139;
public static final int FLOW_CHART_PREPARATION = 140;
public static final int FLOW_CHART_MANUAL_INPUT = 141;
public static final int FLOW_CHART_MANUAL_OPERATION = 142;
public static final int FLOW_CHART_CONNECTOR = 143;
public static final int FLOW_CHART_PUNCHED_CARD = 144;
public static final int FLOW_CHART_PUNCHED_TAPE = 145;
public static final int FLOW_CHART_SUMMING_JUNCTION = 146;
public static final int FLOW_CHART_OR = 147;
public static final int FLOW_CHART_COLLATE = 148;
public static final int FLOW_CHART_SORT = 149;
public static final int FLOW_CHART_EXTRACT = 150;
public static final int FLOW_CHART_MERGE = 151;
public static final int FLOW_CHART_OFFLINE_STORAGE = 152;
public static final int FLOW_CHART_ONLINE_STORAGE = 153;
public static final int FLOW_CHART_MAGNETIC_TAPE = 154;
public static final int FLOW_CHART_MAGNETIC_DISK = 155;
public static final int FLOW_CHART_MAGNETIC_DRUM = 156;
public static final int FLOW_CHART_DISPLAY = 157;
public static final int FLOW_CHART_DELAY = 158;
public static final int FLOW_CHART_ALTERNATE_PROCESS = 159;
public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160;
public static final int ACTION_BUTTON_BLANK = 161;
public static final int ACTION_BUTTON_HOME = 162;
public static final int ACTION_BUTTON_HELP = 163;
public static final int ACTION_BUTTON_INFORMATION = 164;
public static final int ACTION_BUTTON_FORWARD_NEXT = 165;
public static final int ACTION_BUTTON_BACK_PREVIOUS = 166;
public static final int ACTION_BUTTON_END = 167;
public static final int ACTION_BUTTON_BEGINNING = 168;
public static final int ACTION_BUTTON_RETURN = 169;
public static final int ACTION_BUTTON_DOCUMENT = 170;
public static final int ACTION_BUTTON_SOUND = 171;
public static final int ACTION_BUTTON_MOVIE = 172;
public static final int GEAR_6 = 173;
public static final int GEAR_9 = 174;
public static final int FUNNEL = 175;
public static final int MATH_PLUS = 176;
public static final int MATH_MINUS = 177;
public static final int MATH_MULTIPLY = 178;
public static final int MATH_DIVIDE = 179;
public static final int MATH_EQUAL = 180;
public static final int MATH_NOT_EQUAL = 181;
public static final int CORNER_TABS = 182;
public static final int SQUARE_TABS = 183;
public static final int PLAQUE_TABS = 184;
public static final int CHART_X = 185;
public static final int CHART_STAR = 186;
public static final int CHART_PLUS = 187;
}

+ 69
- 69
src/java/org/apache/poi/ss/usermodel/VerticalAlignment.java Ver arquivo

@@ -1,69 +1,69 @@
/* ====================================================================
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.ss.usermodel;
/**
* This enumeration value indicates the type of vertical alignment for a cell, i.e.,
* whether it is aligned top, bottom, vertically centered, justified or distributed.
*/
public enum VerticalAlignment {
/**
* The vertical alignment is aligned-to-top.
*/
TOP,
/**
* The vertical alignment is centered across the height of the cell.
*/
CENTER,
/**
* The vertical alignment is aligned-to-bottom.
*/
BOTTOM,
/**
* <p>
* When text direction is horizontal: the vertical alignment of lines of text is distributed vertically,
* where each line of text inside the cell is evenly distributed across the height of the cell,
* with flush top and bottom margins.
* </p>
* <p>
* When text direction is vertical: similar behavior as horizontal justification.
* The alignment is justified (flush top and bottom in this case). For each line of text, each
* line of the wrapped text in a cell is aligned to the top and bottom (except the last line).
* If no single line of text wraps in the cell, then the text is not justified.
* </p>
*/
JUSTIFY,
/**
* <p>
* When text direction is horizontal: the vertical alignment of lines of text is distributed vertically,
* where each line of text inside the cell is evenly distributed across the height of the cell,
* with flush top
* </p>
* <p>
* When text direction is vertical: behaves exactly as distributed horizontal alignment.
* The first words in a line of text (appearing at the top of the cell) are flush
* with the top edge of the cell, and the last words of a line of text are flush with the bottom edge of the cell,
* and the line of text is distributed evenly from top to bottom.
* </p>
*/
DISTRIBUTED
}
/* ====================================================================
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.ss.usermodel;
/**
* This enumeration value indicates the type of vertical alignment for a cell, i.e.,
* whether it is aligned top, bottom, vertically centered, justified or distributed.
*/
public enum VerticalAlignment {
/**
* The vertical alignment is aligned-to-top.
*/
TOP,
/**
* The vertical alignment is centered across the height of the cell.
*/
CENTER,
/**
* The vertical alignment is aligned-to-bottom.
*/
BOTTOM,
/**
* <p>
* When text direction is horizontal: the vertical alignment of lines of text is distributed vertically,
* where each line of text inside the cell is evenly distributed across the height of the cell,
* with flush top and bottom margins.
* </p>
* <p>
* When text direction is vertical: similar behavior as horizontal justification.
* The alignment is justified (flush top and bottom in this case). For each line of text, each
* line of the wrapped text in a cell is aligned to the top and bottom (except the last line).
* If no single line of text wraps in the cell, then the text is not justified.
* </p>
*/
JUSTIFY,
/**
* <p>
* When text direction is horizontal: the vertical alignment of lines of text is distributed vertically,
* where each line of text inside the cell is evenly distributed across the height of the cell,
* with flush top
* </p>
* <p>
* When text direction is vertical: behaves exactly as distributed horizontal alignment.
* The first words in a line of text (appearing at the top of the cell) are flush
* with the top edge of the cell, and the last words of a line of text are flush with the bottom edge of the cell,
* and the line of text is distributed evenly from top to bottom.
* </p>
*/
DISTRIBUTED
}

+ 34
- 34
src/java/org/apache/poi/util/DelayableLittleEndianOutput.java Ver arquivo

@@ -1,34 +1,34 @@
/* ====================================================================
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.util;
/**
* Implementors of this interface allow client code to 'delay' writing to a certain section of a
* data output stream.<br/>
* A typical application is for writing BIFF records when the size is not known until well after
* the header has been written. The client code can call {@link #createDelayedOutput(int)}
* to reserve two bytes of the output for the 'ushort size' header field. The delayed output can
* be written at any stage.
*
* @author Josh Micich
*/
public interface DelayableLittleEndianOutput extends LittleEndianOutput {
/**
* Creates an output stream intended for outputting a sequence of <tt>size</tt> bytes.
*/
LittleEndianOutput createDelayedOutput(int size);
}
/* ====================================================================
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.util;
/**
* Implementors of this interface allow client code to 'delay' writing to a certain section of a
* data output stream.<br/>
* A typical application is for writing BIFF records when the size is not known until well after
* the header has been written. The client code can call {@link #createDelayedOutput(int)}
* to reserve two bytes of the output for the 'ushort size' header field. The delayed output can
* be written at any stage.
*
* @author Josh Micich
*/
public interface DelayableLittleEndianOutput extends LittleEndianOutput {
/**
* Creates an output stream intended for outputting a sequence of <tt>size</tt> bytes.
*/
LittleEndianOutput createDelayedOutput(int size);
}

+ 34
- 34
src/java/org/apache/poi/util/LittleEndianInput.java Ver arquivo

@@ -1,34 +1,34 @@
/* ====================================================================
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.util;
/**
*
* @author Josh Micich
*/
public interface LittleEndianInput {
int available();
byte readByte();
int readUByte();
short readShort();
int readUShort();
int readInt();
long readLong();
double readDouble();
void readFully(byte[] buf);
void readFully(byte[] buf, int off, int len);
}
/* ====================================================================
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.util;
/**
*
* @author Josh Micich
*/
public interface LittleEndianInput {
int available();
byte readByte();
int readUByte();
short readShort();
int readUShort();
int readInt();
long readLong();
double readDouble();
void readFully(byte[] buf);
void readFully(byte[] buf, int off, int len);
}

+ 144
- 144
src/java/org/apache/poi/util/LittleEndianInputStream.java Ver arquivo

@@ -1,144 +1,144 @@
/* ====================================================================
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.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Wraps an {@link InputStream} providing {@link LittleEndianInput}<p/>
*
* This class does not buffer any input, so the stream read position maintained
* by this class is consistent with that of the inner stream.
*
* @author Josh Micich
*/
public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput {
public LittleEndianInputStream(InputStream is) {
super(is);
}
public int available() {
try {
return super.available();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public byte readByte() {
return (byte)readUByte();
}
public int readUByte() {
int ch;
try {
ch = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch);
return ch;
}
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
public int readInt() {
int ch1;
int ch2;
int ch3;
int ch4;
try {
ch1 = in.read();
ch2 = in.read();
ch3 = in.read();
ch4 = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch1 | ch2 | ch3 | ch4);
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
}
public long readLong() {
int b0;
int b1;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
try {
b0 = in.read();
b1 = in.read();
b2 = in.read();
b3 = in.read();
b4 = in.read();
b5 = in.read();
b6 = in.read();
b7 = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7);
return (((long)b7 << 56) +
((long)b6 << 48) +
((long)b5 << 40) +
((long)b4 << 32) +
((long)b3 << 24) +
(b2 << 16) +
(b1 << 8) +
(b0 << 0));
}
public short readShort() {
return (short)readUShort();
}
public int readUShort() {
int ch1;
int ch2;
try {
ch1 = in.read();
ch2 = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch1 | ch2);
return (ch2 << 8) + (ch1 << 0);
}
private static void checkEOF(int value) {
if (value <0) {
throw new RuntimeException("Unexpected end-of-file");
}
}
public void readFully(byte[] buf) {
readFully(buf, 0, buf.length);
}
public void readFully(byte[] buf, int off, int len) {
int max = off+len;
for(int i=off; i<max; i++) {
int ch;
try {
ch = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch);
buf[i] = (byte) ch;
}
}
}
/* ====================================================================
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.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Wraps an {@link InputStream} providing {@link LittleEndianInput}<p/>
*
* This class does not buffer any input, so the stream read position maintained
* by this class is consistent with that of the inner stream.
*
* @author Josh Micich
*/
public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput {
public LittleEndianInputStream(InputStream is) {
super(is);
}
public int available() {
try {
return super.available();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public byte readByte() {
return (byte)readUByte();
}
public int readUByte() {
int ch;
try {
ch = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch);
return ch;
}
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
public int readInt() {
int ch1;
int ch2;
int ch3;
int ch4;
try {
ch1 = in.read();
ch2 = in.read();
ch3 = in.read();
ch4 = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch1 | ch2 | ch3 | ch4);
return (ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0);
}
public long readLong() {
int b0;
int b1;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
try {
b0 = in.read();
b1 = in.read();
b2 = in.read();
b3 = in.read();
b4 = in.read();
b5 = in.read();
b6 = in.read();
b7 = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7);
return (((long)b7 << 56) +
((long)b6 << 48) +
((long)b5 << 40) +
((long)b4 << 32) +
((long)b3 << 24) +
(b2 << 16) +
(b1 << 8) +
(b0 << 0));
}
public short readShort() {
return (short)readUShort();
}
public int readUShort() {
int ch1;
int ch2;
try {
ch1 = in.read();
ch2 = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch1 | ch2);
return (ch2 << 8) + (ch1 << 0);
}
private static void checkEOF(int value) {
if (value <0) {
throw new RuntimeException("Unexpected end-of-file");
}
}
public void readFully(byte[] buf) {
readFully(buf, 0, buf.length);
}
public void readFully(byte[] buf, int off, int len) {
int max = off+len;
for(int i=off; i<max; i++) {
int ch;
try {
ch = in.read();
} catch (IOException e) {
throw new RuntimeException(e);
}
checkEOF(ch);
buf[i] = (byte) ch;
}
}
}

+ 31
- 31
src/java/org/apache/poi/util/LittleEndianOutput.java Ver arquivo

@@ -1,31 +1,31 @@
/* ====================================================================
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.util;
/**
*
* @author Josh Micich
*/
public interface LittleEndianOutput {
void writeByte(int v);
void writeShort(int v);
void writeInt(int v);
void writeLong(long v);
void writeDouble(double v);
void write(byte[] b);
void write(byte[] b, int offset, int len);
}
/* ====================================================================
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.util;
/**
*
* @author Josh Micich
*/
public interface LittleEndianOutput {
void writeByte(int v);
void writeShort(int v);
void writeInt(int v);
void writeLong(long v);
void writeDouble(double v);
void write(byte[] b);
void write(byte[] b, int offset, int len);
}

+ 91
- 91
src/java/org/apache/poi/util/LittleEndianOutputStream.java Ver arquivo

@@ -1,91 +1,91 @@
/* ====================================================================
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.util;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
*
* @author Josh Micich
*/
public final class LittleEndianOutputStream extends FilterOutputStream implements LittleEndianOutput {
public LittleEndianOutputStream(OutputStream out) {
super(out);
}
public void writeByte(int v) {
try {
out.write(v);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void writeDouble(double v) {
writeLong(Double.doubleToLongBits(v));
}
public void writeInt(int v) {
int b3 = (v >>> 24) & 0xFF;
int b2 = (v >>> 16) & 0xFF;
int b1 = (v >>> 8) & 0xFF;
int b0 = (v >>> 0) & 0xFF;
try {
out.write(b0);
out.write(b1);
out.write(b2);
out.write(b3);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void writeLong(long v) {
writeInt((int)(v >> 0));
writeInt((int)(v >> 32));
}
public void writeShort(int v) {
int b1 = (v >>> 8) & 0xFF;
int b0 = (v >>> 0) & 0xFF;
try {
out.write(b0);
out.write(b1);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void write(byte[] b) {
// suppress IOException for interface method
try {
super.write(b);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void write(byte[] b, int off, int len) {
// suppress IOException for interface method
try {
super.write(b, off, len);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/* ====================================================================
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.util;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
*
* @author Josh Micich
*/
public final class LittleEndianOutputStream extends FilterOutputStream implements LittleEndianOutput {
public LittleEndianOutputStream(OutputStream out) {
super(out);
}
public void writeByte(int v) {
try {
out.write(v);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void writeDouble(double v) {
writeLong(Double.doubleToLongBits(v));
}
public void writeInt(int v) {
int b3 = (v >>> 24) & 0xFF;
int b2 = (v >>> 16) & 0xFF;
int b1 = (v >>> 8) & 0xFF;
int b0 = (v >>> 0) & 0xFF;
try {
out.write(b0);
out.write(b1);
out.write(b2);
out.write(b3);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void writeLong(long v) {
writeInt((int)(v >> 0));
writeInt((int)(v >> 32));
}
public void writeShort(int v) {
int b1 = (v >>> 8) & 0xFF;
int b0 = (v >>> 0) & 0xFF;
try {
out.write(b0);
out.write(b1);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void write(byte[] b) {
// suppress IOException for interface method
try {
super.write(b);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void write(byte[] b, int off, int len) {
// suppress IOException for interface method
try {
super.write(b, off, len);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

Carregando…
Cancelar
Salvar