mirror of https://github.com/apache/poi.git
#64004 - Replace clone() with copy constructor - mainly HSSF classes
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1871911 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ecb42bd78d
commit
ba6152503e
|
@ -65,26 +65,26 @@ import org.junit.runners.Parameterized.Parameters;
|
|||
|
||||
/**
|
||||
* This is an integration test which performs various actions on all stored test-files and tries
|
||||
* to reveal problems which are introduced, but not covered (yet) by unit tests.
|
||||
*
|
||||
* This test looks for any file under the test-data directory and tries to do some useful
|
||||
* to reveal problems which are introduced, but not covered (yet) by unit tests.
|
||||
*
|
||||
* This test looks for any file under the test-data directory and tries to do some useful
|
||||
* processing with it based on it's type.
|
||||
*
|
||||
*
|
||||
* The test is implemented as a junit {@link Parameterized} test, which leads
|
||||
* to one test-method call for each file (currently around 950 files are handled).
|
||||
*
|
||||
* There is a a mapping of extension to implementations of the interface
|
||||
* {@link FileHandler} which defines how the file is loaded and which actions are
|
||||
* tried with the file.
|
||||
*
|
||||
* to one test-method call for each file (currently around 950 files are handled).
|
||||
*
|
||||
* There is a a mapping of extension to implementations of the interface
|
||||
* {@link FileHandler} which defines how the file is loaded and which actions are
|
||||
* tried with the file.
|
||||
*
|
||||
* The test can be expanded by adding more actions to the FileHandlers, this automatically
|
||||
* applies the action to any such file in our test-data repository.
|
||||
*
|
||||
*
|
||||
* There is also a list of files that should actually fail.
|
||||
*
|
||||
* Note: It is also a test-failure if a file that is expected to fail now actually works,
|
||||
* i.e. if a bug was fixed in POI itself, the file should be removed from the expected-failures
|
||||
* here as well! This is to ensure that files that should not work really do not work, e.g.
|
||||
*
|
||||
* Note: It is also a test-failure if a file that is expected to fail now actually works,
|
||||
* i.e. if a bug was fixed in POI itself, the file should be removed from the expected-failures
|
||||
* here as well! This is to ensure that files that should not work really do not work, e.g.
|
||||
* that we do not remove expected sanity checks.
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
|
@ -96,7 +96,7 @@ public class TestAllFiles {
|
|||
|
||||
private static final Map<String,String> FILE_PASSWORD;
|
||||
|
||||
|
||||
|
||||
// map file extensions to the actual mappers
|
||||
public static final Map<String, FileHandler> HANDLERS = new HashMap<>();
|
||||
|
||||
|
@ -136,7 +136,7 @@ public class TestAllFiles {
|
|||
|
||||
// Visio - binary
|
||||
HANDLERS.put(".vsd", IGNORE_SCRATCHPAD ? new HPSFFileHandler() : new HDGFFileHandler());
|
||||
|
||||
|
||||
// Visio - ooxml
|
||||
HANDLERS.put(".vsdm", new XDGFFileHandler());
|
||||
HANDLERS.put(".vsdx", new XDGFFileHandler());
|
||||
|
@ -238,7 +238,7 @@ public class TestAllFiles {
|
|||
passmap.put("poifs/protected_agile.docx", Decryptor.DEFAULT_PASSWORD);
|
||||
passmap.put("poifs/60320-protected.xlsx", "Test001!!");
|
||||
passmap.put("poifs/protected_sha512.xlsx", "this is a test");
|
||||
|
||||
|
||||
FILE_PASSWORD = Collections.unmodifiableMap(passmap);
|
||||
}
|
||||
|
||||
|
@ -326,7 +326,7 @@ public class TestAllFiles {
|
|||
"spreadsheet/testEXCEL_95.xls",
|
||||
"spreadsheet/59074.xls",
|
||||
"spreadsheet/60284.xls",
|
||||
|
||||
|
||||
// OOXML Strict is not yet supported, see bug #57699
|
||||
"spreadsheet/SampleSS.strict.xlsx",
|
||||
"spreadsheet/SimpleStrict.xlsx",
|
||||
|
@ -342,7 +342,7 @@ public class TestAllFiles {
|
|||
|
||||
// sheet cloning errors
|
||||
"spreadsheet/56450.xls",
|
||||
"spreadsheet/OddStyleRecord.xls",
|
||||
// "spreadsheet/OddStyleRecord.xls",
|
||||
|
||||
// msg files with non-standard encodings
|
||||
"hsmf/ASCII_CP1251_LCID1049.msg",
|
||||
|
@ -377,7 +377,7 @@ public class TestAllFiles {
|
|||
}
|
||||
FileHandler handler = HANDLERS.get(getExtension(file));
|
||||
files.add(new Object[] { file, handler });
|
||||
|
||||
|
||||
// for some file-types also run OPCFileHandler
|
||||
if(handler instanceof XSSFFileHandler ||
|
||||
handler instanceof XWPFFileHandler ||
|
||||
|
@ -385,7 +385,7 @@ public class TestAllFiles {
|
|||
handler instanceof XDGFFileHandler) {
|
||||
files.add(new Object[] { file, new OPCFileHandler() });
|
||||
}
|
||||
|
||||
|
||||
if (handler instanceof HSSFFileHandler ||
|
||||
handler instanceof HSLFFileHandler ||
|
||||
handler instanceof HWPFFileHandler ||
|
||||
|
@ -410,7 +410,7 @@ public class TestAllFiles {
|
|||
String pass = TestAllFiles.FILE_PASSWORD.get(file);
|
||||
Biff8EncryptionKey.setCurrentUserPassword(pass);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllFiles() throws Exception {
|
||||
if(handler == null) {
|
||||
|
@ -426,7 +426,7 @@ public class TestAllFiles {
|
|||
file.endsWith(".xlsb") || file.endsWith(".pptx")) &&
|
||||
handler instanceof OPCFileHandler;
|
||||
boolean ignoreHPSF = (handler instanceof HPSFFileHandler);
|
||||
|
||||
|
||||
try {
|
||||
try (InputStream stream = new BufferedInputStream(new FileInputStream(inputFile), 64 * 1024)) {
|
||||
handler.handleFile(stream, file);
|
||||
|
@ -436,7 +436,7 @@ public class TestAllFiles {
|
|||
|
||||
handler.handleExtracting(inputFile);
|
||||
|
||||
assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!",
|
||||
assertFalse("Expected to fail for file " + file + " and handler " + handler + ", but did not fail!",
|
||||
EXPECTED_FAILURES.contains(file) && !ignoredOPC && !ignoreHPSF);
|
||||
} catch (OldFileFormatException e) {
|
||||
// for old word files we should still support extracting text
|
||||
|
|
|
@ -28,14 +28,14 @@ import org.apache.poi.hssf.record.Record;
|
|||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Needs to be implemented in this package to have access to
|
||||
* Needs to be implemented in this package to have access to
|
||||
* HSSFWorkbook.getWorkbook()
|
||||
*/
|
||||
public class RecordsStresser {
|
||||
public static void handleWorkbook(HSSFWorkbook wb) {
|
||||
List<Record> records = wb.getWorkbook().getRecords();
|
||||
for(Record record : records) {
|
||||
// some Records do not implement clone ?!
|
||||
// some Records do not implement clone ?!
|
||||
// equals instead of instanceof is on purpose here to only skip exactly this class and not any derived ones
|
||||
// if(record.getClass().equals(InterfaceHdrRecord.class) ||
|
||||
// record.getClass().equals(MMSRecord.class) ||
|
||||
|
@ -46,18 +46,16 @@ public class RecordsStresser {
|
|||
// continue;
|
||||
// }
|
||||
try {
|
||||
Record newRecord = (Record) record.clone();
|
||||
|
||||
assertEquals("Expecting the same class back from clone(), but had Record of type " + record.getClass() + " and got back a " + newRecord.getClass() + " from clone()",
|
||||
record.getClass(), newRecord.getClass());
|
||||
|
||||
Record newRecord = record.copy();
|
||||
|
||||
assertEquals("Expecting the same class back from clone(), but had Record of type " + record.getClass() + " and got back a " + newRecord.getClass() + " from clone()",
|
||||
record.getClass(), newRecord.getClass());
|
||||
|
||||
byte[] origBytes = record.serialize();
|
||||
byte[] newBytes = newRecord.serialize();
|
||||
|
||||
assertArrayEquals("Record of type " + record.getClass() + " should return the same byte array via the clone() method, but did return a different array",
|
||||
|
||||
assertArrayEquals("Record of type " + record.getClass() + " should return the same byte array via the clone() method, but did return a different array",
|
||||
origBytes, newBytes);
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (RuntimeException e) {
|
||||
// some Records do not implement clone, ignore those for now
|
||||
assertTrue(e.getMessage().contains("needs to define a clone method"));
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* ====================================================================
|
||||
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.common;
|
||||
|
||||
/**
|
||||
* This is an alternative to the {@link Cloneable} interface without its side-effects.
|
||||
* A class implementing Duplicatable provides a deep-copy of itself - usually this is done via a copy-constructor,
|
||||
* which is invoked with a self-reference by the copy method.
|
||||
* References to child objects are duplicated - references to parents are kept as-is and
|
||||
* might need to be replaced by the parent copy operation.
|
||||
*
|
||||
* @param <T> the implementing class itself
|
||||
*
|
||||
* @see <a href="https://www.artima.com/intv/bloch.html#part13">Copy Constructor versus Cloning</a>
|
||||
*/
|
||||
public interface Duplicatable {
|
||||
// Providing a generics interface Duplicatable<T extends Duplicatable<T>> pushes too many
|
||||
// changes to the implementing classes and the benefit of providing a subtype-specific copy method
|
||||
// is not sufficient
|
||||
/**
|
||||
* @return a deep copy of the implementing class / instance
|
||||
*/
|
||||
Duplicatable copy();
|
||||
}
|
|
@ -171,7 +171,4 @@ public abstract class AbstractEscherOptRecord extends EscherRecord {
|
|||
"properties", this::getEscherProperties
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract AbstractEscherOptRecord copy();
|
||||
}
|
||||
|
|
|
@ -142,13 +142,9 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
|
|||
* @return true, if any child has the given recordId
|
||||
*/
|
||||
public boolean hasChildOfType(short recordId) {
|
||||
for (EscherRecord r : this) {
|
||||
if(r.getRecordId() == recordId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return _childRecords.stream().anyMatch(r -> r.getRecordId() == recordId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EscherRecord getChild( int index ) {
|
||||
return _childRecords.get(index);
|
||||
|
@ -170,6 +166,7 @@ public final class EscherContainerRecord extends EscherRecord implements Iterabl
|
|||
return Collections.unmodifiableList(_childRecords).iterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* replaces the internal child list with the contents of the supplied <tt>childRecords</tt>
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.poi.common.Duplicatable;
|
||||
import org.apache.poi.common.usermodel.GenericRecord;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
|
@ -32,12 +33,13 @@ import org.apache.poi.util.GenericRecordUtil;
|
|||
import org.apache.poi.util.GenericRecordXmlWriter;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* The base abstract record from which all escher records are defined. Subclasses will need
|
||||
* to define methods for serialization/deserialization and for determining the record size.
|
||||
*/
|
||||
public abstract class EscherRecord implements Cloneable, GenericRecord {
|
||||
public abstract class EscherRecord implements Duplicatable, GenericRecord {
|
||||
private static final BitField fInstance = BitFieldFactory.getInstance(0xfff0);
|
||||
private static final BitField fVersion = BitFieldFactory.getInstance(0x000f);
|
||||
|
||||
|
@ -238,9 +240,12 @@ public abstract class EscherRecord implements Cloneable, GenericRecord {
|
|||
* Escher records may need to be clonable in the future.
|
||||
*
|
||||
* @return the cloned object
|
||||
* @deprecated use {@link #copy()}
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public final EscherRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
@ -350,5 +355,6 @@ public abstract class EscherRecord implements Cloneable, GenericRecord {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract EscherRecord copy();
|
||||
}
|
|
@ -31,7 +31,7 @@ import org.apache.poi.util.RecordFormatException;
|
|||
* Escher format. We don't attempt to understand the contents, since
|
||||
* they will be in the parent's format, not Escher format.
|
||||
*/
|
||||
public final class EscherTextboxRecord extends EscherRecord implements Cloneable {
|
||||
public final class EscherTextboxRecord extends EscherRecord {
|
||||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
|
|||
* This record is used whenever a escher record is encountered that
|
||||
* we do not explicitly support.
|
||||
*/
|
||||
public final class UnknownEscherRecord extends EscherRecord implements Cloneable {
|
||||
public final class UnknownEscherRecord extends EscherRecord {
|
||||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000_000;
|
||||
|
|
|
@ -23,11 +23,9 @@ import org.apache.poi.util.RecordFormatException;
|
|||
/**
|
||||
*/
|
||||
abstract class DummyRecordBase extends Record {
|
||||
|
||||
protected DummyRecordBase() {
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
protected DummyRecordBase() {}
|
||||
|
||||
public final short getSid() {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -25,37 +25,42 @@ package org.apache.poi.hssf.eventusermodel.dummyrecord;
|
|||
public final class LastCellOfRowDummyRecord extends DummyRecordBase {
|
||||
private final int row;
|
||||
private final int lastColumnNumber;
|
||||
|
||||
|
||||
public LastCellOfRowDummyRecord(int row, int lastColumnNumber) {
|
||||
this.row = row;
|
||||
this.lastColumnNumber = lastColumnNumber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the (0 based) number of the row we are
|
||||
* currently working on.
|
||||
*
|
||||
*
|
||||
* @return the (0 based) number of the row
|
||||
*/
|
||||
public int getRow() {
|
||||
return row;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the (0 based) number of the last column
|
||||
* seen for this row. You should have already been
|
||||
* called with that record.
|
||||
* This is -1 in the case of there being no columns
|
||||
* for the row.
|
||||
*
|
||||
*
|
||||
* @return the (0 based) number of the last column
|
||||
*/
|
||||
public int getLastColumnNumber() {
|
||||
return lastColumnNumber;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "End-of-Row for Row=" + row + " at Column=" + lastColumnNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LastCellOfRowDummyRecord copy() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,18 @@ package org.apache.poi.hssf.eventusermodel.dummyrecord;
|
|||
* but still want to trigger something
|
||||
*/
|
||||
public final class MissingCellDummyRecord extends DummyRecordBase {
|
||||
private int row;
|
||||
private int column;
|
||||
|
||||
private final int row;
|
||||
private final int column;
|
||||
|
||||
public MissingCellDummyRecord(int row, int column) {
|
||||
this.row = row;
|
||||
this.column = column;
|
||||
}
|
||||
public int getRow() { return row; }
|
||||
public int getColumn() { return column; }
|
||||
|
||||
@Override
|
||||
public MissingCellDummyRecord copy() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,17 @@ package org.apache.poi.hssf.eventusermodel.dummyrecord;
|
|||
* want to trigger something
|
||||
*/
|
||||
public final class MissingRowDummyRecord extends DummyRecordBase {
|
||||
private int rowNumber;
|
||||
|
||||
private final int rowNumber;
|
||||
|
||||
public MissingRowDummyRecord(int rowNumber) {
|
||||
this.rowNumber = rowNumber;
|
||||
}
|
||||
public int getRowNumber() {
|
||||
return rowNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MissingRowDummyRecord copy() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public final class InternalSheet {
|
|||
if (rs.peekNextSid() != BOFRecord.sid) {
|
||||
throw new RecordFormatException("BOF record expected");
|
||||
}
|
||||
|
||||
|
||||
BOFRecord bof = (BOFRecord) rs.getNext();
|
||||
if (bof.getType() == BOFRecord.TYPE_WORKSHEET) {
|
||||
// Good, well supported
|
||||
|
@ -152,7 +152,7 @@ public final class InternalSheet {
|
|||
throw new UnsupportedBOFType(bof.getType());
|
||||
}
|
||||
records.add(bof);
|
||||
|
||||
|
||||
while (rs.hasNext()) {
|
||||
int recSid = rs.peekNextSid();
|
||||
|
||||
|
@ -339,14 +339,14 @@ public final class InternalSheet {
|
|||
recs.add(r);
|
||||
}});
|
||||
}
|
||||
|
||||
|
||||
public static class UnsupportedBOFType extends RecordFormatException {
|
||||
private final int type;
|
||||
protected UnsupportedBOFType(int type) {
|
||||
super("BOF not of a supported type, found " + type);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
@ -360,11 +360,7 @@ public final class InternalSheet {
|
|||
_destList = destList;
|
||||
}
|
||||
public void visitRecord(Record r) {
|
||||
try {
|
||||
_destList.add((Record)r.clone());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RecordFormatException(e);
|
||||
}
|
||||
_destList.add(r.copy());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,7 +370,7 @@ public final class InternalSheet {
|
|||
* can be added to a sheet. The <b>Record</b> object does not implement cloneable.
|
||||
* When adding a new record, implement a public clone method if and only if the record
|
||||
* belongs to a sheet.
|
||||
*
|
||||
*
|
||||
* @return the cloned sheet
|
||||
*/
|
||||
public InternalSheet cloneSheet() {
|
||||
|
@ -391,12 +387,8 @@ public final class InternalSheet {
|
|||
*/
|
||||
rb = new DrawingRecord();
|
||||
}
|
||||
try {
|
||||
Record rec = (Record) ((Record) rb).clone();
|
||||
clonedRecords.add(rec);
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RecordFormatException(e);
|
||||
}
|
||||
Record rec = ((Record) rb).copy();
|
||||
clonedRecords.add(rec);
|
||||
}
|
||||
return createSheet(new RecordStream(clonedRecords, 0));
|
||||
}
|
||||
|
@ -478,7 +470,7 @@ public final class InternalSheet {
|
|||
|
||||
/**
|
||||
* Updates formulas in cells and conditional formats due to moving of cells
|
||||
*
|
||||
*
|
||||
* @param shifter the formular shifter
|
||||
* @param externSheetIndex the externSheet index of this sheet
|
||||
*/
|
||||
|
@ -995,7 +987,7 @@ public final class InternalSheet {
|
|||
|
||||
/**
|
||||
* set the default row height for the sheet (if the rows do not define their own height)
|
||||
*
|
||||
*
|
||||
* @param dch the default row height
|
||||
*/
|
||||
public void setDefaultRowHeight(short dch) {
|
||||
|
@ -1247,7 +1239,7 @@ public final class InternalSheet {
|
|||
|
||||
/**
|
||||
* Gets the gridset record for this sheet.
|
||||
*
|
||||
*
|
||||
* @return the gridset record for this sheet
|
||||
*/
|
||||
public GridsetRecord getGridsetRecord()
|
||||
|
@ -1257,9 +1249,9 @@ public final class InternalSheet {
|
|||
|
||||
/**
|
||||
* Returns the first occurrence of a record matching a particular sid.
|
||||
*
|
||||
*
|
||||
* @param sid the sid to search for
|
||||
*
|
||||
*
|
||||
* @return the matching record or {@code null} if it wasn't found
|
||||
*/
|
||||
public Record findFirstRecordBySid(short sid) {
|
||||
|
@ -1330,7 +1322,7 @@ public final class InternalSheet {
|
|||
{
|
||||
printGridlines = newPrintGridlines;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the PrintHeadersRecord.
|
||||
* @return PrintHeadersRecord for the sheet.
|
||||
|
@ -1519,7 +1511,7 @@ public final class InternalSheet {
|
|||
public boolean isDisplayRowColHeadings() {
|
||||
return windowTwo.getDisplayRowColHeadings();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the RowColHeadings are shown in a viewer.
|
||||
* @param show whether to show RowColHeadings or not
|
||||
|
@ -1681,7 +1673,7 @@ public final class InternalSheet {
|
|||
temp.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public int getColumnOutlineLevel(int columnIndex) {
|
||||
return _columnInfos.getOutlineLevel(columnIndex);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public final class RecordStream {
|
|||
|
||||
/**
|
||||
* Creates a RecordStream bounded by startIndex and endIndex
|
||||
*
|
||||
*
|
||||
* @param inputList the list to iterate over
|
||||
* @param startIndex the start index within the list
|
||||
* @param endIx the end index within the list, which is the index of the end element + 1
|
||||
|
@ -70,6 +70,13 @@ public final class RecordStream {
|
|||
return _list.get(_nextIndex).getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the next Record. <code>null</code> if this stream is exhausted.
|
||||
*/
|
||||
public Record peekNextRecord() {
|
||||
return (hasNext()) ? _list.get(_nextIndex) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return -1 if at end of records
|
||||
*/
|
||||
|
|
|
@ -25,14 +25,15 @@ import org.apache.poi.ddf.EscherContainerRecord;
|
|||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ddf.EscherRecordFactory;
|
||||
import org.apache.poi.ddf.NullEscherSerializationListener;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.hssf.util.LazilyConcatenatedByteArray;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* The escher container record is used to hold escher records. It is abstract and
|
||||
* must be subclassed for maximum benefit.
|
||||
*/
|
||||
public abstract class AbstractEscherHolderRecord extends Record implements Cloneable {
|
||||
public abstract class AbstractEscherHolderRecord extends Record {
|
||||
private static boolean DESERIALISE;
|
||||
static {
|
||||
try {
|
||||
|
@ -42,17 +43,17 @@ public abstract class AbstractEscherHolderRecord extends Record implements Clone
|
|||
}
|
||||
}
|
||||
|
||||
private final List<EscherRecord> escherRecords;
|
||||
private final List<EscherRecord> escherRecords = new ArrayList<>();
|
||||
private final LazilyConcatenatedByteArray rawDataContainer = new LazilyConcatenatedByteArray();
|
||||
|
||||
public AbstractEscherHolderRecord()
|
||||
{
|
||||
escherRecords = new ArrayList<>();
|
||||
public AbstractEscherHolderRecord() {}
|
||||
|
||||
public AbstractEscherHolderRecord(AbstractEscherHolderRecord other) {
|
||||
other.escherRecords.stream().map(EscherRecord::copy).forEach(escherRecords::add);
|
||||
rawDataContainer.concatenate(other.rawDataContainer);
|
||||
}
|
||||
|
||||
public AbstractEscherHolderRecord(RecordInputStream in)
|
||||
{
|
||||
escherRecords = new ArrayList<>();
|
||||
public AbstractEscherHolderRecord(RecordInputStream in) {
|
||||
if (! DESERIALISE ) {
|
||||
rawDataContainer.concatenate(in.readRemainder());
|
||||
} else {
|
||||
|
@ -143,10 +144,16 @@ public abstract class AbstractEscherHolderRecord extends Record implements Clone
|
|||
public abstract short getSid();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public AbstractEscherHolderRecord clone() {
|
||||
return (AbstractEscherHolderRecord)cloneViaReserialise();
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract AbstractEscherHolderRecord copy();
|
||||
|
||||
public void addEscherRecord(int index, EscherRecord element)
|
||||
{
|
||||
escherRecords.add( index, element );
|
||||
|
@ -171,7 +178,7 @@ public abstract class AbstractEscherHolderRecord extends Record implements Clone
|
|||
* If we have a EscherContainerRecord as one of our
|
||||
* children (and most top level escher holders do),
|
||||
* then return that.
|
||||
*
|
||||
*
|
||||
* @return the EscherContainerRecord or {@code null} if no child is a container record
|
||||
*/
|
||||
public EscherContainerRecord getEscherContainer() {
|
||||
|
@ -187,15 +194,15 @@ public abstract class AbstractEscherHolderRecord extends Record implements Clone
|
|||
* Descends into all our children, returning the
|
||||
* first EscherRecord with the given id, or null
|
||||
* if none found
|
||||
*
|
||||
*
|
||||
* @param id the record to look for
|
||||
*
|
||||
*
|
||||
* @return the record or {@code null} if it can't be found
|
||||
*/
|
||||
public EscherRecord findFirstWithId(short id) {
|
||||
return findFirstWithId(id, getEscherRecords());
|
||||
}
|
||||
|
||||
|
||||
private EscherRecord findFirstWithId(short id, List<EscherRecord> records) {
|
||||
// Check at our level
|
||||
for (EscherRecord r : records) {
|
||||
|
@ -227,7 +234,7 @@ public abstract class AbstractEscherHolderRecord extends Record implements Clone
|
|||
/**
|
||||
* Big drawing group records are split but it's easier to deal with them
|
||||
* as a whole group so we need to join them together.
|
||||
*
|
||||
*
|
||||
* @param record the record data to concatenate to the end
|
||||
*/
|
||||
public void join( AbstractEscherHolderRecord record )
|
||||
|
|
|
@ -17,18 +17,19 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.hssf.util.CellRangeAddress8Bit;
|
||||
import org.apache.poi.ss.formula.Formula;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* ARRAY (0x0221)<p>
|
||||
*
|
||||
* Treated in a similar way to SharedFormulaRecord
|
||||
*/
|
||||
public final class ArrayRecord extends SharedValueRecordBase implements Cloneable {
|
||||
public final class ArrayRecord extends SharedValueRecordBase {
|
||||
|
||||
public final static short sid = 0x0221;
|
||||
private static final int OPT_ALWAYS_RECALCULATE = 0x0001;
|
||||
|
@ -38,6 +39,13 @@ public final class ArrayRecord extends SharedValueRecordBase implements Cloneabl
|
|||
private int _field3notUsed;
|
||||
private Formula _formula;
|
||||
|
||||
public ArrayRecord(ArrayRecord other) {
|
||||
super(other);
|
||||
_options = other._options;
|
||||
_field3notUsed = other._field3notUsed;
|
||||
_formula = (other._formula == null) ? null : other._formula.copy();
|
||||
}
|
||||
|
||||
public ArrayRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
_options = in.readUShort();
|
||||
|
@ -92,16 +100,18 @@ public final class ArrayRecord extends SharedValueRecordBase implements Cloneabl
|
|||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayRecord clone() {
|
||||
ArrayRecord rec = new ArrayRecord(_formula.copy(), getRange());
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public ArrayRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
// they both seem unused, but clone them nevertheless to have an exact copy
|
||||
rec._options = _options;
|
||||
rec._field3notUsed = _field3notUsed;
|
||||
|
||||
return rec;
|
||||
@Override
|
||||
public ArrayRecord copy() {
|
||||
return new ArrayRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,27 +20,28 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* The AutoFilterInfo record specifies the number of columns that have AutoFilter enabled
|
||||
* and indicates the beginning of the collection of AutoFilter records.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
|
||||
public final class AutoFilterInfoRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x9D;
|
||||
public final class AutoFilterInfoRecord extends StandardRecord {
|
||||
public static final short sid = 0x9D;
|
||||
/**
|
||||
* Number of AutoFilter drop-down arrows on the sheet
|
||||
*/
|
||||
private short _cEntries; // = 0;
|
||||
private short _cEntries;
|
||||
|
||||
public AutoFilterInfoRecord()
|
||||
{
|
||||
public AutoFilterInfoRecord() {}
|
||||
|
||||
public AutoFilterInfoRecord(AutoFilterInfoRecord other) {
|
||||
super(other);
|
||||
_cEntries = other._cEntries;
|
||||
}
|
||||
|
||||
public AutoFilterInfoRecord(RecordInputStream in)
|
||||
{
|
||||
public AutoFilterInfoRecord(RecordInputStream in) {
|
||||
_cEntries = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -91,9 +92,15 @@ public final class AutoFilterInfoRecord extends StandardRecord implements Clonea
|
|||
}
|
||||
|
||||
@Override
|
||||
public AutoFilterInfoRecord clone()
|
||||
{
|
||||
return (AutoFilterInfoRecord)cloneViaReserialise();
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public AutoFilterInfoRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoFilterInfoRecord copy() {
|
||||
return new AutoFilterInfoRecord(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -19,44 +19,40 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Beginning Of File (0x0809)<P>
|
||||
* Description: Somewhat of a misnomer, its used for the beginning of a set of
|
||||
* records that have a particular purpose or subject.
|
||||
* Used in sheets and workbooks.<P>
|
||||
* REFERENCE: PG 289 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Somewhat of a misnomer, its used for the beginning of a set of records that
|
||||
* have a particular purpose or subject. Used in sheets and workbooks.
|
||||
*/
|
||||
public final class BOFRecord extends StandardRecord implements Cloneable {
|
||||
public final class BOFRecord extends StandardRecord {
|
||||
/**
|
||||
* for BIFF8 files the BOF is 0x809. For earlier versions see
|
||||
* {@link #biff2_sid} {@link #biff3_sid} {@link #biff4_sid}
|
||||
* {@link #biff2_sid} {@link #biff3_sid} {@link #biff4_sid}
|
||||
* {@link #biff5_sid}
|
||||
*/
|
||||
public final static short sid = 0x809;
|
||||
public static final short sid = 0x809;
|
||||
// SIDs from earlier BIFF versions
|
||||
public final static short biff2_sid = 0x009;
|
||||
public final static short biff3_sid = 0x209;
|
||||
public final static short biff4_sid = 0x409;
|
||||
public final static short biff5_sid = 0x809;
|
||||
public static final short biff2_sid = 0x009;
|
||||
public static final short biff3_sid = 0x209;
|
||||
public static final short biff4_sid = 0x409;
|
||||
public static final short biff5_sid = 0x809;
|
||||
|
||||
/** suggested default (0x0600 - BIFF8) */
|
||||
public final static int VERSION = 0x0600;
|
||||
public static final int VERSION = 0x0600;
|
||||
/** suggested default 0x10d3 */
|
||||
public final static int BUILD = 0x10d3;
|
||||
public static final int BUILD = 0x10d3;
|
||||
/** suggested default 0x07CC (1996) */
|
||||
public final static int BUILD_YEAR = 0x07CC; // 1996
|
||||
public static final int BUILD_YEAR = 0x07CC; // 1996
|
||||
/** suggested default for a normal sheet (0x41) */
|
||||
public final static int HISTORY_MASK = 0x41;
|
||||
public static final int HISTORY_MASK = 0x41;
|
||||
|
||||
public final static int TYPE_WORKBOOK = 0x05;
|
||||
public final static int TYPE_VB_MODULE = 0x06;
|
||||
public final static int TYPE_WORKSHEET = 0x10;
|
||||
public final static int TYPE_CHART = 0x20;
|
||||
public final static int TYPE_EXCEL_4_MACRO = 0x40;
|
||||
public final static int TYPE_WORKSPACE_FILE = 0x100;
|
||||
public static final int TYPE_WORKBOOK = 0x05;
|
||||
public static final int TYPE_VB_MODULE = 0x06;
|
||||
public static final int TYPE_WORKSHEET = 0x10;
|
||||
public static final int TYPE_CHART = 0x20;
|
||||
public static final int TYPE_EXCEL_4_MACRO = 0x40;
|
||||
public static final int TYPE_WORKSPACE_FILE = 0x100;
|
||||
|
||||
private int field_1_version;
|
||||
private int field_2_type;
|
||||
|
@ -68,9 +64,18 @@ public final class BOFRecord extends StandardRecord implements Cloneable {
|
|||
/**
|
||||
* Constructs an empty BOFRecord with no fields set.
|
||||
*/
|
||||
public BOFRecord() {
|
||||
public BOFRecord() {}
|
||||
|
||||
public BOFRecord(BOFRecord other) {
|
||||
super(other);
|
||||
field_1_version = other.field_1_version;
|
||||
field_2_type = other.field_2_type;
|
||||
field_3_build = other.field_3_build;
|
||||
field_4_year = other.field_4_year;
|
||||
field_5_history = other.field_5_history;
|
||||
field_6_rversion = other.field_6_rversion;
|
||||
}
|
||||
|
||||
|
||||
private BOFRecord(int type) {
|
||||
field_1_version = VERSION;
|
||||
field_2_type = type;
|
||||
|
@ -79,7 +84,7 @@ public final class BOFRecord extends StandardRecord implements Cloneable {
|
|||
field_5_history = 0x01;
|
||||
field_6_rversion = VERSION;
|
||||
}
|
||||
|
||||
|
||||
public static BOFRecord createSheetBOF() {
|
||||
return new BOFRecord(TYPE_WORKSHEET);
|
||||
}
|
||||
|
@ -269,14 +274,15 @@ public final class BOFRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public BOFRecord clone() {
|
||||
BOFRecord rec = new BOFRecord();
|
||||
rec.field_1_version = field_1_version;
|
||||
rec.field_2_type = field_2_type;
|
||||
rec.field_3_build = field_3_build;
|
||||
rec.field_4_year = field_4_year;
|
||||
rec.field_5_history = field_5_history;
|
||||
rec.field_6_rversion = field_6_rversion;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BOFRecord copy() {
|
||||
return new BOFRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,33 +15,31 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: Backup Record <P>
|
||||
* Description: Boolean specifying whether
|
||||
* the GUI should store a backup of the file.<P>
|
||||
* REFERENCE: PG 287 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* Boolean specifying whether the GUI should store a backup of the file.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class BackupRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0x40;
|
||||
private short field_1_backup; // = 0;
|
||||
public final class BackupRecord extends StandardRecord {
|
||||
public static final short sid = 0x40;
|
||||
|
||||
public BackupRecord()
|
||||
{
|
||||
private short field_1_backup;
|
||||
|
||||
public BackupRecord() {}
|
||||
|
||||
public BackupRecord(BackupRecord other) {
|
||||
super(other);
|
||||
field_1_backup = other.field_1_backup;
|
||||
}
|
||||
|
||||
public BackupRecord(RecordInputStream in)
|
||||
{
|
||||
public BackupRecord(RecordInputStream in) {
|
||||
field_1_backup = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -90,4 +88,9 @@ public final class BackupRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackupRecord copy() {
|
||||
return new BackupRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,28 +19,32 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Blank cell record (0x0201) <P>
|
||||
* Description: Represents a column in a row with no value but with styling.<P>
|
||||
* REFERENCE: PG 287 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Represents a column in a row with no value but with styling.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
public final class BlankRecord extends StandardRecord implements CellValueRecordInterface, Cloneable {
|
||||
public final static short sid = 0x0201;
|
||||
private int field_1_row;
|
||||
private short field_2_col;
|
||||
private short field_3_xf;
|
||||
public final class BlankRecord extends StandardRecord implements CellValueRecordInterface {
|
||||
public static final short sid = 0x0201;
|
||||
|
||||
private int field_1_row;
|
||||
private short field_2_col;
|
||||
private short field_3_xf;
|
||||
|
||||
/** Creates a new instance of BlankRecord */
|
||||
public BlankRecord()
|
||||
{
|
||||
public BlankRecord() {}
|
||||
|
||||
public BlankRecord(BlankRecord other) {
|
||||
super(other);
|
||||
field_1_row = other.field_1_row;
|
||||
field_2_col = other.field_2_col;
|
||||
field_3_xf = other.field_3_xf;
|
||||
}
|
||||
|
||||
public BlankRecord(RecordInputStream in)
|
||||
{
|
||||
|
||||
public BlankRecord(RecordInputStream in) {
|
||||
field_1_row = in.readUShort();
|
||||
field_2_col = in.readShort();
|
||||
field_3_xf = in.readShort();
|
||||
|
@ -138,11 +142,15 @@ public final class BlankRecord extends StandardRecord implements CellValueRecord
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public BlankRecord clone() {
|
||||
BlankRecord rec = new BlankRecord();
|
||||
rec.field_1_row = field_1_row;
|
||||
rec.field_2_col = field_2_col;
|
||||
rec.field_3_xf = field_3_xf;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlankRecord copy() {
|
||||
return new BlankRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,33 +15,31 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: Save External Links record (BookBool)<P>
|
||||
* Description: Contains a flag specifying whether the Gui should save externally
|
||||
* linked values from other workbooks. <P>
|
||||
* REFERENCE: PG 289 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* Contains a flag specifying whether the Gui should save externally linked values from other workbooks.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class BookBoolRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0xDA;
|
||||
private short field_1_save_link_values;
|
||||
public final class BookBoolRecord extends StandardRecord {
|
||||
public static final short sid = 0xDA;
|
||||
|
||||
public BookBoolRecord()
|
||||
{
|
||||
private short field_1_save_link_values;
|
||||
|
||||
public BookBoolRecord() {}
|
||||
|
||||
public BookBoolRecord(BookBoolRecord other) {
|
||||
super(other);
|
||||
field_1_save_link_values = other.field_1_save_link_values;
|
||||
}
|
||||
|
||||
public BookBoolRecord(RecordInputStream in)
|
||||
{
|
||||
public BookBoolRecord(RecordInputStream in) {
|
||||
field_1_save_link_values = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -90,4 +88,9 @@ public final class BookBoolRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BookBoolRecord copy() {
|
||||
return new BookBoolRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,24 +21,27 @@ import org.apache.poi.ss.usermodel.FormulaError;
|
|||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Creates new BoolErrRecord. (0x0205) <P>
|
||||
* REFERENCE: PG ??? Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Michael P. Harhen
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Creates new BoolErrRecord. (0x0205)
|
||||
*/
|
||||
public final class BoolErrRecord extends CellRecord implements Cloneable {
|
||||
public final static short sid = 0x0205;
|
||||
public final class BoolErrRecord extends CellRecord {
|
||||
public static final short sid = 0x0205;
|
||||
private int _value;
|
||||
/**
|
||||
* If <code>true</code>, this record represents an error cell value, otherwise this record represents a boolean cell value
|
||||
* If <code>true</code>, this record represents an error cell value,
|
||||
* otherwise this record represents a boolean cell value
|
||||
*/
|
||||
private boolean _isError;
|
||||
|
||||
/** Creates new BoolErrRecord */
|
||||
public BoolErrRecord() {
|
||||
// fields uninitialised
|
||||
public BoolErrRecord() {}
|
||||
|
||||
public BoolErrRecord(BoolErrRecord other) {
|
||||
super(other);
|
||||
_value = other._value;
|
||||
_isError = other._isError;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,11 +186,15 @@ public final class BoolErrRecord extends CellRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public BoolErrRecord clone() {
|
||||
BoolErrRecord rec = new BoolErrRecord();
|
||||
copyBaseFields(rec);
|
||||
rec._value = _value;
|
||||
rec._isError = _isError;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoolErrRecord copy() {
|
||||
return new BoolErrRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,22 +20,24 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
|
||||
/**
|
||||
* Record for the bottom margin.
|
||||
*/
|
||||
public final class BottomMarginRecord extends StandardRecord implements Margin, Cloneable {
|
||||
public final static short sid = 0x29;
|
||||
public final class BottomMarginRecord extends StandardRecord implements Margin {
|
||||
public static final short sid = 0x29;
|
||||
private double field_1_margin;
|
||||
|
||||
public BottomMarginRecord()
|
||||
{
|
||||
public BottomMarginRecord() {}
|
||||
|
||||
public BottomMarginRecord(BottomMarginRecord other) {
|
||||
super(other);
|
||||
field_1_margin = other.field_1_margin;
|
||||
}
|
||||
|
||||
public BottomMarginRecord( RecordInputStream in )
|
||||
{
|
||||
public BottomMarginRecord( RecordInputStream in ) {
|
||||
field_1_margin = in.readDouble();
|
||||
}
|
||||
|
||||
|
@ -79,10 +81,15 @@ public final class BottomMarginRecord extends StandardRecord implements Margin,
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public BottomMarginRecord clone() {
|
||||
BottomMarginRecord rec = new BottomMarginRecord();
|
||||
rec.field_1_margin = this.field_1_margin;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
} // END OF
|
||||
@Override
|
||||
public BottomMarginRecord copy() {
|
||||
return new BottomMarginRecord(this);
|
||||
}
|
||||
}
|
|
@ -18,9 +18,9 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ss.util.WorkbookUtil;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
|
@ -28,20 +28,16 @@ import org.apache.poi.util.LittleEndian;
|
|||
import org.apache.poi.util.LittleEndianConsts;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import org.apache.poi.ss.util.WorkbookUtil;
|
||||
|
||||
/**
|
||||
* Title: Bound Sheet Record (aka BundleSheet) (0x0085)<P>
|
||||
* Description: Defines a sheet within a workbook. Basically stores the sheet name
|
||||
* and tells where the Beginning of file record is within the HSSF
|
||||
* file. <P>
|
||||
* REFERENCE: PG 291 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Defines a sheet within a workbook. Basically stores the sheet name and
|
||||
* tells where the Beginning of file record is within the HSSF file.
|
||||
*/
|
||||
public final class BoundSheetRecord extends StandardRecord {
|
||||
public final static short sid = 0x0085;
|
||||
|
||||
public static final short sid = 0x0085;
|
||||
private static final BitField hiddenFlag = BitFieldFactory.getInstance(0x01);
|
||||
private static final BitField veryHiddenFlag = BitFieldFactory.getInstance(0x02);
|
||||
|
||||
private int field_1_position_of_BOF;
|
||||
private int field_2_option_flags;
|
||||
private int field_4_isMultibyteUnicode;
|
||||
|
@ -52,13 +48,21 @@ public final class BoundSheetRecord extends StandardRecord {
|
|||
setSheetname(sheetname);
|
||||
}
|
||||
|
||||
public BoundSheetRecord(BoundSheetRecord other) {
|
||||
super(other);
|
||||
field_1_position_of_BOF = other.field_1_position_of_BOF;
|
||||
field_2_option_flags = other.field_2_option_flags;
|
||||
field_4_isMultibyteUnicode = other.field_4_isMultibyteUnicode;
|
||||
field_5_sheetname = other.field_5_sheetname;
|
||||
}
|
||||
|
||||
/**
|
||||
* UTF8: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
|
||||
* 1 + 1 + len(str)
|
||||
*
|
||||
* UNICODE: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
|
||||
* 1 + 1 + 2 * len(str)
|
||||
*
|
||||
*
|
||||
* @param in the record stream to read from
|
||||
*/
|
||||
public BoundSheetRecord(RecordInputStream in) {
|
||||
|
@ -158,7 +162,7 @@ public final class BoundSheetRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* Is the sheet hidden? Different from very hidden
|
||||
*
|
||||
*
|
||||
* @return {@code true} if hidden
|
||||
*/
|
||||
public boolean isHidden() {
|
||||
|
@ -167,7 +171,7 @@ public final class BoundSheetRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* Is the sheet hidden? Different from very hidden
|
||||
*
|
||||
*
|
||||
* @param hidden {@code true} if hidden
|
||||
*/
|
||||
public void setHidden(boolean hidden) {
|
||||
|
@ -176,7 +180,7 @@ public final class BoundSheetRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* Is the sheet very hidden? Different from (normal) hidden
|
||||
*
|
||||
*
|
||||
* @return {@code true} if very hidden
|
||||
*/
|
||||
public boolean isVeryHidden() {
|
||||
|
@ -185,7 +189,7 @@ public final class BoundSheetRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* Is the sheet very hidden? Different from (normal) hidden
|
||||
*
|
||||
*
|
||||
* @param veryHidden {@code true} if very hidden
|
||||
*/
|
||||
public void setVeryHidden(boolean veryHidden) {
|
||||
|
@ -195,22 +199,24 @@ public final class BoundSheetRecord extends StandardRecord {
|
|||
/**
|
||||
* Converts a List of {@link BoundSheetRecord}s to an array and sorts by the position of their
|
||||
* BOFs.
|
||||
*
|
||||
*
|
||||
* @param boundSheetRecords the boundSheetRecord list to arrayify
|
||||
*
|
||||
*
|
||||
* @return the sorted boundSheetRecords
|
||||
*/
|
||||
public static BoundSheetRecord[] orderByBofPosition(List<BoundSheetRecord> boundSheetRecords) {
|
||||
BoundSheetRecord[] bsrs = new BoundSheetRecord[boundSheetRecords.size()];
|
||||
boundSheetRecords.toArray(bsrs);
|
||||
Arrays.sort(bsrs, BOFComparator);
|
||||
Arrays.sort(bsrs, BoundSheetRecord::compareRecords);
|
||||
return bsrs;
|
||||
}
|
||||
|
||||
private static final Comparator<BoundSheetRecord> BOFComparator = new Comparator<BoundSheetRecord>() {
|
||||
|
||||
public int compare(BoundSheetRecord bsr1, BoundSheetRecord bsr2) {
|
||||
return bsr1.getPositionOfBof() - bsr2.getPositionOfBof();
|
||||
}
|
||||
};
|
||||
private static int compareRecords(BoundSheetRecord bsr1, BoundSheetRecord bsr2) {
|
||||
return bsr1.getPositionOfBof() - bsr2.getPositionOfBof();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoundSheetRecord copy() {
|
||||
return new BoundSheetRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,22 +21,28 @@ import org.apache.poi.hssf.record.common.FtrHeader;
|
|||
import org.apache.poi.hssf.record.common.FutureRecord;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Conditional Formatting Header v12 record CFHEADER12 (0x0879),
|
||||
* for conditional formattings introduced in Excel 2007 and newer.
|
||||
*/
|
||||
public final class CFHeader12Record extends CFHeaderBase implements FutureRecord, Cloneable {
|
||||
public final class CFHeader12Record extends CFHeaderBase implements FutureRecord {
|
||||
public static final short sid = 0x0879;
|
||||
|
||||
private FtrHeader futureHeader;
|
||||
|
||||
/** Creates new CFHeaderRecord */
|
||||
public CFHeader12Record() {
|
||||
createEmpty();
|
||||
futureHeader = new FtrHeader();
|
||||
futureHeader.setRecordType(sid);
|
||||
}
|
||||
|
||||
public CFHeader12Record(CFHeader12Record other) {
|
||||
super(other);
|
||||
futureHeader = other.futureHeader.copy();
|
||||
}
|
||||
|
||||
public CFHeader12Record(CellRangeAddress[] regions, int nRules) {
|
||||
super(regions, nRules);
|
||||
futureHeader = new FtrHeader();
|
||||
|
@ -78,12 +84,17 @@ public final class CFHeader12Record extends CFHeaderBase implements FutureRecord
|
|||
public CellRangeAddress getAssociatedRange() {
|
||||
return futureHeader.getAssociatedRange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CFHeader12Record clone() {
|
||||
CFHeader12Record result = new CFHeader12Record();
|
||||
result.futureHeader = (FtrHeader)futureHeader.clone();
|
||||
super.copyTo(result);
|
||||
return result;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CFHeader12Record copy() {
|
||||
return new CFHeader12Record(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,20 +21,28 @@ import org.apache.poi.ss.util.CellRangeAddress;
|
|||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.ss.util.CellRangeUtil;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Parent of Conditional Formatting Header records,
|
||||
* {@link CFHeaderRecord} and {@link CFHeader12Record}.
|
||||
*/
|
||||
public abstract class CFHeaderBase extends StandardRecord implements Cloneable {
|
||||
public abstract class CFHeaderBase extends StandardRecord {
|
||||
private int field_1_numcf;
|
||||
private int field_2_need_recalculation_and_id;
|
||||
private CellRangeAddress field_3_enclosing_cell_range;
|
||||
private CellRangeAddressList field_4_cell_ranges;
|
||||
|
||||
/** Creates new CFHeaderBase */
|
||||
protected CFHeaderBase() {
|
||||
protected CFHeaderBase() {}
|
||||
|
||||
protected CFHeaderBase(CFHeaderBase other) {
|
||||
super(other);
|
||||
field_1_numcf = other.field_1_numcf;
|
||||
field_2_need_recalculation_and_id = other.field_2_need_recalculation_and_id;
|
||||
field_3_enclosing_cell_range = other.field_3_enclosing_cell_range.copy();
|
||||
field_4_cell_ranges = other.field_4_cell_ranges.copy();
|
||||
}
|
||||
|
||||
protected CFHeaderBase(CellRangeAddress[] regions, int nRules) {
|
||||
CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(regions);
|
||||
setCellRanges(mergeCellRanges);
|
||||
|
@ -97,7 +105,7 @@ public abstract class CFHeaderBase extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set cell ranges list to a single cell range and
|
||||
* Set cell ranges list to a single cell range and
|
||||
* modify the enclosing cell range accordingly.
|
||||
* @param cellRanges - list of CellRange objects
|
||||
*/
|
||||
|
@ -151,13 +159,12 @@ public abstract class CFHeaderBase extends StandardRecord implements Cloneable {
|
|||
field_4_cell_ranges.serialize(out);
|
||||
}
|
||||
|
||||
protected void copyTo(CFHeaderBase result) {
|
||||
result.field_1_numcf = field_1_numcf;
|
||||
result.field_2_need_recalculation_and_id = field_2_need_recalculation_and_id;
|
||||
result.field_3_enclosing_cell_range = field_3_enclosing_cell_range.copy();
|
||||
result.field_4_cell_ranges = field_4_cell_ranges.copy();
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public abstract CFHeaderBase clone();
|
||||
|
||||
@Override
|
||||
public abstract CFHeaderBase clone(); // NOSONAR
|
||||
public abstract CFHeaderBase copy();
|
||||
}
|
||||
|
|
|
@ -18,19 +18,24 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Conditional Formatting Header record CFHEADER (0x01B0).
|
||||
* Used to describe a {@link CFRuleRecord}.
|
||||
* @see CFHeader12Record
|
||||
*/
|
||||
public final class CFHeaderRecord extends CFHeaderBase implements Cloneable {
|
||||
public final class CFHeaderRecord extends CFHeaderBase {
|
||||
public static final short sid = 0x01B0;
|
||||
|
||||
/** Creates new CFHeaderRecord */
|
||||
public CFHeaderRecord() {
|
||||
createEmpty();
|
||||
}
|
||||
|
||||
public CFHeaderRecord(CFHeaderRecord other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public CFHeaderRecord(CellRangeAddress[] regions, int nRules) {
|
||||
super(regions, nRules);
|
||||
}
|
||||
|
@ -48,9 +53,15 @@ public final class CFHeaderRecord extends CFHeaderBase implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CFHeaderRecord clone() {
|
||||
CFHeaderRecord result = new CFHeaderRecord();
|
||||
super.copyTo(result);
|
||||
return result;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CFHeaderRecord copy() {
|
||||
return new CFHeaderRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,18 +39,19 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Conditional Formatting v12 Rule Record (0x087A).
|
||||
*
|
||||
* Conditional Formatting v12 Rule Record (0x087A).
|
||||
*
|
||||
* <p>This is for newer-style Excel conditional formattings,
|
||||
* from Excel 2007 onwards.
|
||||
*
|
||||
*
|
||||
* <p>{@link CFRuleRecord} is used where the condition type is
|
||||
* {@link #CONDITION_TYPE_CELL_VALUE_IS} or {@link #CONDITION_TYPE_FORMULA},
|
||||
* this is only used for the other types
|
||||
*/
|
||||
public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cloneable {
|
||||
public final class CFRule12Record extends CFRuleBase implements FutureRecord {
|
||||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
@ -66,14 +67,35 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
private int template_type;
|
||||
private byte template_param_length;
|
||||
private byte[] template_params;
|
||||
|
||||
|
||||
private DataBarFormatting data_bar;
|
||||
private IconMultiStateFormatting multistate;
|
||||
private ColorGradientFormatting color_gradient;
|
||||
// TODO Parse this, see #58150
|
||||
private byte[] filter_data;
|
||||
|
||||
/** Creates new CFRuleRecord */
|
||||
public CFRule12Record(CFRule12Record other) {
|
||||
super(other);
|
||||
futureHeader = (other.futureHeader == null) ? null : other.futureHeader.copy();
|
||||
|
||||
// use min() to gracefully handle cases where the length-property and the array-length do not match
|
||||
// we saw some such files in circulation
|
||||
ext_formatting_length = Math.min(other.ext_formatting_length, other.ext_formatting_data.length);
|
||||
ext_formatting_data = other.ext_formatting_data.clone();
|
||||
|
||||
formula_scale = other.formula_scale.copy();
|
||||
|
||||
ext_opts = other.ext_opts;
|
||||
priority = other.priority;
|
||||
template_type = other.template_type;
|
||||
template_param_length = other.template_param_length;
|
||||
template_params = (other.template_params == null) ? null : other.template_params.clone();
|
||||
color_gradient = (other.color_gradient == null) ? null : other.color_gradient.copy();
|
||||
multistate = (other.multistate == null) ? null : other.multistate.copy();
|
||||
data_bar = (other.data_bar == null) ? null : other.data_bar.copy();
|
||||
filter_data = (other.filter_data == null) ? null : other.filter_data.clone();
|
||||
}
|
||||
|
||||
private CFRule12Record(byte conditionType, byte comparisonOperation) {
|
||||
super(conditionType, comparisonOperation);
|
||||
setDefaults();
|
||||
|
@ -84,15 +106,17 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
setDefaults();
|
||||
this.formula_scale = Formula.create(formulaScale);
|
||||
}
|
||||
|
||||
|
||||
private void setDefaults() {
|
||||
futureHeader = new FtrHeader();
|
||||
futureHeader.setRecordType(sid);
|
||||
|
||||
|
||||
ext_formatting_length = 0;
|
||||
ext_formatting_data = new byte[4];
|
||||
|
||||
|
||||
formula_scale = Formula.create(Ptg.EMPTY_PTG_ARRAY);
|
||||
|
||||
|
||||
ext_opts = 0;
|
||||
priority = 0;
|
||||
template_type = getConditionType();
|
||||
|
@ -102,10 +126,10 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
|
||||
/**
|
||||
* Creates a new comparison operation rule
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param formulaText the first formula text
|
||||
*
|
||||
*
|
||||
* @return a new comparison operation rule
|
||||
*/
|
||||
public static CFRule12Record create(HSSFSheet sheet, String formulaText) {
|
||||
|
@ -113,34 +137,34 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
return new CFRule12Record(CONDITION_TYPE_FORMULA, ComparisonOperator.NO_COMPARISON,
|
||||
formula1, null, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new comparison operation rule
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param comparisonOperation the comparison operation
|
||||
* @param formulaText1 the first formula text
|
||||
* @param formulaText2 the second formula text
|
||||
*
|
||||
*
|
||||
* @return a new comparison operation rule
|
||||
*/
|
||||
public static CFRule12Record create(HSSFSheet sheet, byte comparisonOperation,
|
||||
String formulaText1, String formulaText2) {
|
||||
Ptg[] formula1 = parseFormula(formulaText1, sheet);
|
||||
Ptg[] formula2 = parseFormula(formulaText2, sheet);
|
||||
return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation,
|
||||
return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation,
|
||||
formula1, formula2, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new comparison operation rule
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param comparisonOperation the comparison operation
|
||||
* @param formulaText1 the first formula text
|
||||
* @param formulaText2 the second formula text
|
||||
* @param formulaTextScale the scale to apply for the comparison
|
||||
*
|
||||
*
|
||||
* @return a new comparison operation rule
|
||||
*/
|
||||
public static CFRule12Record create(HSSFSheet sheet, byte comparisonOperation,
|
||||
|
@ -148,43 +172,43 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
Ptg[] formula1 = parseFormula(formulaText1, sheet);
|
||||
Ptg[] formula2 = parseFormula(formulaText2, sheet);
|
||||
Ptg[] formula3 = parseFormula(formulaTextScale, sheet);
|
||||
return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation,
|
||||
return new CFRule12Record(CONDITION_TYPE_CELL_VALUE_IS, comparisonOperation,
|
||||
formula1, formula2, formula3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Data Bar formatting
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param color the data bar color
|
||||
*
|
||||
*
|
||||
* @return a new Data Bar formatting
|
||||
*/
|
||||
public static CFRule12Record create(HSSFSheet sheet, ExtendedColor color) {
|
||||
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_DATA_BAR,
|
||||
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_DATA_BAR,
|
||||
ComparisonOperator.NO_COMPARISON);
|
||||
DataBarFormatting dbf = r.createDataBarFormatting();
|
||||
dbf.setColor(color);
|
||||
dbf.setPercentMin((byte)0);
|
||||
dbf.setPercentMax((byte)100);
|
||||
|
||||
|
||||
DataBarThreshold min = new DataBarThreshold();
|
||||
min.setType(RangeType.MIN.id);
|
||||
dbf.setThresholdMin(min);
|
||||
|
||||
|
||||
DataBarThreshold max = new DataBarThreshold();
|
||||
max.setType(RangeType.MAX.id);
|
||||
dbf.setThresholdMax(max);
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Icon Set / Multi-State formatting
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param iconSet the icon set
|
||||
*
|
||||
*
|
||||
* @return a new Icon Set / Multi-State formatting
|
||||
*/
|
||||
public static CFRule12Record create(HSSFSheet sheet, IconSet iconSet) {
|
||||
|
@ -192,20 +216,20 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
for (int i=0; i<ts.length; i++) {
|
||||
ts[i] = new IconMultiStateThreshold();
|
||||
}
|
||||
|
||||
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_ICON_SET,
|
||||
|
||||
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_ICON_SET,
|
||||
ComparisonOperator.NO_COMPARISON);
|
||||
IconMultiStateFormatting imf = r.createMultiStateFormatting();
|
||||
imf.setIconSet(iconSet);
|
||||
imf.setThresholds(ts);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Color Scale / Color Gradient formatting
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
*
|
||||
*
|
||||
* @return a new Color Scale / Color Gradient formatting
|
||||
*/
|
||||
public static CFRule12Record createColorScale(HSSFSheet sheet) {
|
||||
|
@ -216,8 +240,8 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
ts[i] = new ColorGradientThreshold();
|
||||
colors[i] = new ExtendedColor();
|
||||
}
|
||||
|
||||
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE,
|
||||
|
||||
CFRule12Record r = new CFRule12Record(CONDITION_TYPE_COLOR_SCALE,
|
||||
ComparisonOperator.NO_COMPARISON);
|
||||
ColorGradientFormatting cgf = r.createColorGradientFormatting();
|
||||
cgf.setNumControlPoints(numPoints);
|
||||
|
@ -232,7 +256,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
setComparisonOperation(in.readByte());
|
||||
int field_3_formula1_len = in.readUShort();
|
||||
int field_4_formula2_len = in.readUShort();
|
||||
|
||||
|
||||
ext_formatting_length = in.readInt();
|
||||
ext_formatting_data = new byte[0];
|
||||
if (ext_formatting_length == 0) {
|
||||
|
@ -245,13 +269,13 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
in.readFully(ext_formatting_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setFormula1(Formula.read(field_3_formula1_len, in));
|
||||
setFormula2(Formula.read(field_4_formula2_len, in));
|
||||
|
||||
|
||||
int formula_scale_len = in.readUShort();
|
||||
formula_scale = Formula.read(formula_scale_len, in);
|
||||
|
||||
|
||||
ext_opts = in.readByte();
|
||||
priority = in.readUShort();
|
||||
template_type = in.readUShort();
|
||||
|
@ -263,7 +287,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
logger.log(POILogger.WARN, "CF Rule v12 template params length should be 0 or 16, found " + template_param_length);
|
||||
in.readRemainder();
|
||||
}
|
||||
|
||||
|
||||
byte type = getConditionType();
|
||||
if (type == CONDITION_TYPE_COLOR_SCALE) {
|
||||
color_gradient = new ColorGradientFormatting(in);
|
||||
|
@ -275,7 +299,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
multistate = new IconMultiStateFormatting(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean containsDataBarBlock() {
|
||||
return (data_bar != null);
|
||||
}
|
||||
|
@ -284,7 +308,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
}
|
||||
public DataBarFormatting createDataBarFormatting() {
|
||||
if (data_bar != null) return data_bar;
|
||||
|
||||
|
||||
// Convert, setup and return
|
||||
setConditionType(CONDITION_TYPE_DATA_BAR);
|
||||
data_bar = new DataBarFormatting();
|
||||
|
@ -299,7 +323,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
}
|
||||
public IconMultiStateFormatting createMultiStateFormatting() {
|
||||
if (multistate != null) return multistate;
|
||||
|
||||
|
||||
// Convert, setup and return
|
||||
setConditionType(CONDITION_TYPE_ICON_SET);
|
||||
multistate = new IconMultiStateFormatting();
|
||||
|
@ -314,7 +338,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
}
|
||||
public ColorGradientFormatting createColorGradientFormatting() {
|
||||
if (color_gradient != null) return color_gradient;
|
||||
|
||||
|
||||
// Convert, setup and return
|
||||
setConditionType(CONDITION_TYPE_COLOR_SCALE);
|
||||
color_gradient = new ColorGradientFormatting();
|
||||
|
@ -356,7 +380,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
*/
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
futureHeader.serialize(out);
|
||||
|
||||
|
||||
int formula1Len=getFormulaSize(getFormula1());
|
||||
int formula2Len=getFormulaSize(getFormula2());
|
||||
|
||||
|
@ -364,7 +388,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
out.writeByte(getComparisonOperation());
|
||||
out.writeShort(formula1Len);
|
||||
out.writeShort(formula2Len);
|
||||
|
||||
|
||||
// TODO Update ext_formatting_length
|
||||
if (ext_formatting_length == 0) {
|
||||
out.writeInt(0);
|
||||
|
@ -374,18 +398,18 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
serializeFormattingBlock(out);
|
||||
out.write(ext_formatting_data);
|
||||
}
|
||||
|
||||
|
||||
getFormula1().serializeTokens(out);
|
||||
getFormula2().serializeTokens(out);
|
||||
out.writeShort(getFormulaSize(formula_scale));
|
||||
formula_scale.serializeTokens(out);
|
||||
|
||||
|
||||
out.writeByte(ext_opts);
|
||||
out.writeShort(priority);
|
||||
out.writeShort(template_type);
|
||||
out.writeByte(template_param_length);
|
||||
out.write(template_params);
|
||||
|
||||
|
||||
byte type = getConditionType();
|
||||
if (type == CONDITION_TYPE_COLOR_SCALE) {
|
||||
color_gradient.serialize(out);
|
||||
|
@ -409,7 +433,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
len += getFormulaSize(getFormula2());
|
||||
len += 2 + getFormulaSize(formula_scale);
|
||||
len += 6 + template_params.length;
|
||||
|
||||
|
||||
byte type = getConditionType();
|
||||
if (type == CONDITION_TYPE_COLOR_SCALE) {
|
||||
len += color_gradient.getDataLength();
|
||||
|
@ -461,44 +485,18 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord, Cl
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CFRule12Record clone() {
|
||||
CFRule12Record rec = new CFRule12Record(getConditionType(), getComparisonOperation());
|
||||
rec.futureHeader.setAssociatedRange(futureHeader.getAssociatedRange().copy());
|
||||
|
||||
super.copyTo(rec);
|
||||
|
||||
// use min() to gracefully handle cases where the length-property and the array-length do not match
|
||||
// we saw some such files in circulation
|
||||
rec.ext_formatting_length = Math.min(ext_formatting_length, ext_formatting_data.length);
|
||||
rec.ext_formatting_data = IOUtils.safelyAllocate(ext_formatting_length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(ext_formatting_data, 0, rec.ext_formatting_data, 0, rec.ext_formatting_length);
|
||||
|
||||
rec.formula_scale = formula_scale.copy();
|
||||
|
||||
rec.ext_opts = ext_opts;
|
||||
rec.priority = priority;
|
||||
rec.template_type = template_type;
|
||||
rec.template_param_length = template_param_length;
|
||||
rec.template_params = IOUtils.safelyAllocate(template_param_length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(template_params, 0, rec.template_params, 0, template_param_length);
|
||||
|
||||
if (color_gradient != null) {
|
||||
rec.color_gradient = (ColorGradientFormatting)color_gradient.clone();
|
||||
}
|
||||
if (multistate != null) {
|
||||
rec.multistate = (IconMultiStateFormatting)multistate.clone();
|
||||
}
|
||||
if (data_bar != null) {
|
||||
rec.data_bar = (DataBarFormatting)data_bar.clone();
|
||||
}
|
||||
if (filter_data != null) {
|
||||
rec.filter_data = IOUtils.safelyAllocate(filter_data.length, MAX_RECORD_LENGTH);
|
||||
System.arraycopy(filter_data, 0, rec.filter_data, 0, filter_data.length);
|
||||
}
|
||||
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CFRule12Record copy() {
|
||||
return new CFRule12Record(this);
|
||||
}
|
||||
|
||||
public short getFutureRecordType() {
|
||||
return futureHeader.getRecordType();
|
||||
}
|
||||
|
|
|
@ -30,32 +30,31 @@ import org.apache.poi.util.BitFieldFactory;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Conditional Formatting Rules. This can hold old-style rules
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* <p>This is for the older-style Excel conditional formattings,
|
||||
* new-style (Excel 2007+) also make use of {@link CFRule12Record}
|
||||
* for their rules.</p>
|
||||
*/
|
||||
public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
||||
public abstract class CFRuleBase extends StandardRecord {
|
||||
// FIXME: Merge with org.apache.poi.ss.usermodel.ComparisonOperator and rewrite as an enum
|
||||
public static final class ComparisonOperator {
|
||||
public static final byte NO_COMPARISON = 0;
|
||||
public static final byte BETWEEN = 1;
|
||||
public static final byte NOT_BETWEEN = 2;
|
||||
public static final byte EQUAL = 3;
|
||||
public static final byte NOT_EQUAL = 4;
|
||||
public static final byte GT = 5;
|
||||
public static final byte LT = 6;
|
||||
public static final byte GE = 7;
|
||||
public static final byte LE = 8;
|
||||
private static final byte max_operator = 8;
|
||||
public interface ComparisonOperator {
|
||||
byte NO_COMPARISON = 0;
|
||||
byte BETWEEN = 1;
|
||||
byte NOT_BETWEEN = 2;
|
||||
byte EQUAL = 3;
|
||||
byte NOT_EQUAL = 4;
|
||||
byte GT = 5;
|
||||
byte LT = 6;
|
||||
byte GE = 7;
|
||||
byte LE = 8;
|
||||
byte max_operator = 8;
|
||||
}
|
||||
protected static final POILogger logger = POILogFactory.getLogger(CFRuleBase.class);
|
||||
|
||||
private byte condition_type;
|
||||
// The only kinds that CFRuleRecord handles
|
||||
public static final byte CONDITION_TYPE_CELL_VALUE_IS = 1;
|
||||
public static final byte CONDITION_TYPE_FORMULA = 2;
|
||||
|
@ -65,8 +64,6 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
public static final byte CONDITION_TYPE_FILTER = 5;
|
||||
public static final byte CONDITION_TYPE_ICON_SET = 6;
|
||||
|
||||
private byte comparison_operator;
|
||||
|
||||
public static final int TEMPLATE_CELL_VALUE = 0x0000;
|
||||
public static final int TEMPLATE_FORMULA = 0x0001;
|
||||
public static final int TEMPLATE_COLOR_SCALE_FORMATTING = 0x0002;
|
||||
|
@ -94,7 +91,9 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
public static final int TEMPLATE_DUPLICATE_VALUES = 0x001B;
|
||||
public static final int TEMPLATE_ABOVE_OR_EQUAL_TO_AVERAGE = 0x001D;
|
||||
public static final int TEMPLATE_BELOW_OR_EQUAL_TO_AVERAGE = 0x001E;
|
||||
|
||||
|
||||
protected static final POILogger logger = POILogFactory.getLogger(CFRuleBase.class);
|
||||
|
||||
static final BitField modificationBits = bf(0x003FFFFF); // Bits: font,align,bord,patt,prot
|
||||
static final BitField alignHor = bf(0x00000001); // 0 = Horizontal alignment modified
|
||||
static final BitField alignVer = bf(0x00000002); // 0 = Vertical alignment modified
|
||||
|
@ -129,19 +128,24 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
return BitFieldFactory.getInstance(i);
|
||||
}
|
||||
|
||||
|
||||
private byte condition_type;
|
||||
private byte comparison_operator;
|
||||
|
||||
protected int formatting_options;
|
||||
protected short formatting_not_used; // TODO Decode this properly
|
||||
// TODO Decode this properly
|
||||
protected short formatting_not_used;
|
||||
|
||||
protected FontFormatting _fontFormatting;
|
||||
protected BorderFormatting _borderFormatting;
|
||||
protected PatternFormatting _patternFormatting;
|
||||
|
||||
|
||||
private Formula formula1;
|
||||
private Formula formula2;
|
||||
|
||||
/**
|
||||
* Creates new CFRuleRecord
|
||||
*
|
||||
*
|
||||
* @param conditionType the condition type
|
||||
* @param comparisonOperation the comparison operation
|
||||
*/
|
||||
|
@ -151,19 +155,34 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
formula1 = Formula.create(Ptg.EMPTY_PTG_ARRAY);
|
||||
formula2 = Formula.create(Ptg.EMPTY_PTG_ARRAY);
|
||||
}
|
||||
|
||||
protected CFRuleBase(byte conditionType, byte comparisonOperation, Ptg[] formula1, Ptg[] formula2) {
|
||||
this(conditionType, comparisonOperation);
|
||||
this.formula1 = Formula.create(formula1);
|
||||
this.formula2 = Formula.create(formula2);
|
||||
}
|
||||
|
||||
protected CFRuleBase() {}
|
||||
|
||||
|
||||
protected CFRuleBase(CFRuleBase other) {
|
||||
super(other);
|
||||
setConditionType(other.getConditionType());
|
||||
setComparisonOperation(other.getComparisonOperation());
|
||||
formatting_options = other.formatting_options;
|
||||
formatting_not_used = other.formatting_not_used;
|
||||
_fontFormatting = (!other.containsFontFormattingBlock()) ? null : other.getFontFormatting().copy();
|
||||
_borderFormatting = (!other.containsBorderFormattingBlock()) ? null : other.getBorderFormatting().copy();
|
||||
_patternFormatting = (!other.containsPatternFormattingBlock()) ? null : other.getPatternFormatting().copy();
|
||||
formula1 = other.getFormula1().copy();
|
||||
formula2 = other.getFormula2().copy();
|
||||
}
|
||||
|
||||
protected int readFormatOptions(RecordInputStream in) {
|
||||
formatting_options = in.readInt();
|
||||
formatting_not_used = in.readShort();
|
||||
|
||||
int len = 6;
|
||||
|
||||
|
||||
if (containsFontFormattingBlock()) {
|
||||
_fontFormatting = new FontFormatting(in);
|
||||
len += _fontFormatting.getDataLength();
|
||||
|
@ -178,7 +197,7 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
_patternFormatting = new PatternFormatting(in);
|
||||
len += _patternFormatting.getDataLength();
|
||||
}
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -187,10 +206,8 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
}
|
||||
protected void setConditionType(byte condition_type) {
|
||||
if ((this instanceof CFRuleRecord)) {
|
||||
if (condition_type == CONDITION_TYPE_CELL_VALUE_IS ||
|
||||
condition_type == CONDITION_TYPE_FORMULA) {
|
||||
// Good, valid combination
|
||||
} else {
|
||||
if (!(condition_type == CONDITION_TYPE_CELL_VALUE_IS ||
|
||||
condition_type == CONDITION_TYPE_FORMULA)) {
|
||||
throw new IllegalArgumentException("CFRuleRecord only accepts Value-Is and Formula types");
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +218,7 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
if (operation < 0 || operation > ComparisonOperator.max_operator)
|
||||
throw new IllegalArgumentException(
|
||||
"Valid operators are only in the range 0 to " +ComparisonOperator.max_operator);
|
||||
|
||||
|
||||
this.comparison_operator = operation;
|
||||
}
|
||||
public byte getComparisonOperation() {
|
||||
|
@ -351,7 +368,7 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
private void setOptionFlag(boolean flag, BitField field) {
|
||||
formatting_options = field.setBoolean(formatting_options, flag);
|
||||
}
|
||||
|
||||
|
||||
protected int getFormattingBlockSize() {
|
||||
return 6 +
|
||||
(containsFontFormattingBlock()?_fontFormatting.getRawRecord().length:0)+
|
||||
|
@ -375,7 +392,7 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
_patternFormatting.serialize(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the stack of the 1st expression as a list
|
||||
*
|
||||
|
@ -440,27 +457,13 @@ public abstract class CFRuleBase extends StandardRecord implements Cloneable {
|
|||
int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
|
||||
return HSSFFormulaParser.parse(formula, sheet.getWorkbook(), FormulaType.CELL, sheetIndex);
|
||||
}
|
||||
|
||||
protected void copyTo(CFRuleBase rec) {
|
||||
rec.condition_type = condition_type;
|
||||
rec.comparison_operator = comparison_operator;
|
||||
|
||||
rec.formatting_options = formatting_options;
|
||||
rec.formatting_not_used = formatting_not_used;
|
||||
if (containsFontFormattingBlock()) {
|
||||
rec._fontFormatting = _fontFormatting.clone();
|
||||
}
|
||||
if (containsBorderFormattingBlock()) {
|
||||
rec._borderFormatting = _borderFormatting.clone();
|
||||
}
|
||||
if (containsPatternFormattingBlock()) {
|
||||
rec._patternFormatting = (PatternFormatting) _patternFormatting.clone();
|
||||
}
|
||||
|
||||
rec.setFormula1(getFormula1().copy());
|
||||
rec.setFormula2(getFormula2().copy());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public abstract CFRuleBase clone();
|
||||
|
||||
@Override
|
||||
public abstract CFRuleBase copy();
|
||||
}
|
||||
|
|
|
@ -23,18 +23,22 @@ import org.apache.poi.hssf.usermodel.HSSFSheet;
|
|||
import org.apache.poi.ss.formula.Formula;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Conditional Formatting Rule Record (0x01B1).
|
||||
*
|
||||
* Conditional Formatting Rule Record (0x01B1).
|
||||
*
|
||||
* <p>This is for the older-style Excel conditional formattings,
|
||||
* new-style (Excel 2007+) also make use of {@link CFRule12Record}
|
||||
* for their rules.</p>
|
||||
*/
|
||||
public final class CFRuleRecord extends CFRuleBase implements Cloneable {
|
||||
public final class CFRuleRecord extends CFRuleBase {
|
||||
public static final short sid = 0x01B1;
|
||||
|
||||
/** Creates new CFRuleRecord */
|
||||
public CFRuleRecord(CFRuleRecord other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
private CFRuleRecord(byte conditionType, byte comparisonOperation) {
|
||||
super(conditionType, comparisonOperation);
|
||||
setDefaults();
|
||||
|
@ -59,10 +63,10 @@ public final class CFRuleRecord extends CFRuleBase implements Cloneable {
|
|||
|
||||
/**
|
||||
* Creates a new comparison operation rule
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param formulaText the formula text
|
||||
*
|
||||
*
|
||||
* @return a new comparison operation rule
|
||||
*/
|
||||
public static CFRuleRecord create(HSSFSheet sheet, String formulaText) {
|
||||
|
@ -72,12 +76,12 @@ public final class CFRuleRecord extends CFRuleBase implements Cloneable {
|
|||
}
|
||||
/**
|
||||
* Creates a new comparison operation rule
|
||||
*
|
||||
*
|
||||
* @param sheet the sheet
|
||||
* @param comparisonOperation the comparison operation
|
||||
* @param formulaText1 the first formula text
|
||||
* @param formulaText2 the second formula text
|
||||
*
|
||||
*
|
||||
* @return a new comparison operation rule
|
||||
*/
|
||||
public static CFRuleRecord create(HSSFSheet sheet, byte comparisonOperation,
|
||||
|
@ -120,7 +124,7 @@ public final class CFRuleRecord extends CFRuleBase implements Cloneable {
|
|||
out.writeByte(getComparisonOperation());
|
||||
out.writeShort(formula1Len);
|
||||
out.writeShort(formula2Len);
|
||||
|
||||
|
||||
serializeFormattingBlock(out);
|
||||
|
||||
getFormula1().serializeTokens(out);
|
||||
|
@ -156,9 +160,15 @@ public final class CFRuleRecord extends CFRuleBase implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CFRuleRecord clone() {
|
||||
CFRuleRecord rec = new CFRuleRecord(getConditionType(), getComparisonOperation());
|
||||
super.copyTo(rec);
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CFRuleRecord copy() {
|
||||
return new CFRuleRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,30 +19,26 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
/**
|
||||
* XCT - CRN Count <P>
|
||||
*
|
||||
* REFERENCE: 5.114<P>
|
||||
*
|
||||
* @author Josh Micich
|
||||
* XCT - CRN Count
|
||||
*/
|
||||
public final class CRNCountRecord extends StandardRecord {
|
||||
public final static short sid = 0x59;
|
||||
public static final short sid = 0x59;
|
||||
|
||||
private static final short DATA_SIZE = 4;
|
||||
|
||||
private int field_1_number_crn_records;
|
||||
private int field_2_sheet_table_index;
|
||||
|
||||
private int field_1_number_crn_records;
|
||||
private int field_2_sheet_table_index;
|
||||
|
||||
public CRNCountRecord() {
|
||||
throw new RuntimeException("incomplete code");
|
||||
private CRNCountRecord() {
|
||||
// incomplete code
|
||||
}
|
||||
|
||||
public int getNumberOfCRNs() {
|
||||
return field_1_number_crn_records;
|
||||
public CRNCountRecord(CRNCountRecord other) {
|
||||
super(other);
|
||||
field_1_number_crn_records = other.field_1_number_crn_records;
|
||||
field_2_sheet_table_index = other.field_2_sheet_table_index;
|
||||
}
|
||||
|
||||
|
||||
public CRNCountRecord(RecordInputStream in) {
|
||||
field_1_number_crn_records = in.readShort();
|
||||
if(field_1_number_crn_records < 0) {
|
||||
|
@ -53,6 +49,9 @@ public final class CRNCountRecord extends StandardRecord {
|
|||
field_2_sheet_table_index = in.readShort();
|
||||
}
|
||||
|
||||
public int getNumberOfCRNs() {
|
||||
return field_1_number_crn_records;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -77,4 +76,9 @@ public final class CRNCountRecord extends StandardRecord {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CRNCountRecord copy() {
|
||||
return new CRNCountRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,27 +21,30 @@ import org.apache.poi.ss.formula.constant.ConstantValueParser;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* Title: CRN(0x005A)<p>
|
||||
* Description: This record stores the contents of an external cell or cell range<p>
|
||||
* REFERENCE: OOO 5.23
|
||||
* This record stores the contents of an external cell or cell range
|
||||
*/
|
||||
public final class CRNRecord extends StandardRecord {
|
||||
public final static short sid = 0x005A;
|
||||
public static final short sid = 0x005A;
|
||||
|
||||
private int field_1_last_column_index;
|
||||
private int field_2_first_column_index;
|
||||
private int field_3_row_index;
|
||||
private int field_1_last_column_index;
|
||||
private int field_2_first_column_index;
|
||||
private int field_3_row_index;
|
||||
private Object[] field_4_constant_values;
|
||||
|
||||
public CRNRecord() {
|
||||
throw new RuntimeException("incomplete code");
|
||||
private CRNRecord() {
|
||||
// incomplete code
|
||||
}
|
||||
|
||||
public int getNumberOfCRNs() {
|
||||
return field_1_last_column_index;
|
||||
public CRNRecord(CRNRecord other) {
|
||||
super(other);
|
||||
field_1_last_column_index = other.field_1_last_column_index;
|
||||
field_2_first_column_index = other.field_2_first_column_index;
|
||||
field_3_row_index = other.field_3_row_index;
|
||||
// field_4_constant_values are instances of Double, Boolean, String, ErrorCode,
|
||||
// i.e. they are immutable and can their references can be simply cloned
|
||||
field_4_constant_values = (other.field_4_constant_values == null) ? null : other.field_4_constant_values.clone();
|
||||
}
|
||||
|
||||
|
||||
public CRNRecord(RecordInputStream in) {
|
||||
field_1_last_column_index = in.readUByte();
|
||||
field_2_first_column_index = in.readUByte();
|
||||
|
@ -50,6 +53,9 @@ public final class CRNRecord extends StandardRecord {
|
|||
field_4_constant_values = ConstantValueParser.parse(in, nValues);
|
||||
}
|
||||
|
||||
public int getNumberOfCRNs() {
|
||||
return field_1_last_column_index;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -77,4 +83,9 @@ public final class CRNRecord extends StandardRecord {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CRNRecord copy() {
|
||||
return new CRNRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,34 +15,37 @@
|
|||
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.Removal;
|
||||
|
||||
/**
|
||||
* Title: Calc Count Record
|
||||
* Description: Specifies the maximum times the gui should perform a formula
|
||||
* recalculation. For instance: in the case a formula includes
|
||||
* cells that are themselves a result of a formula and a value
|
||||
* changes. This is essentially a failsafe against an infinate
|
||||
* loop in the event the formulas are not independant. <P>
|
||||
* REFERENCE: PG 292 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* Specifies the maximum times the gui should perform a formula recalculation.
|
||||
* For instance: in the case a formula includes cells that are themselves a result of a formula and
|
||||
* a value changes. This is essentially a failsafe against an infinite loop in the event the formulas
|
||||
* are not independent.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
* @see org.apache.poi.hssf.record.CalcModeRecord
|
||||
* @see CalcModeRecord
|
||||
*/
|
||||
|
||||
public final class CalcCountRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0xC;
|
||||
private short field_1_iterations;
|
||||
public final class CalcCountRecord extends StandardRecord {
|
||||
public static final short sid = 0xC;
|
||||
|
||||
public CalcCountRecord()
|
||||
{
|
||||
private short field_1_iterations;
|
||||
|
||||
public CalcCountRecord() {}
|
||||
|
||||
public CalcCountRecord(CalcCountRecord other) {
|
||||
super(other);
|
||||
field_1_iterations = other.field_1_iterations;
|
||||
}
|
||||
|
||||
public CalcCountRecord(RecordInputStream in)
|
||||
{
|
||||
|
||||
public CalcCountRecord(RecordInputStream in) {
|
||||
field_1_iterations = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -91,9 +94,15 @@ public final class CalcCountRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CalcCountRecord clone() {
|
||||
CalcCountRecord rec = new CalcCountRecord();
|
||||
rec.field_1_iterations = field_1_iterations;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalcCountRecord copy() {
|
||||
return new CalcCountRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,52 +15,42 @@
|
|||
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.Removal;
|
||||
|
||||
/**
|
||||
* Title: Calc Mode Record<P>
|
||||
* Description: Tells the gui whether to calculate formulas
|
||||
* automatically, manually or automatically
|
||||
* except for tables.<P>
|
||||
* REFERENCE: PG 292 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Tells the gui whether to calculate formulas automatically, manually or automatically except for tables.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
* @see org.apache.poi.hssf.record.CalcCountRecord
|
||||
* @see CalcCountRecord
|
||||
*/
|
||||
|
||||
public final class CalcModeRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0xD;
|
||||
public final class CalcModeRecord extends StandardRecord {
|
||||
public static final short sid = 0xD;
|
||||
|
||||
/**
|
||||
* manually calculate formulas (0)
|
||||
*/
|
||||
/** manually calculate formulas (0) */
|
||||
public static final short MANUAL = 0;
|
||||
|
||||
public final static short MANUAL = 0;
|
||||
/** automatically calculate formulas (1) */
|
||||
public static final short AUTOMATIC = 1;
|
||||
|
||||
/**
|
||||
* automatically calculate formulas (1)
|
||||
*/
|
||||
/** automatically calculate formulas except for tables (-1) */
|
||||
public static final short AUTOMATIC_EXCEPT_TABLES = -1;
|
||||
|
||||
public final static short AUTOMATIC = 1;
|
||||
private short field_1_calcmode;
|
||||
|
||||
/**
|
||||
* automatically calculate formulas except for tables (-1)
|
||||
*/
|
||||
public CalcModeRecord() {}
|
||||
|
||||
public final static short AUTOMATIC_EXCEPT_TABLES = -1;
|
||||
private short field_1_calcmode;
|
||||
|
||||
public CalcModeRecord()
|
||||
{
|
||||
public CalcModeRecord(CalcModeRecord other) {
|
||||
super(other);
|
||||
field_1_calcmode = other.field_1_calcmode;
|
||||
}
|
||||
|
||||
public CalcModeRecord(RecordInputStream in)
|
||||
{
|
||||
public CalcModeRecord(RecordInputStream in) {
|
||||
field_1_calcmode = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -119,9 +109,15 @@ public final class CalcModeRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CalcModeRecord clone() {
|
||||
CalcModeRecord rec = new CalcModeRecord();
|
||||
rec.field_1_calcmode = field_1_calcmode;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CalcModeRecord copy() {
|
||||
return new CalcModeRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,13 @@ public abstract class CellRecord extends StandardRecord implements CellValueReco
|
|||
private int _columnIndex;
|
||||
private int _formatIndex;
|
||||
|
||||
protected CellRecord() {
|
||||
// fields uninitialised
|
||||
protected CellRecord() {}
|
||||
|
||||
protected CellRecord(CellRecord other) {
|
||||
super(other);
|
||||
_rowIndex = other.getRow();
|
||||
_columnIndex = other.getColumn();
|
||||
_formatIndex = other.getXFIndex();
|
||||
}
|
||||
|
||||
protected CellRecord(RecordInputStream in) {
|
||||
|
@ -100,21 +105,21 @@ public abstract class CellRecord extends StandardRecord implements CellValueReco
|
|||
* 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).
|
||||
*
|
||||
*
|
||||
* @param sb the StringBuilder to write to
|
||||
*/
|
||||
protected abstract void appendValueText(StringBuilder sb);
|
||||
|
||||
/**
|
||||
* Gets the debug info BIFF record type name (used by {@link #toString()}.
|
||||
*
|
||||
*
|
||||
* @return the record type name
|
||||
*/
|
||||
protected abstract String getRecordName();
|
||||
|
||||
/**
|
||||
* writes out the value data for this cell record
|
||||
*
|
||||
*
|
||||
* @param out the output
|
||||
*/
|
||||
protected abstract void serializeValue(LittleEndianOutput out);
|
||||
|
@ -137,9 +142,6 @@ public abstract class CellRecord extends StandardRecord implements CellValueReco
|
|||
return 6 + getValueDataSize();
|
||||
}
|
||||
|
||||
protected final void copyBaseFields(CellRecord rec) {
|
||||
rec._rowIndex = _rowIndex;
|
||||
rec._columnIndex = _columnIndex;
|
||||
rec._formatIndex = _formatIndex;
|
||||
}
|
||||
@Override
|
||||
public abstract CellRecord copy();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
|
@ -23,33 +23,33 @@ import org.apache.poi.util.CodePageUtil;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* Title: Codepage Record
|
||||
* <p>Description: the default characterset. for the workbook</p>
|
||||
* <p>REFERENCE: PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)</p>
|
||||
* <p>Use {@link CodePageUtil} to turn these values into Java code pages
|
||||
* to encode/decode strings.</p>
|
||||
* The default characterset. for the workbook<p>
|
||||
*
|
||||
* Use {@link CodePageUtil} to turn these values into Java code pages to encode/decode strings.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class CodepageRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0x42;
|
||||
private short field_1_codepage; // = 0;
|
||||
public final class CodepageRecord extends StandardRecord {
|
||||
public static final short sid = 0x42;
|
||||
|
||||
/**
|
||||
* Excel 97+ (Biff 8) should always store strings as UTF-16LE or
|
||||
* compressed versions of that. As such, this should always be
|
||||
* 0x4b0 = UTF_16, except for files coming from older versions.
|
||||
*/
|
||||
public final static short CODEPAGE = ( short ) 0x4b0;
|
||||
public static final short CODEPAGE = ( short ) 0x4b0;
|
||||
|
||||
public CodepageRecord()
|
||||
{
|
||||
private short field_1_codepage;
|
||||
|
||||
public CodepageRecord() {}
|
||||
|
||||
public CodepageRecord(CodepageRecord other) {
|
||||
super(other);
|
||||
field_1_codepage = other.field_1_codepage;
|
||||
}
|
||||
|
||||
public CodepageRecord(RecordInputStream in)
|
||||
{
|
||||
public CodepageRecord(RecordInputStream in) {
|
||||
field_1_codepage = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -100,4 +100,9 @@ public final class CodepageRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodepageRecord copy() {
|
||||
return new CodepageRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,27 +17,27 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: COLINFO Record (0x007D)<p>
|
||||
* Description: Defines with width and formatting for a range of columns<p>
|
||||
* REFERENCE: PG 293 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Defines with width and formatting for a range of columns
|
||||
*/
|
||||
public final class ColumnInfoRecord extends StandardRecord implements Cloneable {
|
||||
public final class ColumnInfoRecord extends StandardRecord {
|
||||
public static final short sid = 0x007D;
|
||||
|
||||
private static final BitField hidden = BitFieldFactory.getInstance(0x01);
|
||||
private static final BitField outlevel = BitFieldFactory.getInstance(0x0700);
|
||||
private static final BitField collapsed = BitFieldFactory.getInstance(0x1000);
|
||||
|
||||
private int _firstCol;
|
||||
private int _lastCol;
|
||||
private int _colWidth;
|
||||
private int _xfIndex;
|
||||
private int _options;
|
||||
private static final BitField hidden = BitFieldFactory.getInstance(0x01);
|
||||
private static final BitField outlevel = BitFieldFactory.getInstance(0x0700);
|
||||
private static final BitField collapsed = BitFieldFactory.getInstance(0x1000);
|
||||
// Excel seems write values 2, 10, and 260, even though spec says "must be zero"
|
||||
private int field_6_reserved;
|
||||
|
||||
|
@ -51,6 +51,16 @@ public final class ColumnInfoRecord extends StandardRecord implements Cloneable
|
|||
field_6_reserved = 2; // seems to be the most common value
|
||||
}
|
||||
|
||||
public ColumnInfoRecord(ColumnInfoRecord other) {
|
||||
super(other);
|
||||
_firstCol = other._firstCol;
|
||||
_lastCol = other._lastCol;
|
||||
_colWidth = other._colWidth;
|
||||
_xfIndex = other._xfIndex;
|
||||
_options = other._options;
|
||||
field_6_reserved = other.field_6_reserved;
|
||||
}
|
||||
|
||||
public ColumnInfoRecord(RecordInputStream in) {
|
||||
_firstCol = in.readUShort();
|
||||
_lastCol = in.readUShort();
|
||||
|
@ -196,7 +206,7 @@ public final class ColumnInfoRecord extends StandardRecord implements Cloneable
|
|||
|
||||
/**
|
||||
* @param other the format to match with
|
||||
*
|
||||
*
|
||||
* @return {@code true} if the format, options and column width match
|
||||
*/
|
||||
public boolean formatMatches(ColumnInfoRecord other) {
|
||||
|
@ -246,14 +256,15 @@ public final class ColumnInfoRecord extends StandardRecord implements Cloneable
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public ColumnInfoRecord clone() {
|
||||
ColumnInfoRecord rec = new ColumnInfoRecord();
|
||||
rec._firstCol = _firstCol;
|
||||
rec._lastCol = _lastCol;
|
||||
rec._colWidth = _colWidth;
|
||||
rec._xfIndex = _xfIndex;
|
||||
rec._options = _options;
|
||||
rec.field_6_reserved = field_6_reserved;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnInfoRecord copy() {
|
||||
return new ColumnInfoRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,50 +23,51 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* The common object data record is used to store all common preferences for an excel object.
|
||||
*/
|
||||
public final class CommonObjectDataSubRecord extends SubRecord implements Cloneable {
|
||||
public final static short sid = 0x0015;
|
||||
public final class CommonObjectDataSubRecord extends SubRecord {
|
||||
public static final short sid = 0x0015;
|
||||
|
||||
private static final BitField locked = BitFieldFactory.getInstance(0x0001);
|
||||
private static final BitField printable = BitFieldFactory.getInstance(0x0010);
|
||||
private static final BitField autofill = BitFieldFactory.getInstance(0x2000);
|
||||
private static final BitField autoline = BitFieldFactory.getInstance(0x4000);
|
||||
|
||||
public final static short OBJECT_TYPE_GROUP = 0;
|
||||
public final static short OBJECT_TYPE_LINE = 1;
|
||||
public final static short OBJECT_TYPE_RECTANGLE = 2;
|
||||
public final static short OBJECT_TYPE_OVAL = 3;
|
||||
public final static short OBJECT_TYPE_ARC = 4;
|
||||
public final static short OBJECT_TYPE_CHART = 5;
|
||||
public final static short OBJECT_TYPE_TEXT = 6;
|
||||
public final static short OBJECT_TYPE_BUTTON = 7;
|
||||
public final static short OBJECT_TYPE_PICTURE = 8;
|
||||
public final static short OBJECT_TYPE_POLYGON = 9;
|
||||
public final static short OBJECT_TYPE_RESERVED1 = 10;
|
||||
public final static short OBJECT_TYPE_CHECKBOX = 11;
|
||||
public final static short OBJECT_TYPE_OPTION_BUTTON = 12;
|
||||
public final static short OBJECT_TYPE_EDIT_BOX = 13;
|
||||
public final static short OBJECT_TYPE_LABEL = 14;
|
||||
public final static short OBJECT_TYPE_DIALOG_BOX = 15;
|
||||
public final static short OBJECT_TYPE_SPINNER = 16;
|
||||
public final static short OBJECT_TYPE_SCROLL_BAR = 17;
|
||||
public final static short OBJECT_TYPE_LIST_BOX = 18;
|
||||
public final static short OBJECT_TYPE_GROUP_BOX = 19;
|
||||
public final static short OBJECT_TYPE_COMBO_BOX = 20;
|
||||
public final static short OBJECT_TYPE_RESERVED2 = 21;
|
||||
public final static short OBJECT_TYPE_RESERVED3 = 22;
|
||||
public final static short OBJECT_TYPE_RESERVED4 = 23;
|
||||
public final static short OBJECT_TYPE_RESERVED5 = 24;
|
||||
public final static short OBJECT_TYPE_COMMENT = 25;
|
||||
public final static short OBJECT_TYPE_RESERVED6 = 26;
|
||||
public final static short OBJECT_TYPE_RESERVED7 = 27;
|
||||
public final static short OBJECT_TYPE_RESERVED8 = 28;
|
||||
public final static short OBJECT_TYPE_RESERVED9 = 29;
|
||||
public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30;
|
||||
|
||||
public static final short OBJECT_TYPE_GROUP = 0;
|
||||
public static final short OBJECT_TYPE_LINE = 1;
|
||||
public static final short OBJECT_TYPE_RECTANGLE = 2;
|
||||
public static final short OBJECT_TYPE_OVAL = 3;
|
||||
public static final short OBJECT_TYPE_ARC = 4;
|
||||
public static final short OBJECT_TYPE_CHART = 5;
|
||||
public static final short OBJECT_TYPE_TEXT = 6;
|
||||
public static final short OBJECT_TYPE_BUTTON = 7;
|
||||
public static final short OBJECT_TYPE_PICTURE = 8;
|
||||
public static final short OBJECT_TYPE_POLYGON = 9;
|
||||
public static final short OBJECT_TYPE_RESERVED1 = 10;
|
||||
public static final short OBJECT_TYPE_CHECKBOX = 11;
|
||||
public static final short OBJECT_TYPE_OPTION_BUTTON = 12;
|
||||
public static final short OBJECT_TYPE_EDIT_BOX = 13;
|
||||
public static final short OBJECT_TYPE_LABEL = 14;
|
||||
public static final short OBJECT_TYPE_DIALOG_BOX = 15;
|
||||
public static final short OBJECT_TYPE_SPINNER = 16;
|
||||
public static final short OBJECT_TYPE_SCROLL_BAR = 17;
|
||||
public static final short OBJECT_TYPE_LIST_BOX = 18;
|
||||
public static final short OBJECT_TYPE_GROUP_BOX = 19;
|
||||
public static final short OBJECT_TYPE_COMBO_BOX = 20;
|
||||
public static final short OBJECT_TYPE_RESERVED2 = 21;
|
||||
public static final short OBJECT_TYPE_RESERVED3 = 22;
|
||||
public static final short OBJECT_TYPE_RESERVED4 = 23;
|
||||
public static final short OBJECT_TYPE_RESERVED5 = 24;
|
||||
public static final short OBJECT_TYPE_COMMENT = 25;
|
||||
public static final short OBJECT_TYPE_RESERVED6 = 26;
|
||||
public static final short OBJECT_TYPE_RESERVED7 = 27;
|
||||
public static final short OBJECT_TYPE_RESERVED8 = 28;
|
||||
public static final short OBJECT_TYPE_RESERVED9 = 29;
|
||||
public static final short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30;
|
||||
|
||||
private short field_1_objectType;
|
||||
private int field_2_objectId;
|
||||
private short field_3_option;
|
||||
|
@ -75,9 +76,16 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
private int field_6_reserved3;
|
||||
|
||||
|
||||
public CommonObjectDataSubRecord()
|
||||
{
|
||||
public CommonObjectDataSubRecord() {}
|
||||
|
||||
public CommonObjectDataSubRecord(CommonObjectDataSubRecord other) {
|
||||
super(other);
|
||||
field_1_objectType = other.field_1_objectType;
|
||||
field_2_objectId = other.field_2_objectId;
|
||||
field_3_option = other.field_3_option;
|
||||
field_4_reserved1 = other.field_4_reserved1;
|
||||
field_5_reserved2 = other.field_5_reserved2;
|
||||
field_6_reserved3 = other.field_6_reserved3;
|
||||
}
|
||||
|
||||
public CommonObjectDataSubRecord(LittleEndianInput in, int size) {
|
||||
|
@ -101,31 +109,31 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
buffer.append(" .objectType = ")
|
||||
.append("0x").append(HexDump.toHex( getObjectType ()))
|
||||
.append(" (").append( getObjectType() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .objectId = ")
|
||||
.append("0x").append(HexDump.toHex( getObjectId ()))
|
||||
.append(" (").append( getObjectId() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .option = ")
|
||||
.append("0x").append(HexDump.toHex( getOption ()))
|
||||
.append(" (").append( getOption() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .locked = ").append(isLocked()).append('\n');
|
||||
buffer.append(" .printable = ").append(isPrintable()).append('\n');
|
||||
buffer.append(" .autofill = ").append(isAutofill()).append('\n');
|
||||
buffer.append(" .autoline = ").append(isAutoline()).append('\n');
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .locked = ").append(isLocked()).append('\n');
|
||||
buffer.append(" .printable = ").append(isPrintable()).append('\n');
|
||||
buffer.append(" .autofill = ").append(isAutofill()).append('\n');
|
||||
buffer.append(" .autoline = ").append(isAutoline()).append('\n');
|
||||
buffer.append(" .reserved1 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved1 ()))
|
||||
.append(" (").append( getReserved1() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved2 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved2 ()))
|
||||
.append(" (").append( getReserved2() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(" .reserved3 = ")
|
||||
.append("0x").append(HexDump.toHex( getReserved3 ()))
|
||||
.append(" (").append( getReserved3() ).append(" )");
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
buffer.append(System.getProperty("line.separator"));
|
||||
|
||||
buffer.append("[/ftCmo]\n");
|
||||
return buffer.toString();
|
||||
|
@ -159,23 +167,23 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public CommonObjectDataSubRecord clone() {
|
||||
CommonObjectDataSubRecord rec = new CommonObjectDataSubRecord();
|
||||
|
||||
rec.field_1_objectType = field_1_objectType;
|
||||
rec.field_2_objectId = field_2_objectId;
|
||||
rec.field_3_option = field_3_option;
|
||||
rec.field_4_reserved1 = field_4_reserved1;
|
||||
rec.field_5_reserved2 = field_5_reserved2;
|
||||
rec.field_6_reserved3 = field_6_reserved3;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonObjectDataSubRecord copy() {
|
||||
return new CommonObjectDataSubRecord(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the object type field for the CommonObjectData record.
|
||||
*
|
||||
* @return One of
|
||||
* @return One of
|
||||
* OBJECT_TYPE_GROUP
|
||||
* OBJECT_TYPE_LINE
|
||||
* OBJECT_TYPE_RECTANGLE
|
||||
|
@ -217,7 +225,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
* Set the object type field for the CommonObjectData record.
|
||||
*
|
||||
* @param field_1_objectType
|
||||
* One of
|
||||
* One of
|
||||
* OBJECT_TYPE_GROUP
|
||||
* OBJECT_TYPE_LINE
|
||||
* OBJECT_TYPE_RECTANGLE
|
||||
|
@ -257,7 +265,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Get the object id field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @return the object id field
|
||||
*/
|
||||
public int getObjectId()
|
||||
|
@ -267,7 +275,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Set the object id field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @param field_2_objectId the object id field
|
||||
*/
|
||||
public void setObjectId(int field_2_objectId)
|
||||
|
@ -277,7 +285,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Get the option field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @return the option field
|
||||
*/
|
||||
public short getOption()
|
||||
|
@ -287,7 +295,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Set the option field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @param field_3_option the option field
|
||||
*/
|
||||
public void setOption(short field_3_option)
|
||||
|
@ -297,7 +305,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Get the reserved1 field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @return the reserved1 field
|
||||
*/
|
||||
public int getReserved1()
|
||||
|
@ -307,7 +315,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Set the reserved1 field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @param field_4_reserved1 the reserved1 field
|
||||
*/
|
||||
public void setReserved1(int field_4_reserved1)
|
||||
|
@ -317,7 +325,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Get the reserved2 field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @return the reserved2 field
|
||||
*/
|
||||
public int getReserved2()
|
||||
|
@ -327,7 +335,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Set the reserved2 field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @param field_5_reserved2 the reserved2 field
|
||||
*/
|
||||
public void setReserved2(int field_5_reserved2)
|
||||
|
@ -337,7 +345,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Get the reserved3 field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @return the reserved3 field
|
||||
*/
|
||||
public int getReserved3()
|
||||
|
@ -347,7 +355,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
|
||||
/**
|
||||
* Set the reserved3 field for the CommonObjectData record.
|
||||
*
|
||||
*
|
||||
* @param field_6_reserved3 the reserved3 field
|
||||
*/
|
||||
public void setReserved3(int field_6_reserved3)
|
||||
|
@ -358,7 +366,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
/**
|
||||
* Sets the locked field value.
|
||||
* true if object is locked when sheet has been protected
|
||||
*
|
||||
*
|
||||
* @param value {@code true} if object is locked when sheet has been protected
|
||||
*/
|
||||
public void setLocked(boolean value)
|
||||
|
@ -378,7 +386,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
/**
|
||||
* Sets the printable field value.
|
||||
* object appears when printed
|
||||
*
|
||||
*
|
||||
* @param value {@code true} if object appears when printed
|
||||
*/
|
||||
public void setPrintable(boolean value)
|
||||
|
@ -398,7 +406,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
/**
|
||||
* Sets the autofill field value.
|
||||
* whether object uses an automatic fill style
|
||||
*
|
||||
*
|
||||
* @param value {@code true} if object uses an automatic fill style
|
||||
*/
|
||||
public void setAutofill(boolean value)
|
||||
|
@ -418,7 +426,7 @@ public final class CommonObjectDataSubRecord extends SubRecord implements Clonea
|
|||
/**
|
||||
* Sets the autoline field value.
|
||||
* whether object uses an automatic line style
|
||||
*
|
||||
*
|
||||
* @param value {@code true} if object uses an automatic line style
|
||||
*/
|
||||
public void setAutoline(boolean value)
|
||||
|
|
|
@ -19,23 +19,26 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Continue Record(0x003C) - Helper class used primarily for SST Records <P>
|
||||
* Description: handles overflow for prior record in the input
|
||||
* stream; content is tailored to that prior record<P>
|
||||
* @author Marc Johnson (mjohnson at apache dot org)
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Csaba Nagy (ncsaba at yahoo dot com)
|
||||
* Helper class used primarily for SST Records<p>
|
||||
*
|
||||
* handles overflow for prior record in the input stream; content is tailored to that prior record
|
||||
*/
|
||||
public final class ContinueRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x003C;
|
||||
public final class ContinueRecord extends StandardRecord {
|
||||
public static final short sid = 0x003C;
|
||||
private byte[] _data;
|
||||
|
||||
public ContinueRecord(byte[] data) {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public ContinueRecord(ContinueRecord other) {
|
||||
super(other);
|
||||
_data = (other._data == null) ? null : other._data.clone();
|
||||
}
|
||||
|
||||
protected int getDataSize() {
|
||||
return _data.length;
|
||||
}
|
||||
|
@ -70,7 +73,15 @@ public final class ContinueRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public ContinueRecord clone() {
|
||||
return new ContinueRecord(_data);
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContinueRecord copy() {
|
||||
return new ContinueRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,37 +15,36 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: Country Record (aka WIN.INI country)<P>
|
||||
* Description: used for localization. Currently HSSF always sets this to 1
|
||||
* and it seems to work fine even in Germany. (es geht's auch fuer Deutschland)<P>
|
||||
* Country Record (aka WIN.INI country) - used for localization<p>
|
||||
*
|
||||
* Currently HSSF always sets this to 1 and it seems to work fine even in Germany.
|
||||
*
|
||||
* REFERENCE: PG 298 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class CountryRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0x8c;
|
||||
public final class CountryRecord extends StandardRecord {
|
||||
public static final short sid = 0x8c;
|
||||
|
||||
// 1 for US
|
||||
private short field_1_default_country;
|
||||
private short field_2_current_country;
|
||||
private short field_1_default_country;
|
||||
private short field_2_current_country;
|
||||
|
||||
public CountryRecord()
|
||||
{
|
||||
public CountryRecord() {}
|
||||
|
||||
public CountryRecord(CountryRecord other) {
|
||||
super(other);
|
||||
field_1_default_country = other.field_1_default_country;
|
||||
field_2_current_country = other.field_2_current_country;
|
||||
}
|
||||
|
||||
public CountryRecord(RecordInputStream in)
|
||||
{
|
||||
public CountryRecord(RecordInputStream in) {
|
||||
field_1_default_country = in.readShort();
|
||||
field_2_current_country = in.readShort();
|
||||
}
|
||||
|
@ -120,4 +119,9 @@ public final class CountryRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CountryRecord copy() {
|
||||
return new CountryRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,39 +19,15 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: DBCell Record (0x00D7)<p>
|
||||
* Description: Used by Excel and other MS apps to quickly find rows in the sheets.<P>
|
||||
* REFERENCE: PG 299/440 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Used by Excel and other MS apps to quickly find rows in the sheets.
|
||||
*/
|
||||
public final class DBCellRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x00D7;
|
||||
public final static int BLOCK_SIZE = 32;
|
||||
|
||||
public static final class Builder {
|
||||
private short[] _cellOffsets;
|
||||
private int _nCellOffsets;
|
||||
public Builder() {
|
||||
_cellOffsets = new short[4];
|
||||
}
|
||||
public final class DBCellRecord extends StandardRecord {
|
||||
public static final short sid = 0x00D7;
|
||||
public static final int BLOCK_SIZE = 32;
|
||||
|
||||
public void addCellOffset(int cellRefOffset) {
|
||||
if (_cellOffsets.length <= _nCellOffsets) {
|
||||
short[] temp = new short[_nCellOffsets * 2];
|
||||
System.arraycopy(_cellOffsets, 0, temp, 0, _nCellOffsets);
|
||||
_cellOffsets = temp;
|
||||
}
|
||||
_cellOffsets[_nCellOffsets] = (short) cellRefOffset;
|
||||
_nCellOffsets++;
|
||||
}
|
||||
|
||||
public DBCellRecord build(int rowOffset) {
|
||||
short[] cellOffsets = new short[_nCellOffsets];
|
||||
System.arraycopy(_cellOffsets, 0, cellOffsets, 0, _nCellOffsets);
|
||||
return new DBCellRecord(rowOffset, cellOffsets);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* offset from the start of this DBCellRecord to the start of the first cell in
|
||||
* the next DBCell block.
|
||||
|
@ -59,23 +35,21 @@ public final class DBCellRecord extends StandardRecord implements Cloneable {
|
|||
private final int field_1_row_offset;
|
||||
private final short[] field_2_cell_offsets;
|
||||
|
||||
DBCellRecord(int rowOffset, short[]cellOffsets) {
|
||||
public DBCellRecord(int rowOffset, short[] cellOffsets) {
|
||||
field_1_row_offset = rowOffset;
|
||||
field_2_cell_offsets = cellOffsets;
|
||||
}
|
||||
|
||||
public DBCellRecord(RecordInputStream in) {
|
||||
field_1_row_offset = in.readUShort();
|
||||
int size = in.remaining();
|
||||
int size = in.remaining();
|
||||
field_2_cell_offsets = new short[ size / 2 ];
|
||||
|
||||
for (int i=0;i<field_2_cell_offsets.length;i++)
|
||||
{
|
||||
for (int i=0;i<field_2_cell_offsets.length;i++) {
|
||||
field_2_cell_offsets[ i ] = in.readShort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
|
@ -91,8 +65,8 @@ public final class DBCellRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
out.writeInt(field_1_row_offset);
|
||||
for (int k = 0; k < field_2_cell_offsets.length; k++) {
|
||||
out.writeShort(field_2_cell_offsets[ k ]);
|
||||
for (short field_2_cell_offset : field_2_cell_offsets) {
|
||||
out.writeShort(field_2_cell_offset);
|
||||
}
|
||||
}
|
||||
protected int getDataSize() {
|
||||
|
@ -104,7 +78,15 @@ public final class DBCellRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DBCellRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBCellRecord copy() {
|
||||
// safe because immutable
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
@ -67,8 +67,7 @@ import org.apache.poi.util.StringUtil;
|
|||
*
|
||||
* At the moment this class is read-only.
|
||||
*/
|
||||
public class DConRefRecord extends StandardRecord
|
||||
{
|
||||
public class DConRefRecord extends StandardRecord {
|
||||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
@ -108,54 +107,25 @@ public class DConRefRecord extends StandardRecord
|
|||
*/
|
||||
private byte[] _unused;
|
||||
|
||||
public DConRefRecord(DConRefRecord other) {
|
||||
super(other);
|
||||
firstCol = other.firstCol;
|
||||
firstRow = other.firstRow;
|
||||
lastCol = other.lastCol;
|
||||
lastRow = other.lastRow;
|
||||
charCount = other.charCount;
|
||||
charType = other.charType;
|
||||
path = (other.path == null) ? null : other.path.clone();
|
||||
_unused = (other._unused == null) ? null : other._unused.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read constructor.
|
||||
*
|
||||
* @param data byte array containing a DConRef Record, including the header.
|
||||
*/
|
||||
public DConRefRecord(byte[] data)
|
||||
{
|
||||
int offset = 0;
|
||||
if (!(LittleEndian.getShort(data, offset) == DConRefRecord.sid))
|
||||
throw new RecordFormatException("incompatible sid.");
|
||||
offset += LittleEndian.SHORT_SIZE;
|
||||
|
||||
//length = LittleEndian.getShort(data, offset);
|
||||
offset += LittleEndian.SHORT_SIZE;
|
||||
|
||||
firstRow = LittleEndian.getUShort(data, offset);
|
||||
offset += LittleEndian.SHORT_SIZE;
|
||||
lastRow = LittleEndian.getUShort(data, offset);
|
||||
offset += LittleEndian.SHORT_SIZE;
|
||||
firstCol = LittleEndian.getUByte(data, offset);
|
||||
offset += LittleEndian.BYTE_SIZE;
|
||||
lastCol = LittleEndian.getUByte(data, offset);
|
||||
offset += LittleEndian.BYTE_SIZE;
|
||||
charCount = LittleEndian.getUShort(data, offset);
|
||||
offset += LittleEndian.SHORT_SIZE;
|
||||
if (charCount < 2)
|
||||
throw new RecordFormatException("Character count must be >= 2");
|
||||
|
||||
charType = LittleEndian.getUByte(data, offset);
|
||||
offset += LittleEndian.BYTE_SIZE; //7 bits reserved + 1 bit type
|
||||
|
||||
/*
|
||||
* bytelength is the length of the string in bytes, which depends on whether the string is
|
||||
* made of single- or double-byte chars. This is given by charType, which equals 0 if
|
||||
* single-byte, 1 if double-byte.
|
||||
*/
|
||||
int byteLength = charCount * ((charType & 1) + 1);
|
||||
|
||||
path = LittleEndian.getByteArray(data, offset, byteLength, MAX_RECORD_LENGTH);
|
||||
offset += byteLength;
|
||||
|
||||
/*
|
||||
* If it's a self reference, the last one or two bytes (depending on char type) are the
|
||||
* unused field. Not sure If i need to bother with this...
|
||||
*/
|
||||
if (path[0] == 0x02)
|
||||
_unused = LittleEndian.getByteArray(data, offset, (charType + 1), MAX_RECORD_LENGTH);
|
||||
|
||||
public DConRefRecord(byte[] data) {
|
||||
this(bytesToRIStream(data));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,10 +133,10 @@ public class DConRefRecord extends StandardRecord
|
|||
*
|
||||
* @param inStream RecordInputStream containing a DConRefRecord structure.
|
||||
*/
|
||||
public DConRefRecord(RecordInputStream inStream)
|
||||
{
|
||||
if (inStream.getSid() != sid)
|
||||
public DConRefRecord(RecordInputStream inStream) {
|
||||
if (inStream.getSid() != sid) {
|
||||
throw new RecordFormatException("Wrong sid: " + inStream.getSid());
|
||||
}
|
||||
|
||||
firstRow = inStream.readUShort();
|
||||
lastRow = inStream.readUShort();
|
||||
|
@ -174,17 +144,23 @@ public class DConRefRecord extends StandardRecord
|
|||
lastCol = inStream.readUByte();
|
||||
|
||||
charCount = inStream.readUShort();
|
||||
charType = inStream.readUByte() & 0x01; //first bit only.
|
||||
|
||||
// byteLength depends on whether we are using single- or double-byte chars.
|
||||
int byteLength = charCount * (charType + 1);
|
||||
// 7 bits reserved + 1 bit type - first bit only
|
||||
charType = inStream.readUByte() & 0x01;
|
||||
|
||||
// bytelength is the length of the string in bytes, which depends on whether the string is
|
||||
// made of single- or double-byte chars. This is given by charType, which equals 0 if
|
||||
// single-byte, 1 if double-byte.
|
||||
final int byteLength = charCount * (charType + 1);
|
||||
|
||||
path = IOUtils.safelyAllocate(byteLength, MAX_RECORD_LENGTH);
|
||||
inStream.readFully(path);
|
||||
|
||||
if (path[0] == 0x02)
|
||||
// If it's a self reference, the last one or two bytes (depending on char type) are the
|
||||
// unused field. Not sure If i need to bother with this...
|
||||
if (path[0] == 0x02) {
|
||||
_unused = inStream.readRemainder();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -291,8 +267,7 @@ public class DConRefRecord extends StandardRecord
|
|||
//all of the path strings start with either 0x02 or 0x01 followed by zero or
|
||||
//more of 0x01..0x08
|
||||
int offset = 1;
|
||||
while (path[offset] < 0x20 && offset < path.length)
|
||||
{
|
||||
while (offset < path.length && path[offset] < 0x20) {
|
||||
offset++;
|
||||
}
|
||||
String out = new String(Arrays.copyOfRange(path, offset, path.length), StringUtil.UTF8);
|
||||
|
@ -310,8 +285,17 @@ public class DConRefRecord extends StandardRecord
|
|||
*/
|
||||
public boolean isExternalRef()
|
||||
{
|
||||
if (path[0] == 0x01)
|
||||
return true;
|
||||
return false;
|
||||
return path[0] == 0x01;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DConRefRecord copy() {
|
||||
return new DConRefRecord(this);
|
||||
}
|
||||
|
||||
private static RecordInputStream bytesToRIStream(byte[] data) {
|
||||
RecordInputStream ric = new RecordInputStream(new ByteArrayInputStream(data));
|
||||
ric.nextRecord();
|
||||
return ric;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,21 +23,26 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* Title: Double Stream Flag Record (0x0161)<p>
|
||||
* Description: tells if this is a double stream file. (always no for HSSF generated files)<p>
|
||||
* Double Stream files contain both BIFF8 and BIFF7 workbooks.<p>
|
||||
* REFERENCE: PG 305 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Tells if this is a double stream file. (never applies to HSSF generated files)<p>
|
||||
*
|
||||
* Double Stream files contain both BIFF8 and BIFF7 workbooks.
|
||||
*/
|
||||
public final class DSFRecord extends StandardRecord {
|
||||
public final static short sid = 0x0161;
|
||||
public static final short sid = 0x0161;
|
||||
|
||||
private static final BitField biff5BookStreamFlag = BitFieldFactory.getInstance(0x0001);
|
||||
|
||||
private int _options;
|
||||
|
||||
private DSFRecord(DSFRecord other) {
|
||||
super(other);
|
||||
_options = other._options;
|
||||
}
|
||||
|
||||
private DSFRecord(int options) {
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public DSFRecord(boolean isBiff5BookStreamPresent) {
|
||||
this(0);
|
||||
_options = biff5BookStreamFlag.setBoolean(0, isBiff5BookStreamPresent);
|
||||
|
@ -71,4 +76,9 @@ public final class DSFRecord extends StandardRecord {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DSFRecord copy() {
|
||||
return new DSFRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,14 +18,13 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: DATAVALIDATIONS Record (0x01B2)<p>
|
||||
* Description: used in data validation ;
|
||||
* This record is the list header of all data validation records (0x01BE) in the current sheet.
|
||||
* This record is the list header of all data validation records (0x01BE) in the current sheet.
|
||||
*/
|
||||
public final class DVALRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x01B2;
|
||||
public final class DVALRecord extends StandardRecord {
|
||||
public static final short sid = 0x01B2;
|
||||
|
||||
/** Options of the DVAL */
|
||||
private short field_1_options;
|
||||
|
@ -47,12 +46,21 @@ public final class DVALRecord extends StandardRecord implements Cloneable {
|
|||
field_5_dv_no = 0x00000000;
|
||||
}
|
||||
|
||||
public DVALRecord(DVALRecord other) {
|
||||
super(other);
|
||||
field_1_options = other.field_1_options;
|
||||
field_2_horiz_pos = other.field_2_horiz_pos;
|
||||
field_3_vert_pos = other.field_3_vert_pos;
|
||||
field_cbo_id = other.field_cbo_id;
|
||||
field_5_dv_no = other.field_5_dv_no;
|
||||
}
|
||||
|
||||
public DVALRecord(RecordInputStream in) {
|
||||
field_1_options = in.readShort();
|
||||
field_2_horiz_pos = in.readInt();
|
||||
field_3_vert_pos = in.readInt();
|
||||
field_cbo_id = in.readInt();
|
||||
field_5_dv_no = in.readInt();
|
||||
field_cbo_id = in.readInt();
|
||||
field_5_dv_no = in.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,7 +150,6 @@ public final class DVALRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
|
||||
out.writeShort(getOptions());
|
||||
out.writeInt(getHorizontalPos());
|
||||
out.writeInt(getVerticalPos());
|
||||
|
@ -158,14 +165,16 @@ public final class DVALRecord extends StandardRecord implements Cloneable {
|
|||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DVALRecord clone() {
|
||||
DVALRecord rec = new DVALRecord();
|
||||
rec.field_1_options = field_1_options;
|
||||
rec.field_2_horiz_pos = field_2_horiz_pos;
|
||||
rec.field_3_vert_pos = field_3_vert_pos;
|
||||
rec.field_cbo_id = field_cbo_id;
|
||||
rec.field_5_dv_no = field_5_dv_no;
|
||||
return rec;
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DVALRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DVALRecord copy() {
|
||||
return new DVALRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,46 +25,23 @@ import org.apache.poi.ss.util.CellRangeAddress;
|
|||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: DATAVALIDATION Record (0x01BE)<p>
|
||||
* Description: This record stores data validation settings and a list of cell ranges
|
||||
* which contain these settings. The data validation settings of a sheet
|
||||
* are stored in a sequential list of DV records. This list is followed by
|
||||
* DVAL record(s)
|
||||
* This record stores data validation settings and a list of cell ranges which contain these settings.
|
||||
* The data validation settings of a sheet are stored in a sequential list of DV records.
|
||||
* This list is followed by DVAL record(s)
|
||||
*/
|
||||
public final class DVRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x01BE;
|
||||
|
||||
public final class DVRecord extends StandardRecord {
|
||||
public static final short sid = 0x01BE;
|
||||
|
||||
/** the unicode string used for error/prompt title/text when not present */
|
||||
private static final UnicodeString NULL_TEXT_STRING = new UnicodeString("\0");
|
||||
|
||||
/** Option flags */
|
||||
private int _option_flags;
|
||||
/** Title of the prompt box, cannot be longer than 32 chars */
|
||||
private UnicodeString _promptTitle;
|
||||
/** Title of the error box, cannot be longer than 32 chars */
|
||||
private UnicodeString _errorTitle;
|
||||
/** Text of the prompt box, cannot be longer than 255 chars */
|
||||
private UnicodeString _promptText;
|
||||
/** Text of the error box, cannot be longer than 255 chars */
|
||||
private UnicodeString _errorText;
|
||||
/** Not used - Excel seems to always write 0x3FE0 */
|
||||
private short _not_used_1 = 0x3FE0;
|
||||
/** Formula data for first condition (RPN token array without size field) */
|
||||
private Formula _formula1;
|
||||
/** Not used - Excel seems to always write 0x0000 */
|
||||
@SuppressWarnings("RedundantFieldInitialization")
|
||||
private short _not_used_2 = 0x0000;
|
||||
/** Formula data for second condition (RPN token array without size field) */
|
||||
private Formula _formula2;
|
||||
/** Cell range address list with all affected ranges */
|
||||
private CellRangeAddressList _regions;
|
||||
|
||||
/**
|
||||
* Option flags field
|
||||
*
|
||||
*
|
||||
* @see HSSFDataValidation utility class
|
||||
*/
|
||||
private static final BitField opt_data_type = new BitField(0x0000000F);
|
||||
|
@ -76,13 +53,49 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
private static final BitField opt_show_error_on_invalid_value = new BitField(0x00080000);
|
||||
private static final BitField opt_condition_operator = new BitField(0x00700000);
|
||||
|
||||
/** Option flags */
|
||||
private int _option_flags;
|
||||
/** Title of the prompt box, cannot be longer than 32 chars */
|
||||
private final UnicodeString _promptTitle;
|
||||
/** Title of the error box, cannot be longer than 32 chars */
|
||||
private final UnicodeString _errorTitle;
|
||||
/** Text of the prompt box, cannot be longer than 255 chars */
|
||||
private final UnicodeString _promptText;
|
||||
/** Text of the error box, cannot be longer than 255 chars */
|
||||
private final UnicodeString _errorText;
|
||||
/** Not used - Excel seems to always write 0x3FE0 */
|
||||
private short _not_used_1 = 0x3FE0;
|
||||
/** Formula data for first condition (RPN token array without size field) */
|
||||
private final Formula _formula1;
|
||||
/** Not used - Excel seems to always write 0x0000 */
|
||||
@SuppressWarnings("RedundantFieldInitialization")
|
||||
private short _not_used_2 = 0x0000;
|
||||
/** Formula data for second condition (RPN token array without size field) */
|
||||
private final Formula _formula2;
|
||||
/** Cell range address list with all affected ranges */
|
||||
private final CellRangeAddressList _regions;
|
||||
|
||||
public DVRecord(DVRecord other) {
|
||||
super(other);
|
||||
_option_flags = other._option_flags;
|
||||
_promptTitle = other._promptTitle.copy();
|
||||
_errorTitle = other._errorTitle.copy();
|
||||
_promptText = other._promptText.copy();
|
||||
_errorText = other._errorText.copy();
|
||||
_not_used_1 = other._not_used_1;
|
||||
_formula1 = (other._formula1 == null) ? null : other._formula1.copy();
|
||||
_not_used_2 = other._not_used_2;
|
||||
_formula2 = (other._formula2 == null) ? null : other._formula2.copy();
|
||||
_regions = (other._regions == null) ? null : other._regions.copy();
|
||||
}
|
||||
|
||||
public DVRecord(int validationType, int operator, int errorStyle, boolean emptyCellAllowed,
|
||||
boolean suppressDropDownArrow, boolean isExplicitList,
|
||||
boolean showPromptBox, String promptTitle, String promptText,
|
||||
boolean showPromptBox, String promptTitle, String promptText,
|
||||
boolean showErrorBox, String errorTitle, String errorText,
|
||||
Ptg[] formula1, Ptg[] formula2,
|
||||
CellRangeAddressList regions) {
|
||||
|
||||
|
||||
// check length-limits
|
||||
if(promptTitle != null && promptTitle.length() > 32) {
|
||||
throw new IllegalStateException("Prompt-title cannot be longer than 32 characters, but had: " + promptTitle);
|
||||
|
@ -118,7 +131,6 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
public DVRecord(RecordInputStream in) {
|
||||
|
||||
_option_flags = in.readInt();
|
||||
|
||||
_promptTitle = readUnicodeString(in);
|
||||
|
@ -144,7 +156,6 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
_regions = new CellRangeAddressList(in);
|
||||
}
|
||||
|
||||
// --> start option flags
|
||||
/**
|
||||
* @return the condition data type
|
||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType
|
||||
|
@ -276,7 +287,7 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
private static void appendFormula(StringBuilder sb, String label, Formula f) {
|
||||
sb.append(label);
|
||||
|
||||
|
||||
if (f == null) {
|
||||
sb.append("<empty>\n");
|
||||
return;
|
||||
|
@ -291,7 +302,7 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
public void serialize(LittleEndianOutput out) {
|
||||
|
||||
out.writeInt(_option_flags);
|
||||
|
||||
|
||||
serializeUnicodeString(_promptTitle, out);
|
||||
serializeUnicodeString(_errorTitle, out);
|
||||
serializeUnicodeString(_promptText, out);
|
||||
|
@ -299,19 +310,19 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
out.writeShort(_formula1.getEncodedTokenSize());
|
||||
out.writeShort(_not_used_1);
|
||||
_formula1.serializeTokens(out);
|
||||
|
||||
|
||||
out.writeShort(_formula2.getEncodedTokenSize());
|
||||
out.writeShort(_not_used_2);
|
||||
_formula2.serializeTokens(out);
|
||||
|
||||
|
||||
_regions.serialize(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* When entered via the UI, Excel translates empty string into "\0"
|
||||
* While it is possible to encode the title/text as empty string (Excel doesn't exactly crash),
|
||||
* the resulting tool-tip text / message box looks wrong. It is best to do the same as the
|
||||
* Excel UI and encode 'not present' as "\0".
|
||||
* the resulting tool-tip text / message box looks wrong. It is best to do the same as the
|
||||
* Excel UI and encode 'not present' as "\0".
|
||||
*/
|
||||
private static UnicodeString resolveTitleText(String str) {
|
||||
if (str == null || str.length() < 1) {
|
||||
|
@ -354,13 +365,18 @@ public final class DVRecord extends StandardRecord implements Cloneable {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the object. Uses serialisation, as the
|
||||
* contents are somewhat complex
|
||||
*/
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DVRecord clone() {
|
||||
return (DVRecord)cloneViaReserialise();
|
||||
return copy();
|
||||
}
|
||||
|
||||
/** Clones the object. */
|
||||
@Override
|
||||
public DVRecord copy() {
|
||||
return new DVRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,33 +15,31 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: Date Window 1904 Flag record <P>
|
||||
* Description: Flag specifying whether 1904 date windowing is used.
|
||||
* (tick toc tick toc...BOOM!) <P>
|
||||
* REFERENCE: PG 280 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* Flag specifying whether 1904 date windowing is used.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class DateWindow1904Record
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0x22;
|
||||
private short field_1_window;
|
||||
public final class DateWindow1904Record extends StandardRecord {
|
||||
public static final short sid = 0x22;
|
||||
|
||||
public DateWindow1904Record()
|
||||
{
|
||||
private short field_1_window;
|
||||
|
||||
public DateWindow1904Record() {}
|
||||
|
||||
public DateWindow1904Record(DateWindow1904Record other) {
|
||||
super(other);
|
||||
field_1_window = other.field_1_window;
|
||||
}
|
||||
|
||||
public DateWindow1904Record(RecordInputStream in)
|
||||
{
|
||||
public DateWindow1904Record(RecordInputStream in) {
|
||||
field_1_window = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -88,4 +86,9 @@ public final class DateWindow1904Record
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateWindow1904Record copy() {
|
||||
return new DateWindow1904Record(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,30 +18,32 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Default Column Width Record (0x0055) <P>
|
||||
* Description: Specifies the default width for columns that have no specific
|
||||
* width set.<P>
|
||||
* REFERENCE: PG 302 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Specifies the default width for columns that have no specific width set.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
public final class DefaultColWidthRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x0055;
|
||||
private int field_1_col_width;
|
||||
public final class DefaultColWidthRecord extends StandardRecord {
|
||||
public static final short sid = 0x0055;
|
||||
|
||||
/**
|
||||
* The default column width is 8 characters
|
||||
*/
|
||||
public final static int DEFAULT_COLUMN_WIDTH = 0x0008;
|
||||
public static final int DEFAULT_COLUMN_WIDTH = 0x0008;
|
||||
|
||||
public DefaultColWidthRecord()
|
||||
{
|
||||
private int field_1_col_width;
|
||||
|
||||
public DefaultColWidthRecord() {
|
||||
field_1_col_width = DEFAULT_COLUMN_WIDTH;
|
||||
}
|
||||
|
||||
public DefaultColWidthRecord(DefaultColWidthRecord other) {
|
||||
super(other);
|
||||
field_1_col_width = other.field_1_col_width;
|
||||
}
|
||||
|
||||
public DefaultColWidthRecord(RecordInputStream in)
|
||||
{
|
||||
field_1_col_width = in.readUShort();
|
||||
|
@ -92,9 +94,15 @@ public final class DefaultColWidthRecord extends StandardRecord implements Clone
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DefaultColWidthRecord clone() {
|
||||
DefaultColWidthRecord rec = new DefaultColWidthRecord();
|
||||
rec.field_1_col_width = field_1_col_width;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultColWidthRecord copy() {
|
||||
return new DefaultColWidthRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
|
@ -20,35 +19,35 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Default Row Height Record
|
||||
* Description: Row height for rows with undefined or not explicitly defined
|
||||
* heights.
|
||||
* REFERENCE: PG 301 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Row height for rows with undefined or not explicitly defined heights.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class DefaultRowHeightRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x225;
|
||||
private short field_1_option_flags;
|
||||
private short field_2_row_height;
|
||||
public final class DefaultRowHeightRecord extends StandardRecord {
|
||||
public static final short sid = 0x225;
|
||||
|
||||
/**
|
||||
* The default row height for empty rows is 255 twips (255 / 20 == 12.75 points)
|
||||
*/
|
||||
/** The default row height for empty rows is 255 twips (255 / 20 == 12.75 points) */
|
||||
public static final short DEFAULT_ROW_HEIGHT = 0xFF;
|
||||
|
||||
public DefaultRowHeightRecord()
|
||||
{
|
||||
private short field_1_option_flags;
|
||||
private short field_2_row_height;
|
||||
|
||||
public DefaultRowHeightRecord() {
|
||||
field_1_option_flags = 0x0000;
|
||||
field_2_row_height = DEFAULT_ROW_HEIGHT;
|
||||
}
|
||||
|
||||
public DefaultRowHeightRecord(RecordInputStream in)
|
||||
{
|
||||
public DefaultRowHeightRecord(DefaultRowHeightRecord other) {
|
||||
super(other);
|
||||
field_1_option_flags = other.field_1_option_flags;
|
||||
field_2_row_height = other.field_2_row_height;
|
||||
}
|
||||
|
||||
public DefaultRowHeightRecord(RecordInputStream in) {
|
||||
field_1_option_flags = in.readShort();
|
||||
field_2_row_height = in.readShort();
|
||||
}
|
||||
|
@ -121,10 +120,15 @@ public final class DefaultRowHeightRecord extends StandardRecord implements Clon
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DefaultRowHeightRecord clone() {
|
||||
DefaultRowHeightRecord rec = new DefaultRowHeightRecord();
|
||||
rec.field_1_option_flags = field_1_option_flags;
|
||||
rec.field_2_row_height = field_2_row_height;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultRowHeightRecord copy() {
|
||||
return new DefaultRowHeightRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,12 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Delta Record (0x0010)<p>
|
||||
* Description: controls the accuracy of the calculations<p>
|
||||
* REFERENCE: PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
*/
|
||||
public final class DeltaRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x0010;
|
||||
public final static double DEFAULT_VALUE = 0.0010; // should be .001
|
||||
/** Controls the accuracy of the calculations */
|
||||
public final class DeltaRecord extends StandardRecord {
|
||||
public static final short sid = 0x0010;
|
||||
public static final double DEFAULT_VALUE = 0.0010;
|
||||
|
||||
// a double is an IEEE 8-byte float...damn IEEE and their goofy standards an
|
||||
// ambiguous numeric identifiers
|
||||
|
@ -36,6 +33,11 @@ public final class DeltaRecord extends StandardRecord implements Cloneable {
|
|||
field_1_max_change = maxChange;
|
||||
}
|
||||
|
||||
public DeltaRecord(DeltaRecord other) {
|
||||
super(other);
|
||||
field_1_max_change = other.field_1_max_change;
|
||||
}
|
||||
|
||||
public DeltaRecord(RecordInputStream in) {
|
||||
field_1_max_change = in.readDouble();
|
||||
}
|
||||
|
@ -70,7 +72,15 @@ public final class DeltaRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DeltaRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeltaRecord copy() {
|
||||
// immutable
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -15,41 +15,44 @@
|
|||
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.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Dimensions Record<P>
|
||||
* Description: provides the minumum and maximum bounds
|
||||
* of a sheet.<P>
|
||||
* REFERENCE: PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Provides the minumum and maximum bounds of a sheet.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class DimensionsRecord extends StandardRecord implements Cloneable {
|
||||
public final class DimensionsRecord extends StandardRecord {
|
||||
|
||||
private static final POILogger logger = POILogFactory.getLogger(DimensionsRecord.class);
|
||||
|
||||
public final static short sid = 0x200;
|
||||
public static final short sid = 0x200;
|
||||
private int field_1_first_row;
|
||||
private int field_2_last_row; // plus 1
|
||||
private short field_3_first_col;
|
||||
private short field_4_last_col;
|
||||
private short field_5_zero; // must be 0 (reserved)
|
||||
|
||||
public DimensionsRecord()
|
||||
{
|
||||
public DimensionsRecord() {}
|
||||
|
||||
public DimensionsRecord(DimensionsRecord other) {
|
||||
super(other);
|
||||
field_1_first_row = other.field_1_first_row;
|
||||
field_2_last_row = other.field_2_last_row;
|
||||
field_3_first_col = other.field_3_first_col;
|
||||
field_4_last_col = other.field_4_last_col;
|
||||
field_5_zero = other.field_5_zero;
|
||||
}
|
||||
|
||||
public DimensionsRecord(RecordInputStream in)
|
||||
{
|
||||
public DimensionsRecord(RecordInputStream in) {
|
||||
field_1_first_row = in.readInt();
|
||||
field_2_last_row = in.readInt();
|
||||
field_3_first_col = in.readShort();
|
||||
|
@ -179,13 +182,15 @@ public final class DimensionsRecord extends StandardRecord implements Cloneable
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DimensionsRecord clone() {
|
||||
DimensionsRecord rec = new DimensionsRecord();
|
||||
rec.field_1_first_row = field_1_first_row;
|
||||
rec.field_2_last_row = field_2_last_row;
|
||||
rec.field_3_first_col = field_3_first_col;
|
||||
rec.field_4_last_col = field_4_last_col;
|
||||
rec.field_5_zero = field_5_zero;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionsRecord copy() {
|
||||
return new DimensionsRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ddf.NullEscherSerializationListener;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public final class DrawingGroupRecord extends AbstractEscherHolderRecord {
|
||||
public static final short sid = 0xEB;
|
||||
|
@ -31,12 +31,13 @@ public final class DrawingGroupRecord extends AbstractEscherHolderRecord {
|
|||
static final int MAX_RECORD_SIZE = 8228;
|
||||
private static final int MAX_DATA_SIZE = MAX_RECORD_SIZE - 4;
|
||||
|
||||
public DrawingGroupRecord()
|
||||
{
|
||||
public DrawingGroupRecord() {}
|
||||
|
||||
public DrawingGroupRecord(DrawingGroupRecord other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public DrawingGroupRecord( RecordInputStream in )
|
||||
{
|
||||
public DrawingGroupRecord( RecordInputStream in ) {
|
||||
super( in );
|
||||
}
|
||||
|
||||
|
@ -136,4 +137,9 @@ public final class DrawingGroupRecord extends AbstractEscherHolderRecord {
|
|||
LittleEndian.putShort(data, 0 + offset, ContinueRecord.sid);
|
||||
LittleEndian.putShort(data, 2 + offset, (short) sizeExcludingHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DrawingGroupRecord copy() {
|
||||
return new DrawingGroupRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,9 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
/**
|
||||
* DrawingRecord (0x00EC)
|
||||
*/
|
||||
public final class DrawingRecord extends StandardRecord implements Cloneable {
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
public final class DrawingRecord extends StandardRecord {
|
||||
public static final short sid = 0x00EC;
|
||||
|
||||
private static final byte[] EMPTY_BYTE_ARRAY = {};
|
||||
|
@ -33,6 +32,13 @@ public final class DrawingRecord extends StandardRecord implements Cloneable {
|
|||
recordData = EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
public DrawingRecord(DrawingRecord other) {
|
||||
super(other);
|
||||
recordData = (other.recordData == null) ? null : other.recordData.clone();
|
||||
// TODO - this code probably never copies a contd array ...
|
||||
contd = (other.contd == null) ? null : other.contd.clone();
|
||||
}
|
||||
|
||||
public DrawingRecord(RecordInputStream in) {
|
||||
recordData = in.readRemainder();
|
||||
}
|
||||
|
@ -69,20 +75,21 @@ public final class DrawingRecord extends StandardRecord implements Cloneable {
|
|||
recordData = thedata;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DrawingRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cloning of drawing records must be executed through HSSFPatriarch, because all id's must be changed
|
||||
* @return cloned drawing records
|
||||
*/
|
||||
@Override
|
||||
public DrawingRecord clone() {
|
||||
DrawingRecord rec = new DrawingRecord();
|
||||
rec.recordData = recordData.clone();
|
||||
if (contd != null) {
|
||||
// TODO - this code probably never executes
|
||||
rec.contd = contd.clone();
|
||||
}
|
||||
|
||||
return rec;
|
||||
public DrawingRecord copy() {
|
||||
return new DrawingRecord(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,8 +26,10 @@ import java.io.ByteArrayInputStream;
|
|||
public final class DrawingRecordForBiffViewer extends AbstractEscherHolderRecord {
|
||||
public static final short sid = 0xEC;
|
||||
|
||||
public DrawingRecordForBiffViewer()
|
||||
{
|
||||
public DrawingRecordForBiffViewer() {}
|
||||
|
||||
public DrawingRecordForBiffViewer(DrawingRecordForBiffViewer other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public DrawingRecordForBiffViewer( RecordInputStream in)
|
||||
|
@ -59,4 +61,9 @@ public final class DrawingRecordForBiffViewer extends AbstractEscherHolderRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DrawingRecordForBiffViewer copy() {
|
||||
return new DrawingRecordForBiffViewer(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,14 @@ package org.apache.poi.hssf.record;
|
|||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* MsoDrawingSelection (0x00ED)<p>
|
||||
* Reference:
|
||||
* [MS-OGRAPH].pdf sec 2.4.69
|
||||
*/
|
||||
public final class DrawingSelectionRecord extends StandardRecord implements Cloneable {
|
||||
public final class DrawingSelectionRecord extends StandardRecord {
|
||||
public static final short sid = 0x00ED;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +45,12 @@ public final class DrawingSelectionRecord extends StandardRecord implements Clon
|
|||
private final int _type;
|
||||
private final int _length;
|
||||
|
||||
public OfficeArtRecordHeader(OfficeArtRecordHeader other) {
|
||||
_verAndInstance = other._verAndInstance;
|
||||
_type = other._type;
|
||||
_length = other._length;
|
||||
}
|
||||
|
||||
public OfficeArtRecordHeader(LittleEndianInput in) {
|
||||
_verAndInstance = in.readUShort();
|
||||
_type = in.readUShort();
|
||||
|
@ -57,11 +64,10 @@ public final class DrawingSelectionRecord extends StandardRecord implements Clon
|
|||
}
|
||||
|
||||
public String debugFormatAsString() {
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
sb.append("ver+inst=").append(HexDump.shortToHex(_verAndInstance));
|
||||
sb.append(" type=").append(HexDump.shortToHex(_type));
|
||||
sb.append(" len=").append(HexDump.intToHex(_length));
|
||||
return sb.toString();
|
||||
return
|
||||
"ver+inst=" + HexDump.shortToHex(_verAndInstance) +
|
||||
" type=" + HexDump.shortToHex(_type) +
|
||||
" len=" + HexDump.intToHex(_length);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +99,7 @@ public final class DrawingSelectionRecord extends StandardRecord implements Clon
|
|||
}
|
||||
|
||||
protected int getDataSize() {
|
||||
return OfficeArtRecordHeader.ENCODED_SIZE
|
||||
return OfficeArtRecordHeader.ENCODED_SIZE
|
||||
+ 12 // 3 int fields
|
||||
+ _shapeIds.length * 4;
|
||||
}
|
||||
|
@ -109,7 +115,15 @@ public final class DrawingSelectionRecord extends StandardRecord implements Clon
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public DrawingSelectionRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DrawingSelectionRecord copy() {
|
||||
// currently immutable
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -18,33 +18,25 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* End Of File record.
|
||||
* <P>
|
||||
* Description: Marks the end of records belonging to a particular object in the
|
||||
* HSSF File<P>
|
||||
* REFERENCE: PG 307 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Marks the end of records belonging to a particular object in the HSSF File
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
public final class EOFRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x0A;
|
||||
public final class EOFRecord extends StandardRecord {
|
||||
public static final short sid = 0x0A;
|
||||
public static final int ENCODED_SIZE = 4;
|
||||
|
||||
public static final EOFRecord instance = new EOFRecord();
|
||||
|
||||
private EOFRecord() {
|
||||
// no data fields
|
||||
}
|
||||
|
||||
private EOFRecord() {}
|
||||
|
||||
/**
|
||||
* @param in unused (since this record has no data)
|
||||
*/
|
||||
public EOFRecord(RecordInputStream in)
|
||||
{
|
||||
}
|
||||
public EOFRecord(RecordInputStream in) {}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
|
@ -68,7 +60,15 @@ public final class EOFRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public EOFRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EOFRecord copy() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
@ -40,7 +41,7 @@ import org.apache.poi.util.StringUtil;
|
|||
* A sub-record within the OBJ record which stores a reference to an object
|
||||
* stored in a separate entry within the OLE2 compound file.
|
||||
*/
|
||||
public final class EmbeddedObjectRefSubRecord extends SubRecord implements Cloneable {
|
||||
public final class EmbeddedObjectRefSubRecord extends SubRecord {
|
||||
private static POILogger logger = POILogFactory.getLogger(EmbeddedObjectRefSubRecord.class);
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
@ -73,8 +74,16 @@ public final class EmbeddedObjectRefSubRecord extends SubRecord implements Clone
|
|||
field_4_ole_classname = null;
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
public EmbeddedObjectRefSubRecord(EmbeddedObjectRefSubRecord other) {
|
||||
super(other);
|
||||
field_1_unknown_int = other.field_1_unknown_int;
|
||||
field_2_refPtg = (other.field_2_refPtg == null) ? null : other.field_2_refPtg.copy();
|
||||
field_2_unknownFormulaData = (other.field_2_unknownFormulaData == null) ? null : other.field_2_unknownFormulaData.clone();
|
||||
field_3_unicode_flag = other.field_3_unicode_flag;
|
||||
field_4_ole_classname = other.field_4_ole_classname;
|
||||
field_4_unknownByte = other.field_4_unknownByte;
|
||||
field_5_stream_id = other.field_5_stream_id;
|
||||
field_6_unknown = (other.field_6_unknown == null) ? null : other.field_6_unknown.clone();
|
||||
}
|
||||
|
||||
public EmbeddedObjectRefSubRecord(LittleEndianInput in, int size) {
|
||||
|
@ -158,6 +167,10 @@ public final class EmbeddedObjectRefSubRecord extends SubRecord implements Clone
|
|||
field_6_unknown = readRawData(in, remaining);
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
private static Ptg readRefPtg(byte[] formulaRawBytes) {
|
||||
LittleEndianInput in = new LittleEndianInputStream(new ByteArrayInputStream(formulaRawBytes));
|
||||
byte ptgSid = in.readByte();
|
||||
|
@ -310,8 +323,16 @@ public final class EmbeddedObjectRefSubRecord extends SubRecord implements Clone
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public EmbeddedObjectRefSubRecord clone() {
|
||||
return this; // TODO proper clone
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddedObjectRefSubRecord copy() {
|
||||
return new EmbeddedObjectRefSubRecord(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -339,15 +360,15 @@ public final class EmbeddedObjectRefSubRecord extends SubRecord implements Clone
|
|||
sb.append("[/ftPictFmla]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public void setUnknownFormulaData(byte[] formularData) {
|
||||
field_2_unknownFormulaData = formularData;
|
||||
}
|
||||
|
||||
|
||||
public void setOleClassname(String oleClassname) {
|
||||
field_4_ole_classname = oleClassname;
|
||||
}
|
||||
|
||||
|
||||
public void setStorageId(int storageId) {
|
||||
field_5_stream_id = storageId;
|
||||
}
|
||||
|
|
|
@ -14,27 +14,25 @@
|
|||
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.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* ftEnd (0x0000)<p>
|
||||
*
|
||||
*
|
||||
* The end data record is used to denote the end of the subrecords.
|
||||
*/
|
||||
public final class EndSubRecord extends SubRecord implements Cloneable {
|
||||
public final class EndSubRecord extends SubRecord {
|
||||
// Note - zero sid is somewhat unusual (compared to plain Records)
|
||||
public final static short sid = 0x0000;
|
||||
public static final short sid = 0x0000;
|
||||
private static final int ENCODED_SIZE = 0;
|
||||
|
||||
public EndSubRecord()
|
||||
{
|
||||
|
||||
}
|
||||
public EndSubRecord() {}
|
||||
|
||||
/**
|
||||
* @param in unused (since this record has no data)
|
||||
|
@ -76,8 +74,15 @@ public final class EndSubRecord extends SubRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public EndSubRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EndSubRecord copy() {
|
||||
return new EndSubRecord();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ import org.apache.poi.util.RecordFormatException;
|
|||
|
||||
public final class EscherAggregate extends AbstractEscherHolderRecord {
|
||||
public static final short sid = 9876; // not a real sid - dummy value
|
||||
private static POILogger log = POILogFactory.getLogger(EscherAggregate.class);
|
||||
private static final POILogger log = POILogFactory.getLogger(EscherAggregate.class);
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000_000;
|
||||
|
||||
|
@ -317,6 +317,13 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
|||
}
|
||||
}
|
||||
|
||||
public EscherAggregate(EscherAggregate other) {
|
||||
super(other);
|
||||
// shallow copy, because the aggregates doesn't own the records
|
||||
shapeToObj.putAll(other.shapeToObj);
|
||||
tailRec.putAll(other.tailRec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the current sid.
|
||||
*/
|
||||
|
@ -814,4 +821,9 @@ public final class EscherAggregate extends AbstractEscherHolderRecord {
|
|||
public void removeTailRecord(NoteRecord note) {
|
||||
tailRec.remove(note.getShapeId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EscherAggregate copy() {
|
||||
return new EscherAggregate(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,28 +17,27 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.poi.hssf.record.cont.ContinuableRecord;
|
||||
import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Title: Extended Static String Table (0x00FF)<p>
|
||||
* Description: This record is used for a quick lookup into the SST record. This
|
||||
* record breaks the SST table into a set of buckets. The offsets
|
||||
* to these buckets within the SST record are kept as well as the
|
||||
* position relative to the start of the SST record.<p>
|
||||
* REFERENCE: PG 313 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Extended Static String Table (0x00FF)<p>
|
||||
* This record is used for a quick lookup into the SST record. This record breaks the SST table
|
||||
* into a set of buckets. The offsets to these buckets within the SST record are kept as well as
|
||||
* the position relative to the start of the SST record.
|
||||
*/
|
||||
public final class ExtSSTRecord extends ContinuableRecord {
|
||||
public final static short sid = 0x00FF;
|
||||
public static final short sid = 0x00FF;
|
||||
public static final int DEFAULT_BUCKET_SIZE = 8;
|
||||
//Can't seem to find this documented but from the biffviewer it is clear that
|
||||
//Excel only records the indexes for the first 128 buckets.
|
||||
public static final int MAX_BUCKETS = 128;
|
||||
|
||||
|
||||
|
||||
|
||||
public static final class InfoSubRecord {
|
||||
public static final int ENCODED_SIZE = 8;
|
||||
private int field_1_stream_pos; // stream pointer to the SST record
|
||||
|
@ -48,7 +47,7 @@ public final class ExtSSTRecord extends ContinuableRecord {
|
|||
|
||||
/**
|
||||
* Creates new ExtSSTInfoSubRecord
|
||||
*
|
||||
*
|
||||
* @param streamPos stream pointer to the SST record
|
||||
* @param bucketSstOffset ... don't really understand this yet
|
||||
*/
|
||||
|
@ -57,6 +56,12 @@ public final class ExtSSTRecord extends ContinuableRecord {
|
|||
field_2_bucket_sst_offset = bucketSstOffset;
|
||||
}
|
||||
|
||||
public InfoSubRecord(InfoSubRecord other) {
|
||||
field_1_stream_pos = other.field_1_stream_pos;
|
||||
field_2_bucket_sst_offset = other.field_2_bucket_sst_offset;
|
||||
field_3_zero = other.field_3_zero;
|
||||
}
|
||||
|
||||
public InfoSubRecord(RecordInputStream in)
|
||||
{
|
||||
field_1_stream_pos = in.readInt();
|
||||
|
@ -78,8 +83,8 @@ public final class ExtSSTRecord extends ContinuableRecord {
|
|||
out.writeShort(field_3_zero);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private short _stringsPerBucket;
|
||||
private InfoSubRecord[] _sstInfos;
|
||||
|
||||
|
@ -89,6 +94,12 @@ public final class ExtSSTRecord extends ContinuableRecord {
|
|||
_sstInfos = new InfoSubRecord[0];
|
||||
}
|
||||
|
||||
public ExtSSTRecord(ExtSSTRecord other) {
|
||||
_stringsPerBucket = other._stringsPerBucket;
|
||||
_sstInfos = (other._sstInfos == null) ? null
|
||||
: Stream.of(other._sstInfos).map(InfoSubRecord::new).toArray(InfoSubRecord[]::new);
|
||||
}
|
||||
|
||||
public ExtSSTRecord(RecordInputStream in) {
|
||||
_stringsPerBucket = in.readShort();
|
||||
|
||||
|
@ -161,9 +172,9 @@ public final class ExtSSTRecord extends ContinuableRecord {
|
|||
|
||||
/**
|
||||
* Given a number of strings (in the sst), returns the size of the extsst record
|
||||
*
|
||||
*
|
||||
* @param numStrings the number of strings
|
||||
*
|
||||
*
|
||||
* @return the size of the extsst record
|
||||
*/
|
||||
public static int getRecordSizeForStrings(int numStrings) {
|
||||
|
@ -181,4 +192,9 @@ public final class ExtSSTRecord extends ContinuableRecord {
|
|||
_sstInfos[i] = new InfoSubRecord(bucketAbsoluteOffsets[i], bucketRelativeOffsets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtSSTRecord copy() {
|
||||
return new ExtSSTRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
|
@ -23,179 +23,164 @@ import org.apache.poi.util.BitFieldFactory;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* Title: Extended Format Record
|
||||
* Description: Probably one of the more complex records. There are two breeds:
|
||||
* Style and Cell.
|
||||
*<P>
|
||||
* It should be noted that fields in the extended format record are
|
||||
* somewhat arbitrary. Almost all of the fields are bit-level, but
|
||||
* we name them as best as possible by functional group. In some
|
||||
* places this is better than others.
|
||||
*<P>
|
||||
* Probably one of the more complex records.<p>
|
||||
* There are two breeds: Style and Cell.<p>
|
||||
* It should be noted that fields in the extended format record are somewhat arbitrary.
|
||||
* Almost all of the fields are bit-level, but we name them as best as possible by functional group.
|
||||
* In some places this is better than others.
|
||||
*
|
||||
* REFERENCE: PG 426 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
|
||||
* @since 2.0-pre
|
||||
*/
|
||||
|
||||
public final class ExtendedFormatRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public static final short sid = 0xE0;
|
||||
public final class ExtendedFormatRecord extends StandardRecord {
|
||||
public static final short sid = 0xE0;
|
||||
|
||||
// null constant
|
||||
public static final short NULL = (short)0xfff0;
|
||||
public static final short NULL = (short)0xfff0;
|
||||
|
||||
// xf type
|
||||
public static final short XF_STYLE = 1;
|
||||
public static final short XF_CELL = 0;
|
||||
public static final short XF_STYLE = 1;
|
||||
public static final short XF_CELL = 0;
|
||||
|
||||
// borders
|
||||
public static final short NONE = 0x0;
|
||||
public static final short THIN = 0x1;
|
||||
public static final short MEDIUM = 0x2;
|
||||
public static final short DASHED = 0x3;
|
||||
public static final short DOTTED = 0x4;
|
||||
public static final short THICK = 0x5;
|
||||
public static final short DOUBLE = 0x6;
|
||||
public static final short HAIR = 0x7;
|
||||
public static final short MEDIUM_DASHED = 0x8;
|
||||
public static final short DASH_DOT = 0x9;
|
||||
public static final short MEDIUM_DASH_DOT = 0xA;
|
||||
public static final short DASH_DOT_DOT = 0xB;
|
||||
public static final short MEDIUM_DASH_DOT_DOT = 0xC;
|
||||
public static final short SLANTED_DASH_DOT = 0xD;
|
||||
public static final short NONE = 0x0;
|
||||
public static final short THIN = 0x1;
|
||||
public static final short MEDIUM = 0x2;
|
||||
public static final short DASHED = 0x3;
|
||||
public static final short DOTTED = 0x4;
|
||||
public static final short THICK = 0x5;
|
||||
public static final short DOUBLE = 0x6;
|
||||
public static final short HAIR = 0x7;
|
||||
public static final short MEDIUM_DASHED = 0x8;
|
||||
public static final short DASH_DOT = 0x9;
|
||||
public static final short MEDIUM_DASH_DOT = 0xA;
|
||||
public static final short DASH_DOT_DOT = 0xB;
|
||||
public static final short MEDIUM_DASH_DOT_DOT = 0xC;
|
||||
public static final short SLANTED_DASH_DOT = 0xD;
|
||||
|
||||
// alignment
|
||||
public static final short GENERAL = 0x0;
|
||||
public static final short LEFT = 0x1;
|
||||
public static final short CENTER = 0x2;
|
||||
public static final short RIGHT = 0x3;
|
||||
public static final short FILL = 0x4;
|
||||
public static final short JUSTIFY = 0x5;
|
||||
public static final short CENTER_SELECTION = 0x6;
|
||||
public static final short GENERAL = 0x0;
|
||||
public static final short LEFT = 0x1;
|
||||
public static final short CENTER = 0x2;
|
||||
public static final short RIGHT = 0x3;
|
||||
public static final short FILL = 0x4;
|
||||
public static final short JUSTIFY = 0x5;
|
||||
public static final short CENTER_SELECTION = 0x6;
|
||||
|
||||
// vertical alignment
|
||||
public static final short VERTICAL_TOP = 0x0;
|
||||
public static final short VERTICAL_CENTER = 0x1;
|
||||
public static final short VERTICAL_BOTTOM = 0x2;
|
||||
public static final short VERTICAL_JUSTIFY = 0x3;
|
||||
public static final short VERTICAL_TOP = 0x0;
|
||||
public static final short VERTICAL_CENTER = 0x1;
|
||||
public static final short VERTICAL_BOTTOM = 0x2;
|
||||
public static final short VERTICAL_JUSTIFY = 0x3;
|
||||
|
||||
// fill
|
||||
public static final short NO_FILL = 0 ;
|
||||
public static final short SOLID_FILL = 1 ;
|
||||
public static final short FINE_DOTS = 2 ;
|
||||
public static final short ALT_BARS = 3 ;
|
||||
public static final short SPARSE_DOTS = 4 ;
|
||||
public static final short THICK_HORZ_BANDS = 5 ;
|
||||
public static final short THICK_VERT_BANDS = 6 ;
|
||||
public static final short THICK_BACKWARD_DIAG = 7 ;
|
||||
public static final short THICK_FORWARD_DIAG = 8 ;
|
||||
public static final short BIG_SPOTS = 9 ;
|
||||
public static final short BRICKS = 10 ;
|
||||
public static final short THIN_HORZ_BANDS = 11 ;
|
||||
public static final short THIN_VERT_BANDS = 12 ;
|
||||
public static final short THIN_BACKWARD_DIAG = 13 ;
|
||||
public static final short THIN_FORWARD_DIAG = 14 ;
|
||||
public static final short SQUARES = 15 ;
|
||||
public static final short DIAMONDS = 16 ;
|
||||
|
||||
// fields in BOTH style and Cell XF records
|
||||
private short field_1_font_index; // not bit-mapped
|
||||
private short field_2_format_index; // not bit-mapped
|
||||
public static final short NO_FILL = 0;
|
||||
public static final short SOLID_FILL = 1;
|
||||
public static final short FINE_DOTS = 2;
|
||||
public static final short ALT_BARS = 3;
|
||||
public static final short SPARSE_DOTS = 4;
|
||||
public static final short THICK_HORZ_BANDS = 5;
|
||||
public static final short THICK_VERT_BANDS = 6;
|
||||
public static final short THICK_BACKWARD_DIAG = 7;
|
||||
public static final short THICK_FORWARD_DIAG = 8;
|
||||
public static final short BIG_SPOTS = 9;
|
||||
public static final short BRICKS = 10;
|
||||
public static final short THIN_HORZ_BANDS = 11;
|
||||
public static final short THIN_VERT_BANDS = 12;
|
||||
public static final short THIN_BACKWARD_DIAG = 13;
|
||||
public static final short THIN_FORWARD_DIAG = 14;
|
||||
public static final short SQUARES = 15;
|
||||
public static final short DIAMONDS = 16;
|
||||
|
||||
// field_3_cell_options bit map
|
||||
private static final BitField _locked = BitFieldFactory.getInstance(0x0001);
|
||||
private static final BitField _hidden = BitFieldFactory.getInstance(0x0002);
|
||||
private static final BitField _xf_type = BitFieldFactory.getInstance(0x0004);
|
||||
private static final BitField _123_prefix = BitFieldFactory.getInstance(0x0008);
|
||||
private static final BitField _parent_index = BitFieldFactory.getInstance(0xFFF0);
|
||||
private short field_3_cell_options;
|
||||
private static final BitField _locked = bf(0x0001);
|
||||
private static final BitField _hidden = bf(0x0002);
|
||||
private static final BitField _xf_type = bf(0x0004);
|
||||
private static final BitField _123_prefix = bf(0x0008);
|
||||
private static final BitField _parent_index = bf(0xFFF0);
|
||||
|
||||
// field_4_alignment_options bit map
|
||||
private static final BitField _alignment = BitFieldFactory.getInstance(0x0007);
|
||||
private static final BitField _wrap_text = BitFieldFactory.getInstance(0x0008);
|
||||
private static final BitField _vertical_alignment = BitFieldFactory.getInstance(0x0070);
|
||||
private static final BitField _justify_last = BitFieldFactory.getInstance(0x0080);
|
||||
private static final BitField _rotation = BitFieldFactory.getInstance(0xFF00);
|
||||
private short field_4_alignment_options;
|
||||
private static final BitField _alignment = bf(0x0007);
|
||||
private static final BitField _wrap_text = bf(0x0008);
|
||||
private static final BitField _vertical_alignment = bf(0x0070);
|
||||
private static final BitField _justify_last = bf(0x0080);
|
||||
private static final BitField _rotation = bf(0xFF00);
|
||||
|
||||
// field_5_indention_options
|
||||
private static final BitField _indent =
|
||||
BitFieldFactory.getInstance(0x000F);
|
||||
private static final BitField _shrink_to_fit =
|
||||
BitFieldFactory.getInstance(0x0010);
|
||||
private static final BitField _merge_cells =
|
||||
BitFieldFactory.getInstance(0x0020);
|
||||
private static final BitField _reading_order =
|
||||
BitFieldFactory.getInstance(0x00C0);
|
||||
private static final BitField _indent = bf(0x000F);
|
||||
private static final BitField _shrink_to_fit = bf(0x0010);
|
||||
private static final BitField _merge_cells = bf(0x0020);
|
||||
private static final BitField _reading_order = bf(0x00C0);
|
||||
|
||||
// apparently bits 8 and 9 are unused
|
||||
private static final BitField _indent_not_parent_format =
|
||||
BitFieldFactory.getInstance(0x0400);
|
||||
private static final BitField _indent_not_parent_font =
|
||||
BitFieldFactory.getInstance(0x0800);
|
||||
private static final BitField _indent_not_parent_alignment =
|
||||
BitFieldFactory.getInstance(0x1000);
|
||||
private static final BitField _indent_not_parent_border =
|
||||
BitFieldFactory.getInstance(0x2000);
|
||||
private static final BitField _indent_not_parent_pattern =
|
||||
BitFieldFactory.getInstance(0x4000);
|
||||
private static final BitField _indent_not_parent_cell_options =
|
||||
BitFieldFactory.getInstance(0x8000);
|
||||
private short field_5_indention_options;
|
||||
private static final BitField _indent_not_parent_format = bf(0x0400);
|
||||
private static final BitField _indent_not_parent_font = bf(0x0800);
|
||||
private static final BitField _indent_not_parent_alignment = bf(0x1000);
|
||||
private static final BitField _indent_not_parent_border = bf(0x2000);
|
||||
private static final BitField _indent_not_parent_pattern = bf(0x4000);
|
||||
private static final BitField _indent_not_parent_cell_options = bf(0x8000);
|
||||
|
||||
// field_6_border_options bit map
|
||||
private static final BitField _border_left = BitFieldFactory.getInstance(0x000F);
|
||||
private static final BitField _border_right = BitFieldFactory.getInstance(0x00F0);
|
||||
private static final BitField _border_top = BitFieldFactory.getInstance(0x0F00);
|
||||
private static final BitField _border_bottom = BitFieldFactory.getInstance(0xF000);
|
||||
private short field_6_border_options;
|
||||
private static final BitField _border_left = bf(0x000F);
|
||||
private static final BitField _border_right = bf(0x00F0);
|
||||
private static final BitField _border_top = bf(0x0F00);
|
||||
private static final BitField _border_bottom = bf(0xF000);
|
||||
|
||||
// all three of the following attributes are palette options
|
||||
// field_7_palette_options bit map
|
||||
private static final BitField _left_border_palette_idx =
|
||||
BitFieldFactory.getInstance(0x007F);
|
||||
private static final BitField _right_border_palette_idx =
|
||||
BitFieldFactory.getInstance(0x3F80);
|
||||
private static final BitField _diag =
|
||||
BitFieldFactory.getInstance(0xC000);
|
||||
private short field_7_palette_options;
|
||||
private static final BitField _left_border_palette_idx = bf(0x007F);
|
||||
private static final BitField _right_border_palette_idx = bf(0x3F80);
|
||||
private static final BitField _diag = bf(0xC000);
|
||||
|
||||
// field_8_adtl_palette_options bit map
|
||||
private static final BitField _top_border_palette_idx =
|
||||
BitFieldFactory.getInstance(0x0000007F);
|
||||
private static final BitField _bottom_border_palette_idx =
|
||||
BitFieldFactory.getInstance(0x00003F80);
|
||||
private static final BitField _adtl_diag =
|
||||
BitFieldFactory.getInstance(0x001fc000);
|
||||
private static final BitField _adtl_diag_line_style =
|
||||
BitFieldFactory.getInstance(0x01e00000);
|
||||
private static final BitField _top_border_palette_idx = bf(0x0000007F);
|
||||
private static final BitField _bottom_border_palette_idx = bf(0x00003F80);
|
||||
private static final BitField _adtl_diag = bf(0x001fc000);
|
||||
private static final BitField _adtl_diag_line_style = bf(0x01e00000);
|
||||
|
||||
// apparently bit 25 is unused
|
||||
private static final BitField _adtl_fill_pattern =
|
||||
BitFieldFactory.getInstance(0xfc000000);
|
||||
private int field_8_adtl_palette_options; // additional to avoid 2
|
||||
private static final BitField _adtl_fill_pattern = bf(0xfc000000);
|
||||
|
||||
// field_9_fill_palette_options bit map
|
||||
private static final BitField _fill_foreground = BitFieldFactory.getInstance(0x007F);
|
||||
private static final BitField _fill_background = BitFieldFactory.getInstance(0x3f80);
|
||||
private static final BitField _fill_foreground = bf(0x007F);
|
||||
private static final BitField _fill_background = bf(0x3f80);
|
||||
|
||||
// apparently bits 15 and 14 are unused
|
||||
private short field_9_fill_palette_options;
|
||||
|
||||
/**
|
||||
* Constructor ExtendedFormatRecord
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public ExtendedFormatRecord()
|
||||
{
|
||||
private static BitField bf(int i) {
|
||||
return BitFieldFactory.getInstance(i);
|
||||
}
|
||||
|
||||
public ExtendedFormatRecord(RecordInputStream in)
|
||||
{
|
||||
|
||||
// fields in BOTH style and Cell XF records
|
||||
private short field_1_font_index; // not bit-mapped
|
||||
private short field_2_format_index; // not bit-mapped
|
||||
|
||||
private short field_3_cell_options;
|
||||
private short field_4_alignment_options;
|
||||
private short field_5_indention_options;
|
||||
private short field_6_border_options;
|
||||
private short field_7_palette_options;
|
||||
private int field_8_adtl_palette_options; // additional to avoid 2
|
||||
|
||||
|
||||
// apparently bits 15 and 14 are unused
|
||||
private short field_9_fill_palette_options;
|
||||
|
||||
public ExtendedFormatRecord() {}
|
||||
|
||||
public ExtendedFormatRecord(ExtendedFormatRecord other) {
|
||||
super(other);
|
||||
field_1_font_index = other.field_1_font_index;
|
||||
field_2_format_index = other.field_2_format_index;
|
||||
field_3_cell_options = other.field_3_cell_options;
|
||||
field_4_alignment_options = other.field_4_alignment_options;
|
||||
field_5_indention_options = other.field_5_indention_options;
|
||||
field_6_border_options = other.field_6_border_options;
|
||||
field_7_palette_options = other.field_7_palette_options;
|
||||
field_8_adtl_palette_options = other.field_8_adtl_palette_options;
|
||||
field_9_fill_palette_options = other.field_9_fill_palette_options;
|
||||
}
|
||||
|
||||
public ExtendedFormatRecord(RecordInputStream in) {
|
||||
field_1_font_index = in.readShort();
|
||||
field_2_format_index = in.readShort();
|
||||
field_3_cell_options = in.readShort();
|
||||
|
@ -560,7 +545,7 @@ public final class ExtendedFormatRecord
|
|||
/**
|
||||
* <p>Sets whether or not to use the pattern in this XF instead of the
|
||||
* parent XF (foreground/background).</p>
|
||||
*
|
||||
*
|
||||
* @param pattern {@code true} if this XF has a different pattern
|
||||
* value than its parent, {@code false} otherwise.
|
||||
* @see #setIndentionOptions(short)
|
||||
|
@ -1788,16 +1773,16 @@ public final class ExtendedFormatRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clones all the style information from another
|
||||
* ExtendedFormatRecord, onto this one. This
|
||||
* ExtendedFormatRecord, onto this one. This
|
||||
* will then hold all the same style options.
|
||||
*
|
||||
*
|
||||
* If The source ExtendedFormatRecord comes from
|
||||
* a different Workbook, you will need to sort
|
||||
* out the font and format indices yourself!
|
||||
*
|
||||
*
|
||||
* @param source the ExtendedFormatRecord to copy from
|
||||
*/
|
||||
public void cloneStyleFrom(ExtendedFormatRecord source) {
|
||||
|
@ -1863,11 +1848,15 @@ public final class ExtendedFormatRecord
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public int[] stateSummary() {
|
||||
return new int[] { field_1_font_index, field_2_format_index, field_3_cell_options, field_4_alignment_options,
|
||||
field_5_indention_options, field_6_border_options, field_7_palette_options, field_8_adtl_palette_options, field_9_fill_palette_options };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ExtendedFormatRecord copy() {
|
||||
return new ExtendedFormatRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||
*/
|
||||
public class ExternSheetRecord extends StandardRecord {
|
||||
|
||||
public final static short sid = 0x0017;
|
||||
private final List<RefSubRecord> _list;
|
||||
|
||||
public static final short sid = 0x0017;
|
||||
private final List<RefSubRecord> _list = new ArrayList<>();
|
||||
|
||||
private static final class RefSubRecord {
|
||||
public static final int ENCODED_SIZE = 6;
|
||||
|
||||
|
@ -38,26 +38,31 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
private final int _extBookIndex;
|
||||
private int _firstSheetIndex; // may be -1 (0xFFFF)
|
||||
private int _lastSheetIndex; // may be -1 (0xFFFF)
|
||||
|
||||
public void adjustIndex(int offset) {
|
||||
_firstSheetIndex += offset;
|
||||
_lastSheetIndex += offset;
|
||||
}
|
||||
|
||||
/** a Constructor for making new sub record
|
||||
*/
|
||||
|
||||
public RefSubRecord(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
|
||||
_extBookIndex = extBookIndex;
|
||||
_firstSheetIndex = firstSheetIndex;
|
||||
_lastSheetIndex = lastSheetIndex;
|
||||
}
|
||||
|
||||
|
||||
public RefSubRecord(RefSubRecord other) {
|
||||
_extBookIndex = other._extBookIndex;
|
||||
_firstSheetIndex = other._firstSheetIndex;
|
||||
_lastSheetIndex = other._lastSheetIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
public RefSubRecord(RecordInputStream in) {
|
||||
this(in.readShort(), in.readShort(), in.readShort());
|
||||
}
|
||||
|
||||
public void adjustIndex(int offset) {
|
||||
_firstSheetIndex += offset;
|
||||
_lastSheetIndex += offset;
|
||||
}
|
||||
|
||||
public int getExtBookIndex(){
|
||||
return _extBookIndex;
|
||||
}
|
||||
|
@ -67,7 +72,7 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
public int getLastSheetIndex(){
|
||||
return _lastSheetIndex;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
@ -76,55 +81,53 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
buffer.append(" lastSheet=").append(_lastSheetIndex);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
out.writeShort(_extBookIndex);
|
||||
out.writeShort(_firstSheetIndex);
|
||||
out.writeShort(_lastSheetIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ExternSheetRecord() {
|
||||
_list = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ExternSheetRecord() {}
|
||||
|
||||
public ExternSheetRecord(ExternSheetRecord other) {
|
||||
other._list.stream().map(RefSubRecord::new).forEach(_list::add);
|
||||
}
|
||||
|
||||
public ExternSheetRecord(RecordInputStream in) {
|
||||
_list = new ArrayList<>();
|
||||
|
||||
int nItems = in.readShort();
|
||||
|
||||
|
||||
for (int i = 0 ; i < nItems ; ++i) {
|
||||
RefSubRecord rec = new RefSubRecord(in);
|
||||
_list.add(rec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* @return number of REF structures
|
||||
*/
|
||||
public int getNumOfRefs() {
|
||||
return _list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* adds REF struct (ExternSheetSubRecord)
|
||||
* @param rec REF struct
|
||||
*/
|
||||
public void addREFRecord(RefSubRecord rec) {
|
||||
_list.add(rec);
|
||||
}
|
||||
|
||||
|
||||
/** returns the number of REF Records, which is in model
|
||||
* @return number of REF records
|
||||
*/
|
||||
public int getNumOfREFRecords() {
|
||||
return _list.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -137,22 +140,22 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
sb.append('\n');
|
||||
}
|
||||
sb.append("[/EXTERNSHEET]\n");
|
||||
|
||||
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getDataSize() {
|
||||
return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
int nItems = _list.size();
|
||||
|
||||
out.writeShort(nItems);
|
||||
|
||||
|
||||
for (int i = 0; i < nItems; i++) {
|
||||
getRef(i).serialize(out);
|
||||
}
|
||||
|
@ -161,22 +164,22 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
private RefSubRecord getRef(int i) {
|
||||
return _list.get(i);
|
||||
}
|
||||
|
||||
|
||||
public void removeSheet(int sheetIdx) {
|
||||
int nItems = _list.size();
|
||||
for (int i = 0; i < nItems; i++) {
|
||||
RefSubRecord refSubRecord = _list.get(i);
|
||||
if(refSubRecord.getFirstSheetIndex() == sheetIdx &&
|
||||
if(refSubRecord.getFirstSheetIndex() == sheetIdx &&
|
||||
refSubRecord.getLastSheetIndex() == sheetIdx) {
|
||||
// removing the entry would mess up the sheet index in Formula of NameRecord
|
||||
_list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), -1, -1));
|
||||
} else if (refSubRecord.getFirstSheetIndex() > sheetIdx &&
|
||||
} else if (refSubRecord.getFirstSheetIndex() > sheetIdx &&
|
||||
refSubRecord.getLastSheetIndex() > sheetIdx) {
|
||||
_list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), refSubRecord.getFirstSheetIndex()-1, refSubRecord.getLastSheetIndex()-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return the non static version of the id for this record.
|
||||
*/
|
||||
|
@ -187,7 +190,7 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* @param refIndex specifies the n-th refIndex
|
||||
*
|
||||
*
|
||||
* @return the index of the SupBookRecord for this index
|
||||
*/
|
||||
public int getExtbookIndexFromRefIndex(int refIndex) {
|
||||
|
@ -197,7 +200,7 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* @param extBookIndex external sheet reference index
|
||||
*
|
||||
*
|
||||
* @return -1 if not found
|
||||
*/
|
||||
public int findRefIndexFromExtBookIndex(int extBookIndex) {
|
||||
|
@ -214,9 +217,9 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
* Returns the first sheet that the reference applies to, or
|
||||
* -1 if the referenced sheet can't be found, or -2 if the
|
||||
* reference is workbook scoped.
|
||||
*
|
||||
*
|
||||
* @param extRefIndex external sheet reference index
|
||||
*
|
||||
*
|
||||
* @return the first sheet that the reference applies to, or
|
||||
* -1 if the referenced sheet can't be found, or -2 if the
|
||||
* reference is workbook scoped
|
||||
|
@ -231,9 +234,9 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
* reference is workbook scoped.
|
||||
* For a single sheet reference, the first and last should be
|
||||
* the same.
|
||||
*
|
||||
*
|
||||
* @param extRefIndex external sheet reference index
|
||||
*
|
||||
*
|
||||
* @return the last sheet that the reference applies to, or
|
||||
* -1 if the referenced sheet can't be found, or -2 if the
|
||||
* reference is workbook scoped.
|
||||
|
@ -258,7 +261,7 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
* see {@link org.apache.poi.hssf.record.SupBookRecord#getSheetNames()}.
|
||||
* This referenced string specifies the name of the first sheet within the external workbook that is in scope.
|
||||
* This sheet MUST be a worksheet or macro sheet.</p>
|
||||
*
|
||||
*
|
||||
* <p>If the supporting link type is self-referencing, then this value specifies the zero-based index of a
|
||||
* {@link org.apache.poi.hssf.record.BoundSheetRecord} record in the workbook stream that specifies
|
||||
* the first sheet within the scope of this reference. This sheet MUST be a worksheet or a macro sheet.
|
||||
|
@ -283,7 +286,7 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
if (ref.getExtBookIndex() != externalBookIndex) {
|
||||
continue;
|
||||
}
|
||||
if (ref.getFirstSheetIndex() == firstSheetIndex &&
|
||||
if (ref.getFirstSheetIndex() == firstSheetIndex &&
|
||||
ref.getLastSheetIndex() == lastSheetIndex) {
|
||||
return i;
|
||||
}
|
||||
|
@ -301,4 +304,9 @@ public class ExternSheetRecord extends StandardRecord {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternSheetRecord copy() {
|
||||
return new ExternSheetRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.apache.poi.util.StringUtil;
|
|||
*/
|
||||
public final class ExternalNameRecord extends StandardRecord {
|
||||
|
||||
public final static short sid = 0x0023; // as per BIFF8. (some old versions used 0x223)
|
||||
public static final short sid = 0x0023; // as per BIFF8. (some old versions used 0x223)
|
||||
|
||||
private static final int OPT_BUILTIN_NAME = 0x0001;
|
||||
private static final int OPT_AUTOMATIC_LINK = 0x0002; // m$ doc calls this fWantAdvise
|
||||
|
@ -39,11 +39,11 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
|
||||
|
||||
|
||||
private short field_1_option_flag;
|
||||
private short field_2_ixals;
|
||||
private short field_3_not_used;
|
||||
private short field_1_option_flag;
|
||||
private short field_2_ixals;
|
||||
private short field_3_not_used;
|
||||
private String field_4_name;
|
||||
private Formula field_5_name_definition;
|
||||
private Formula field_5_name_definition;
|
||||
|
||||
/**
|
||||
* 'rgoper' / 'Last received results of the DDE link'
|
||||
|
@ -60,6 +60,54 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
*/
|
||||
private int _nRows;
|
||||
|
||||
public ExternalNameRecord() {
|
||||
field_2_ixals = 0;
|
||||
}
|
||||
|
||||
public ExternalNameRecord(ExternalNameRecord other) {
|
||||
super(other);
|
||||
field_1_option_flag = other.field_1_option_flag;
|
||||
field_2_ixals = other.field_2_ixals;
|
||||
field_3_not_used = other.field_3_not_used;
|
||||
field_4_name = other.field_4_name;
|
||||
field_5_name_definition = (other.field_5_name_definition == null) ? null : other.field_5_name_definition.copy();
|
||||
_ddeValues = (other._ddeValues == null) ? null : other._ddeValues.clone();
|
||||
_nColumns = other._nColumns;
|
||||
_nRows = other._nRows;
|
||||
}
|
||||
|
||||
public ExternalNameRecord(RecordInputStream in) {
|
||||
field_1_option_flag = in.readShort();
|
||||
field_2_ixals = in.readShort();
|
||||
field_3_not_used = in.readShort();
|
||||
|
||||
int numChars = in.readUByte();
|
||||
field_4_name = StringUtil.readUnicodeString(in, numChars);
|
||||
|
||||
// the record body can take different forms.
|
||||
// The form is dictated by the values of 3-th and 4-th bits in field_1_option_flag
|
||||
if(!isOLELink() && !isStdDocumentNameIdentifier()){
|
||||
// another switch: the fWantAdvise bit specifies whether the body describes
|
||||
// an external defined name or a DDE data item
|
||||
if(isAutomaticLink()){
|
||||
if(in.available() > 0) {
|
||||
//body specifies DDE data item
|
||||
int nColumns = in.readUByte() + 1;
|
||||
int nRows = in.readShort() + 1;
|
||||
|
||||
int totalCount = nRows * nColumns;
|
||||
_ddeValues = ConstantValueParser.parse(in, totalCount);
|
||||
_nColumns = nColumns;
|
||||
_nRows = nRows;
|
||||
}
|
||||
} else {
|
||||
//body specifies an external defined name
|
||||
int formulaLen = in.readUShort();
|
||||
field_5_name_definition = Formula.read(formulaLen, in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the name is a built-in name
|
||||
*/
|
||||
|
@ -68,7 +116,7 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
}
|
||||
/**
|
||||
* For OLE and DDE, links can be either 'automatic' or 'manual'
|
||||
*
|
||||
*
|
||||
* @return {@code true} if this is a automatic link
|
||||
*/
|
||||
public boolean isAutomaticLink() {
|
||||
|
@ -76,7 +124,7 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
}
|
||||
/**
|
||||
* only for OLE and DDE
|
||||
*
|
||||
*
|
||||
* @return {@code true} if this is a picture link
|
||||
*/
|
||||
public boolean isPicureLink() {
|
||||
|
@ -84,7 +132,7 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
}
|
||||
/**
|
||||
* DDE links only. If <code>true</code>, this denotes the 'StdDocumentName'
|
||||
*
|
||||
*
|
||||
* @return {@code true} if this denotes the 'StdDocumentName'
|
||||
*/
|
||||
public boolean isStdDocumentNameIdentifier() {
|
||||
|
@ -102,7 +150,7 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
public String getText() {
|
||||
return field_4_name;
|
||||
}
|
||||
|
||||
|
||||
public void setText(String str) {
|
||||
field_4_name = str;
|
||||
}
|
||||
|
@ -112,13 +160,13 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
* index of the name of the Sheet this refers to, as
|
||||
* defined in the preceding {@link SupBookRecord}.
|
||||
* If it isn't a local name, then it must be zero.
|
||||
*
|
||||
*
|
||||
* @return the index of the name of the Sheet this refers to
|
||||
*/
|
||||
public short getIx() {
|
||||
return field_2_ixals;
|
||||
}
|
||||
|
||||
|
||||
public void setIx(short ix) {
|
||||
field_2_ixals = ix;
|
||||
}
|
||||
|
@ -134,7 +182,7 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
@Override
|
||||
protected int getDataSize(){
|
||||
int result = 2 + 4; // short and int
|
||||
result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, not short
|
||||
result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, not short
|
||||
|
||||
if(!isOLELink() && !isStdDocumentNameIdentifier()){
|
||||
if(isAutomaticLink()){
|
||||
|
@ -171,42 +219,6 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
}
|
||||
}
|
||||
|
||||
public ExternalNameRecord() {
|
||||
field_2_ixals = 0;
|
||||
}
|
||||
|
||||
public ExternalNameRecord(RecordInputStream in) {
|
||||
field_1_option_flag = in.readShort();
|
||||
field_2_ixals = in.readShort();
|
||||
field_3_not_used = in.readShort();
|
||||
|
||||
int numChars = in.readUByte();
|
||||
field_4_name = StringUtil.readUnicodeString(in, numChars);
|
||||
|
||||
// the record body can take different forms.
|
||||
// The form is dictated by the values of 3-th and 4-th bits in field_1_option_flag
|
||||
if(!isOLELink() && !isStdDocumentNameIdentifier()){
|
||||
// another switch: the fWantAdvise bit specifies whether the body describes
|
||||
// an external defined name or a DDE data item
|
||||
if(isAutomaticLink()){
|
||||
if(in.available() > 0) {
|
||||
//body specifies DDE data item
|
||||
int nColumns = in.readUByte() + 1;
|
||||
int nRows = in.readShort() + 1;
|
||||
|
||||
int totalCount = nRows * nColumns;
|
||||
_ddeValues = ConstantValueParser.parse(in, totalCount);
|
||||
_nColumns = nColumns;
|
||||
_nRows = nRows;
|
||||
}
|
||||
} else {
|
||||
//body specifies an external defined name
|
||||
int formulaLen = in.readUShort();
|
||||
field_5_name_definition = Formula.read(formulaLen, in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getSid() {
|
||||
return sid;
|
||||
|
@ -228,4 +240,9 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||
sb.append("[/EXTERNALNAME]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalNameRecord copy() {
|
||||
return new ExternalNameRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,29 +19,30 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.hssf.record.common.FtrHeader;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: FeatHdr (Feature Header) Record
|
||||
* <P>
|
||||
* This record specifies common information for Shared Features, and
|
||||
* specifies the beginning of a collection of records to define them.
|
||||
* The collection of data (Globals Substream ABNF, macro sheet substream
|
||||
* This record specifies common information for Shared Features, and
|
||||
* specifies the beginning of a collection of records to define them.
|
||||
* The collection of data (Globals Substream ABNF, macro sheet substream
|
||||
* ABNF or worksheet substream ABNF) specifies Shared Feature data.
|
||||
*/
|
||||
public final class FeatHdrRecord extends StandardRecord implements Cloneable {
|
||||
public final class FeatHdrRecord extends StandardRecord {
|
||||
/**
|
||||
* Specifies the enhanced protection type. Used to protect a
|
||||
* shared workbook by restricting access to some areas of it
|
||||
* Specifies the enhanced protection type. Used to protect a
|
||||
* shared workbook by restricting access to some areas of it
|
||||
*/
|
||||
public static final int SHAREDFEATURES_ISFPROTECTION = 0x02;
|
||||
/**
|
||||
* Specifies that formula errors should be ignored
|
||||
* Specifies that formula errors should be ignored
|
||||
*/
|
||||
public static final int SHAREDFEATURES_ISFFEC2 = 0x03;
|
||||
/**
|
||||
* Specifies the smart tag type. Recognises certain
|
||||
* types of entries (proper names, dates/times etc) and
|
||||
* flags them for action
|
||||
* flags them for action
|
||||
*/
|
||||
public static final int SHAREDFEATURES_ISFFACTOID = 0x04;
|
||||
/**
|
||||
|
@ -50,13 +51,13 @@ public final class FeatHdrRecord extends StandardRecord implements Cloneable {
|
|||
*/
|
||||
public static final int SHAREDFEATURES_ISFLIST = 0x05;
|
||||
|
||||
|
||||
public final static short sid = 0x0867;
|
||||
|
||||
private FtrHeader futureHeader;
|
||||
public static final short sid = 0x0867;
|
||||
|
||||
private final FtrHeader futureHeader;
|
||||
private int isf_sharedFeatureType; // See SHAREDFEATURES_
|
||||
private byte reserved; // Should always be one
|
||||
/**
|
||||
/**
|
||||
* 0x00000000 = rgbHdrData not present
|
||||
* 0xffffffff = rgbHdrData present
|
||||
*/
|
||||
|
@ -69,13 +70,18 @@ public final class FeatHdrRecord extends StandardRecord implements Cloneable {
|
|||
futureHeader.setRecordType(sid);
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
public FeatHdrRecord(FeatHdrRecord other) {
|
||||
super(other);
|
||||
futureHeader = other.futureHeader.copy();
|
||||
isf_sharedFeatureType = other.isf_sharedFeatureType;
|
||||
reserved = other.reserved;
|
||||
cbHdrData = other.cbHdrData;
|
||||
rgbHdrData = (other.rgbHdrData == null) ? null : other.rgbHdrData.clone();
|
||||
}
|
||||
|
||||
public FeatHdrRecord(RecordInputStream in) {
|
||||
futureHeader = new FtrHeader(in);
|
||||
|
||||
|
||||
isf_sharedFeatureType = in.readShort();
|
||||
reserved = in.readByte();
|
||||
cbHdrData = in.readInt();
|
||||
|
@ -83,19 +89,23 @@ public final class FeatHdrRecord extends StandardRecord implements Cloneable {
|
|||
rgbHdrData = in.readRemainder();
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("[FEATURE HEADER]\n");
|
||||
|
||||
|
||||
// TODO ...
|
||||
|
||||
|
||||
buffer.append("[/FEATURE HEADER]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
futureHeader.serialize(out);
|
||||
|
||||
|
||||
out.writeShort(isf_sharedFeatureType);
|
||||
out.writeByte(reserved);
|
||||
out.writeInt((int)cbHdrData);
|
||||
|
@ -105,12 +115,20 @@ public final class FeatHdrRecord extends StandardRecord implements Cloneable {
|
|||
protected int getDataSize() {
|
||||
return 12 + 2+1+4+rgbHdrData.length;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FeatHdrRecord clone() {
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FeatHdrRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatHdrRecord copy() {
|
||||
//HACK: do a "cheat" clone, see Record.java for more information
|
||||
return (FeatHdrRecord)cloneViaReserialise();
|
||||
return new FeatHdrRecord(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.poi.hssf.record.common.FeatFormulaErr2;
|
||||
import org.apache.poi.hssf.record.common.FeatProtection;
|
||||
import org.apache.poi.hssf.record.common.FeatSmartTag;
|
||||
|
@ -26,6 +28,7 @@ import org.apache.poi.ss.util.CellRangeAddress;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Feat (Feature) Record
|
||||
|
@ -33,19 +36,17 @@ import org.apache.poi.util.POILogger;
|
|||
* This record specifies Shared Features data. It is normally paired
|
||||
* up with a {@link FeatHdrRecord}.
|
||||
*/
|
||||
public final class FeatRecord extends StandardRecord implements Cloneable {
|
||||
private static POILogger logger = POILogFactory.getLogger(FeatRecord.class);
|
||||
public final static short sid = 0x0868;
|
||||
public final class FeatRecord extends StandardRecord {
|
||||
private static final POILogger logger = POILogFactory.getLogger(FeatRecord.class);
|
||||
public static final short sid = 0x0868;
|
||||
// SIDs from newer versions
|
||||
public final static short v11_sid = 0x0872;
|
||||
public final static short v12_sid = 0x0878;
|
||||
|
||||
private FtrHeader futureHeader;
|
||||
|
||||
/**
|
||||
* See SHAREDFEATURES_* on {@link FeatHdrRecord}
|
||||
*/
|
||||
private int isf_sharedFeatureType;
|
||||
public static final short v11_sid = 0x0872;
|
||||
public static final short v12_sid = 0x0878;
|
||||
|
||||
private final FtrHeader futureHeader;
|
||||
|
||||
/** See SHAREDFEATURES_* on {@link FeatHdrRecord} */
|
||||
private int isf_sharedFeatureType;
|
||||
private byte reserved1; // Should always be zero
|
||||
private long reserved2; // Should always be zero
|
||||
/** Only matters if type is ISFFEC2 */
|
||||
|
@ -55,24 +56,33 @@ public final class FeatRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Contents depends on isf_sharedFeatureType :
|
||||
* ISFPROTECTION -> FeatProtection
|
||||
* ISFPROTECTION -> FeatProtection
|
||||
* ISFFEC2 -> FeatFormulaErr2
|
||||
* ISFFACTOID -> FeatSmartTag
|
||||
*/
|
||||
private SharedFeature sharedFeature;
|
||||
|
||||
private SharedFeature sharedFeature;
|
||||
|
||||
public FeatRecord() {
|
||||
futureHeader = new FtrHeader();
|
||||
futureHeader.setRecordType(sid);
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
public FeatRecord(FeatRecord other) {
|
||||
super(other);
|
||||
futureHeader = other.futureHeader.copy();
|
||||
isf_sharedFeatureType = other.isf_sharedFeatureType;
|
||||
reserved1 = other.reserved1;
|
||||
reserved2 = other.reserved2;
|
||||
cbFeatData = other.cbFeatData;
|
||||
reserved3 = other.reserved3;
|
||||
cellRefs = (other.cellRefs == null) ? null :
|
||||
Stream.of(other.cellRefs).map(CellRangeAddress::copy).toArray(CellRangeAddress[]::new);
|
||||
sharedFeature = (other.sharedFeature == null) ? null : other.sharedFeature.copy();
|
||||
}
|
||||
|
||||
public FeatRecord(RecordInputStream in) {
|
||||
futureHeader = new FtrHeader(in);
|
||||
|
||||
|
||||
isf_sharedFeatureType = in.readShort();
|
||||
reserved1 = in.readByte();
|
||||
reserved2 = in.readInt();
|
||||
|
@ -84,7 +94,7 @@ public final class FeatRecord extends StandardRecord implements Cloneable {
|
|||
for(int i=0; i<cellRefs.length; i++) {
|
||||
cellRefs[i] = new CellRangeAddress(in);
|
||||
}
|
||||
|
||||
|
||||
switch(isf_sharedFeatureType) {
|
||||
case FeatHdrRecord.SHAREDFEATURES_ISFPROTECTION:
|
||||
sharedFeature = new FeatProtection(in);
|
||||
|
@ -100,30 +110,34 @@ public final class FeatRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
}
|
||||
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("[SHARED FEATURE]\n");
|
||||
|
||||
|
||||
// TODO ...
|
||||
|
||||
|
||||
buffer.append("[/SHARED FEATURE]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
futureHeader.serialize(out);
|
||||
|
||||
|
||||
out.writeShort(isf_sharedFeatureType);
|
||||
out.writeByte(reserved1);
|
||||
out.writeInt((int)reserved2);
|
||||
out.writeShort(cellRefs.length);
|
||||
out.writeInt((int)cbFeatData);
|
||||
out.writeShort(reserved3);
|
||||
|
||||
|
||||
for(int i=0; i<cellRefs.length; i++) {
|
||||
cellRefs[i].serialize(out);
|
||||
}
|
||||
|
||||
|
||||
sharedFeature.serialize(out);
|
||||
}
|
||||
|
||||
|
@ -156,7 +170,7 @@ public final class FeatRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
public void setSharedFeature(SharedFeature feature) {
|
||||
this.sharedFeature = feature;
|
||||
|
||||
|
||||
if(feature instanceof FeatProtection) {
|
||||
isf_sharedFeatureType = FeatHdrRecord.SHAREDFEATURES_ISFPROTECTION;
|
||||
}
|
||||
|
@ -166,7 +180,7 @@ public final class FeatRecord extends StandardRecord implements Cloneable {
|
|||
if(feature instanceof FeatSmartTag) {
|
||||
isf_sharedFeatureType = FeatHdrRecord.SHAREDFEATURES_ISFFACTOID;
|
||||
}
|
||||
|
||||
|
||||
if(isf_sharedFeatureType == FeatHdrRecord.SHAREDFEATURES_ISFFEC2) {
|
||||
cbFeatData = sharedFeature.getDataSize();
|
||||
} else {
|
||||
|
@ -174,12 +188,16 @@ public final class FeatRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FeatRecord clone() {
|
||||
//HACK: do a "cheat" clone, see Record.java for more information
|
||||
return (FeatRecord)cloneViaReserialise();
|
||||
}
|
||||
return copy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FeatRecord copy() {
|
||||
return new FeatRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,13 +33,14 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianByteArrayOutputStream;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.LittleEndianOutputStream;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: File Pass Record (0x002F) <p>
|
||||
* File Pass Record (0x002F) <p>
|
||||
*
|
||||
* Description: Indicates that the record after this record are encrypted.
|
||||
* Indicates that the record after this record are encrypted.
|
||||
*/
|
||||
public final class FilePassRecord extends StandardRecord implements Cloneable {
|
||||
public final class FilePassRecord extends StandardRecord {
|
||||
public static final short sid = 0x002F;
|
||||
private static final int ENCRYPTION_XOR = 0;
|
||||
private static final int ENCRYPTION_OTHER = 1;
|
||||
|
@ -48,12 +49,9 @@ public final class FilePassRecord extends StandardRecord implements Cloneable {
|
|||
private EncryptionInfo encryptionInfo;
|
||||
|
||||
private FilePassRecord(FilePassRecord other) {
|
||||
super(other);
|
||||
encryptionType = other.encryptionType;
|
||||
try {
|
||||
encryptionInfo = other.encryptionInfo.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new EncryptedDocumentException(e);
|
||||
}
|
||||
encryptionInfo = other.encryptionInfo.copy();
|
||||
}
|
||||
|
||||
public FilePassRecord(EncryptionMode encryptionMode) {
|
||||
|
@ -138,8 +136,16 @@ public final class FilePassRecord extends StandardRecord implements Cloneable {
|
|||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilePassRecord clone() {
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FilePassRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilePassRecord copy() {
|
||||
return new FilePassRecord(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,17 +18,16 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: FILESHARING (0x005B) <p>
|
||||
* Description: stores the encrypted readonly for a workbook (write protect)
|
||||
* This functionality is accessed from the options dialog box available when performing 'Save As'.<p>
|
||||
* REFERENCE: PG 314 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Stores the encrypted readonly for a workbook (write protect).<p>
|
||||
* This functionality is accessed from the options dialog box available when performing 'Save As'.
|
||||
*/
|
||||
public final class FileSharingRecord extends StandardRecord implements Cloneable {
|
||||
public final class FileSharingRecord extends StandardRecord {
|
||||
|
||||
public final static short sid = 0x005B;
|
||||
public static final short sid = 0x005B;
|
||||
private short field_1_readonly;
|
||||
private short field_2_password;
|
||||
private byte field_3_username_unicode_options;
|
||||
|
@ -36,14 +35,22 @@ public final class FileSharingRecord extends StandardRecord implements Cloneable
|
|||
|
||||
public FileSharingRecord() {}
|
||||
|
||||
public FileSharingRecord(FileSharingRecord other) {
|
||||
super(other);
|
||||
field_1_readonly = other.field_1_readonly;
|
||||
field_2_password = other.field_2_password;
|
||||
field_3_username_unicode_options = other.field_3_username_unicode_options;
|
||||
field_3_username_value = other.field_3_username_value;
|
||||
}
|
||||
|
||||
public FileSharingRecord(RecordInputStream in) {
|
||||
field_1_readonly = in.readShort();
|
||||
field_2_password = in.readShort();
|
||||
|
||||
|
||||
int nameLen = in.readShort();
|
||||
|
||||
|
||||
if(nameLen > 0) {
|
||||
// TODO - Current examples(3) from junits only have zero length username.
|
||||
// TODO - Current examples(3) from junits only have zero length username.
|
||||
field_3_username_unicode_options = in.readByte();
|
||||
field_3_username_value = in.readCompressedUnicode(nameLen);
|
||||
} else {
|
||||
|
@ -137,11 +144,15 @@ public final class FileSharingRecord extends StandardRecord implements Cloneable
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FileSharingRecord clone() {
|
||||
FileSharingRecord clone = new FileSharingRecord();
|
||||
clone.setReadOnly(field_1_readonly);
|
||||
clone.setPassword(field_2_password);
|
||||
clone.setUsername(field_3_username_value);
|
||||
return clone;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileSharingRecord copy() {
|
||||
return new FileSharingRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,35 +15,32 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: Function Group Count Record<P>
|
||||
* Description: Number of built in function groups in the current version of the
|
||||
* Spreadsheet (probably only used on Windoze)<P>
|
||||
* REFERENCE: PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* umber of built in function groups in the current version of the Spreadsheet (probably only used on Windows)
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class FnGroupCountRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0x9c;
|
||||
public final class FnGroupCountRecord extends StandardRecord {
|
||||
public static final short sid = 0x9c;
|
||||
|
||||
/**
|
||||
* suggested default (14 dec)
|
||||
*/
|
||||
|
||||
public final static short COUNT = 14;
|
||||
public static final short COUNT = 14;
|
||||
private short field_1_count;
|
||||
|
||||
public FnGroupCountRecord()
|
||||
{
|
||||
public FnGroupCountRecord() {}
|
||||
|
||||
public FnGroupCountRecord(FnGroupCountRecord other) {
|
||||
super(other);
|
||||
field_1_count = other.field_1_count;
|
||||
}
|
||||
|
||||
public FnGroupCountRecord(RecordInputStream in)
|
||||
|
@ -96,4 +93,9 @@ public final class FnGroupCountRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FnGroupCountRecord copy() {
|
||||
return new FnGroupCountRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,50 +25,68 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: Font Record (0x0031) <p>
|
||||
* - describes a font in the workbook (index = 0-3,5-infinity - skip 4)<P>
|
||||
* Description: An element in the Font Table<p>
|
||||
* REFERENCE: PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
*/
|
||||
/** Describes a font in the workbook */
|
||||
public final class FontRecord extends StandardRecord {
|
||||
// docs are wrong (0x231 Microsoft Support site article Q184647)
|
||||
public final static short sid = 0x0031;
|
||||
public final static short SS_NONE = 0;
|
||||
public final static short SS_SUPER = 1;
|
||||
public final static short SS_SUB = 2;
|
||||
public final static byte U_NONE = 0;
|
||||
public final static byte U_SINGLE = 1;
|
||||
public final static byte U_DOUBLE = 2;
|
||||
public final static byte U_SINGLE_ACCOUNTING = 0x21;
|
||||
public final static byte U_DOUBLE_ACCOUNTING = 0x22;
|
||||
// in units of .05 of a point
|
||||
private short field_1_font_height;
|
||||
private short field_2_attributes;
|
||||
public static final short sid = 0x0031;
|
||||
public static final short SS_NONE = 0;
|
||||
public static final short SS_SUPER = 1;
|
||||
public static final short SS_SUB = 2;
|
||||
public static final byte U_NONE = 0;
|
||||
public static final byte U_SINGLE = 1;
|
||||
public static final byte U_DOUBLE = 2;
|
||||
public static final byte U_SINGLE_ACCOUNTING = 0x21;
|
||||
public static final byte U_DOUBLE_ACCOUNTING = 0x22;
|
||||
|
||||
// 0 0x01 - Reserved bit must be 0
|
||||
private static final BitField italic = BitFieldFactory.getInstance(0x02); // is this font in italics
|
||||
// is this font in italics
|
||||
private static final BitField italic = BitFieldFactory.getInstance(0x02);
|
||||
|
||||
// 2 0x04 - reserved bit must be 0
|
||||
private static final BitField strikeout =BitFieldFactory.getInstance(0x08); // is this font has a line through the center
|
||||
private static final BitField macoutline = BitFieldFactory.getInstance(0x10); // some weird macintosh thing....but who understands those mac people anyhow
|
||||
private static final BitField macshadow = BitFieldFactory.getInstance(0x20); // some weird macintosh thing....but who understands those mac people anyhow
|
||||
// is this font has a line through the center
|
||||
private static final BitField strikeout = BitFieldFactory.getInstance(0x08);
|
||||
// some weird macintosh thing....but who understands those mac people anyhow
|
||||
private static final BitField macoutline = BitFieldFactory.getInstance(0x10);
|
||||
private static final BitField macshadow = BitFieldFactory.getInstance(0x20);
|
||||
|
||||
// in units of .05 of a point
|
||||
private short field_1_font_height;
|
||||
private short field_2_attributes;
|
||||
|
||||
// 7-6 - reserved bits must be 0
|
||||
// the rest is unused
|
||||
private short field_3_color_palette_index;
|
||||
private short field_4_bold_weight;
|
||||
private short field_5_super_sub_script; // 00none/01super/02sub
|
||||
private byte field_6_underline; // 00none/01single/02double/21singleaccounting/22doubleaccounting
|
||||
private byte field_7_family; // ?? defined by windows api logfont structure?
|
||||
private byte field_8_charset; // ?? defined by windows api logfont structure?
|
||||
private byte field_9_zero; // must be 0
|
||||
private short field_3_color_palette_index;
|
||||
private short field_4_bold_weight;
|
||||
// 00none/01super/02sub
|
||||
private short field_5_super_sub_script;
|
||||
// 00none/01single/02double/21singleaccounting/22doubleaccounting
|
||||
private byte field_6_underline;
|
||||
// ?? defined by windows api logfont structure?
|
||||
private byte field_7_family;
|
||||
// ?? defined by windows api logfont structure?
|
||||
private byte field_8_charset;
|
||||
// must be 0
|
||||
private byte field_9_zero;
|
||||
/** possibly empty string never <code>null</code> */
|
||||
private String field_11_font_name;
|
||||
private String field_11_font_name;
|
||||
|
||||
public FontRecord() {
|
||||
}
|
||||
|
||||
public FontRecord(FontRecord other) {
|
||||
super(other);
|
||||
field_1_font_height = other.field_1_font_height;
|
||||
field_2_attributes = other.field_2_attributes;
|
||||
field_3_color_palette_index = other.field_3_color_palette_index;
|
||||
field_4_bold_weight = other.field_4_bold_weight;
|
||||
field_5_super_sub_script = other.field_5_super_sub_script;
|
||||
field_6_underline = other.field_6_underline;
|
||||
field_7_family = other.field_7_family;
|
||||
field_8_charset = other.field_8_charset;
|
||||
field_9_zero = other.field_9_zero;
|
||||
field_11_font_name = other.field_11_font_name;
|
||||
}
|
||||
|
||||
public FontRecord(RecordInputStream in) {
|
||||
field_1_font_height = in.readShort();
|
||||
field_2_attributes = in.readShort();
|
||||
|
@ -490,4 +508,9 @@ public final class FontRecord extends StandardRecord {
|
|||
public boolean equals(Object o) {
|
||||
return (o instanceof FontRecord) && sameProperties((FontRecord) o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRecord copy() {
|
||||
return new FontRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,18 +17,22 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Footer Record (0x0015)<p>
|
||||
* Description: Specifies the footer for a sheet<p>
|
||||
* REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Specifies the footer for a sheet
|
||||
*/
|
||||
public final class FooterRecord extends HeaderFooterBase implements Cloneable {
|
||||
public final static short sid = 0x0015;
|
||||
public final class FooterRecord extends HeaderFooterBase {
|
||||
public static final short sid = 0x0015;
|
||||
|
||||
public FooterRecord(String text) {
|
||||
super(text);
|
||||
}
|
||||
|
||||
public FooterRecord(FooterRecord other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public FooterRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
@ -47,7 +51,15 @@ public final class FooterRecord extends HeaderFooterBase implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FooterRecord clone() {
|
||||
return new FooterRecord(getText());
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FooterRecord copy() {
|
||||
return new FooterRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,30 +22,29 @@ import org.apache.poi.util.LittleEndianConsts;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: Format Record (0x041E)<p>
|
||||
* Description: describes a number format -- those goofy strings like $(#,###)<p>
|
||||
*
|
||||
* REFERENCE: PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Describes a number format -- those goofy strings like $(#,###)
|
||||
*/
|
||||
public final class FormatRecord extends StandardRecord implements Cloneable {
|
||||
public final class FormatRecord extends StandardRecord {
|
||||
|
||||
private static final POILogger logger = POILogFactory.getLogger(FormatRecord.class);
|
||||
|
||||
public final static short sid = 0x041E;
|
||||
public static final short sid = 0x041E;
|
||||
|
||||
private final int field_1_index_code;
|
||||
private final boolean field_3_hasMultibyte;
|
||||
private final String field_4_formatstring;
|
||||
|
||||
private FormatRecord(FormatRecord other) {
|
||||
super(other);
|
||||
field_1_index_code = other.field_1_index_code;
|
||||
field_3_hasMultibyte = other.field_3_hasMultibyte;
|
||||
field_4_formatstring = other.field_4_formatstring;
|
||||
}
|
||||
|
||||
|
||||
public FormatRecord(int indexCode, String fs) {
|
||||
field_1_index_code = indexCode;
|
||||
field_4_formatstring = fs;
|
||||
|
@ -114,9 +113,17 @@ public final class FormatRecord extends StandardRecord implements Cloneable {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FormatRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormatRecord copy() {
|
||||
return new FormatRecord(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,168 +18,28 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.ss.formula.Formula;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.util.*;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Formula Record (0x0006).
|
||||
* REFERENCE: PG 317/444 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
public final class FormulaRecord extends CellRecord implements Cloneable {
|
||||
public final class FormulaRecord extends CellRecord {
|
||||
|
||||
public static final short sid = 0x0006; // docs say 406...because of a bug Microsoft support site article #Q184647)
|
||||
private static int FIXED_SIZE = 14; // double + short + int
|
||||
// docs say 406...because of a bug Microsoft support site article #Q184647)
|
||||
public static final short sid = 0x0006;
|
||||
// double + short + int
|
||||
private static final int FIXED_SIZE = 14;
|
||||
|
||||
private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001);
|
||||
private static final BitField calcOnLoad = BitFieldFactory.getInstance(0x0002);
|
||||
private static final BitField sharedFormula = BitFieldFactory.getInstance(0x0008);
|
||||
|
||||
/**
|
||||
* Manages the cached formula result values of other types besides numeric.
|
||||
* Excel encodes the same 8 bytes that would be field_4_value with various NaN
|
||||
* values that are decoded/encoded by this class.
|
||||
*/
|
||||
static final class SpecialCachedValue {
|
||||
/** deliberately chosen by Excel in order to encode other values within Double NaNs */
|
||||
private static final long BIT_MARKER = 0xFFFF000000000000L;
|
||||
private static final int VARIABLE_DATA_LENGTH = 6;
|
||||
private static final int DATA_INDEX = 2;
|
||||
|
||||
// FIXME: can these be merged with {@link CellType}?
|
||||
// are the numbers specific to the HSSF formula record format or just a poor-man's enum?
|
||||
public static final int STRING = 0;
|
||||
public static final int BOOLEAN = 1;
|
||||
public static final int ERROR_CODE = 2;
|
||||
public static final int EMPTY = 3;
|
||||
|
||||
private final byte[] _variableData;
|
||||
|
||||
private SpecialCachedValue(byte[] data) {
|
||||
_variableData = data;
|
||||
}
|
||||
|
||||
public int getTypeCode() {
|
||||
return _variableData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if the double value encoded by <tt>valueLongBits</tt>
|
||||
* is a normal (non NaN) double value.
|
||||
*/
|
||||
public static SpecialCachedValue create(long valueLongBits) {
|
||||
if ((BIT_MARKER & valueLongBits) != BIT_MARKER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] result = new byte[VARIABLE_DATA_LENGTH];
|
||||
long x = valueLongBits;
|
||||
for (int i=0; i<VARIABLE_DATA_LENGTH; i++) {
|
||||
result[i] = (byte) x;
|
||||
x >>= 8;
|
||||
}
|
||||
switch (result[0]) {
|
||||
case STRING:
|
||||
case BOOLEAN:
|
||||
case ERROR_CODE:
|
||||
case EMPTY:
|
||||
break;
|
||||
default:
|
||||
throw new org.apache.poi.util.RecordFormatException("Bad special value code (" + result[0] + ")");
|
||||
}
|
||||
return new SpecialCachedValue(result);
|
||||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
out.write(_variableData);
|
||||
out.writeShort(0xFFFF);
|
||||
}
|
||||
|
||||
public String formatDebugString() {
|
||||
return formatValue() + ' ' + HexDump.toHex(_variableData);
|
||||
}
|
||||
|
||||
private String formatValue() {
|
||||
int typeCode = getTypeCode();
|
||||
switch (typeCode) {
|
||||
case STRING:
|
||||
return "<string>";
|
||||
case BOOLEAN:
|
||||
return getDataValue() == 0 ? "FALSE" : "TRUE";
|
||||
case ERROR_CODE:
|
||||
return ErrorEval.getText(getDataValue());
|
||||
case EMPTY:
|
||||
return "<empty>";
|
||||
}
|
||||
return "#error(type=" + typeCode + ")#";
|
||||
}
|
||||
|
||||
private int getDataValue() {
|
||||
return _variableData[DATA_INDEX];
|
||||
}
|
||||
|
||||
public static SpecialCachedValue createCachedEmptyValue() {
|
||||
return create(EMPTY, 0);
|
||||
}
|
||||
|
||||
public static SpecialCachedValue createForString() {
|
||||
return create(STRING, 0);
|
||||
}
|
||||
|
||||
public static SpecialCachedValue createCachedBoolean(boolean b) {
|
||||
return create(BOOLEAN, b ? 1 : 0);
|
||||
}
|
||||
|
||||
public static SpecialCachedValue createCachedErrorCode(int errorCode) {
|
||||
return create(ERROR_CODE, errorCode);
|
||||
}
|
||||
|
||||
private static SpecialCachedValue create(int code, int data) {
|
||||
byte[] vd = {
|
||||
(byte) code,
|
||||
0,
|
||||
(byte) data,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
return new SpecialCachedValue(vd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + '[' + formatValue() + ']';
|
||||
}
|
||||
|
||||
public int getValueType() {
|
||||
int typeCode = getTypeCode();
|
||||
switch (typeCode) {
|
||||
case STRING: return CellType.STRING.getCode();
|
||||
case BOOLEAN: return CellType.BOOLEAN.getCode();
|
||||
case ERROR_CODE: return CellType.ERROR.getCode();
|
||||
case EMPTY: return CellType.STRING.getCode(); // is this correct?
|
||||
}
|
||||
throw new IllegalStateException("Unexpected type id (" + typeCode + ")");
|
||||
}
|
||||
|
||||
public boolean getBooleanValue() {
|
||||
if (getTypeCode() != BOOLEAN) {
|
||||
throw new IllegalStateException("Not a boolean cached value - " + formatValue());
|
||||
}
|
||||
return getDataValue() != 0;
|
||||
}
|
||||
|
||||
public int getErrorValue() {
|
||||
if (getTypeCode() != ERROR_CODE) {
|
||||
throw new IllegalStateException("Not an error cached value - " + formatValue());
|
||||
}
|
||||
return getDataValue();
|
||||
}
|
||||
}
|
||||
|
||||
private double field_4_value;
|
||||
private short field_5_options;
|
||||
/**
|
||||
|
@ -193,19 +53,27 @@ public final class FormulaRecord extends CellRecord implements Cloneable {
|
|||
/**
|
||||
* Since the NaN support seems sketchy (different constants) we'll store and spit it out directly
|
||||
*/
|
||||
private SpecialCachedValue specialCachedValue;
|
||||
private FormulaSpecialCachedValue specialCachedValue;
|
||||
|
||||
/** Creates new FormulaRecord */
|
||||
|
||||
public FormulaRecord() {
|
||||
field_8_parsed_expr = Formula.create(Ptg.EMPTY_PTG_ARRAY);
|
||||
}
|
||||
|
||||
public FormulaRecord(FormulaRecord other) {
|
||||
super(other);
|
||||
field_4_value = other.field_4_value;
|
||||
field_5_options = other.field_5_options;
|
||||
field_6_zero = other.field_6_zero;
|
||||
field_8_parsed_expr = (other.field_8_parsed_expr == null) ? null : new Formula(other.field_8_parsed_expr);
|
||||
specialCachedValue = (other.specialCachedValue == null) ? null : new FormulaSpecialCachedValue(other.specialCachedValue);
|
||||
}
|
||||
|
||||
public FormulaRecord(RecordInputStream ris) {
|
||||
super(ris);
|
||||
long valueLongBits = ris.readLong();
|
||||
field_5_options = ris.readShort();
|
||||
specialCachedValue = SpecialCachedValue.create(valueLongBits);
|
||||
specialCachedValue = FormulaSpecialCachedValue.create(valueLongBits);
|
||||
if (specialCachedValue == null) {
|
||||
field_4_value = Double.longBitsToDouble(valueLongBits);
|
||||
}
|
||||
|
@ -228,16 +96,16 @@ public final class FormulaRecord extends CellRecord implements Cloneable {
|
|||
}
|
||||
|
||||
public void setCachedResultTypeEmptyString() {
|
||||
specialCachedValue = SpecialCachedValue.createCachedEmptyValue();
|
||||
specialCachedValue = FormulaSpecialCachedValue.createCachedEmptyValue();
|
||||
}
|
||||
public void setCachedResultTypeString() {
|
||||
specialCachedValue = SpecialCachedValue.createForString();
|
||||
specialCachedValue = FormulaSpecialCachedValue.createForString();
|
||||
}
|
||||
public void setCachedResultErrorCode(int errorCode) {
|
||||
specialCachedValue = SpecialCachedValue.createCachedErrorCode(errorCode);
|
||||
specialCachedValue = FormulaSpecialCachedValue.createCachedErrorCode(errorCode);
|
||||
}
|
||||
public void setCachedResultBoolean(boolean value) {
|
||||
specialCachedValue = SpecialCachedValue.createCachedBoolean(value);
|
||||
specialCachedValue = FormulaSpecialCachedValue.createCachedBoolean(value);
|
||||
}
|
||||
/**
|
||||
* @return <code>true</code> if this {@link FormulaRecord} is followed by a
|
||||
|
@ -246,7 +114,7 @@ public final class FormulaRecord extends CellRecord implements Cloneable {
|
|||
*/
|
||||
public boolean hasCachedResultString() {
|
||||
return specialCachedValue != null &&
|
||||
specialCachedValue.getTypeCode() == SpecialCachedValue.STRING;
|
||||
specialCachedValue.getTypeCode() == FormulaSpecialCachedValue.STRING;
|
||||
}
|
||||
|
||||
public int getCachedResultType() {
|
||||
|
@ -353,12 +221,12 @@ public final class FormulaRecord extends CellRecord implements Cloneable {
|
|||
out.writeInt(field_6_zero); // may as well write original data back so as to minimise differences from original
|
||||
field_8_parsed_expr.serialize(out);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getRecordName() {
|
||||
return "FORMULA";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void appendValueText(StringBuilder sb) {
|
||||
sb.append(" .value = ");
|
||||
|
@ -385,15 +253,16 @@ public final class FormulaRecord extends CellRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FormulaRecord clone() {
|
||||
FormulaRecord rec = new FormulaRecord();
|
||||
copyBaseFields(rec);
|
||||
rec.field_4_value = field_4_value;
|
||||
rec.field_5_options = field_5_options;
|
||||
rec.field_6_zero = field_6_zero;
|
||||
rec.field_8_parsed_expr = field_8_parsed_expr;
|
||||
rec.specialCachedValue = specialCachedValue;
|
||||
return rec;
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FormulaRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FormulaRecord copy() {
|
||||
return new FormulaRecord(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/* ====================================================================
|
||||
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.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* Manages the cached formula result values of other types besides numeric.
|
||||
* Excel encodes the same 8 bytes that would be field_4_value with various NaN
|
||||
* values that are decoded/encoded by this class.
|
||||
*/
|
||||
@Internal
|
||||
public final class FormulaSpecialCachedValue {
|
||||
/** deliberately chosen by Excel in order to encode other values within Double NaNs */
|
||||
private static final long BIT_MARKER = 0xFFFF000000000000L;
|
||||
private static final int VARIABLE_DATA_LENGTH = 6;
|
||||
private static final int DATA_INDEX = 2;
|
||||
|
||||
// FIXME: can these be merged with {@link CellType}?
|
||||
// are the numbers specific to the HSSF formula record format or just a poor-man's enum?
|
||||
public static final int STRING = 0;
|
||||
public static final int BOOLEAN = 1;
|
||||
public static final int ERROR_CODE = 2;
|
||||
public static final int EMPTY = 3;
|
||||
|
||||
private final byte[] _variableData;
|
||||
|
||||
FormulaSpecialCachedValue(FormulaSpecialCachedValue other) {
|
||||
_variableData = (other._variableData == null) ? null : other._variableData.clone();
|
||||
}
|
||||
|
||||
private FormulaSpecialCachedValue(byte[] data) {
|
||||
_variableData = data;
|
||||
}
|
||||
|
||||
public int getTypeCode() {
|
||||
return _variableData[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if the double value encoded by <tt>valueLongBits</tt>
|
||||
* is a normal (non NaN) double value.
|
||||
*/
|
||||
public static FormulaSpecialCachedValue create(long valueLongBits) {
|
||||
if ((BIT_MARKER & valueLongBits) != BIT_MARKER) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] result = new byte[VARIABLE_DATA_LENGTH];
|
||||
long x = valueLongBits;
|
||||
for (int i=0; i<VARIABLE_DATA_LENGTH; i++) {
|
||||
result[i] = (byte) x;
|
||||
x >>= 8;
|
||||
}
|
||||
switch (result[0]) {
|
||||
case STRING:
|
||||
case BOOLEAN:
|
||||
case ERROR_CODE:
|
||||
case EMPTY:
|
||||
break;
|
||||
default:
|
||||
throw new org.apache.poi.util.RecordFormatException("Bad special value code (" + result[0] + ")");
|
||||
}
|
||||
return new FormulaSpecialCachedValue(result);
|
||||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
out.write(_variableData);
|
||||
out.writeShort(0xFFFF);
|
||||
}
|
||||
|
||||
public String formatDebugString() {
|
||||
return formatValue() + ' ' + HexDump.toHex(_variableData);
|
||||
}
|
||||
|
||||
private String formatValue() {
|
||||
int typeCode = getTypeCode();
|
||||
switch (typeCode) {
|
||||
case STRING:
|
||||
return "<string>";
|
||||
case BOOLEAN:
|
||||
return getDataValue() == 0 ? "FALSE" : "TRUE";
|
||||
case ERROR_CODE:
|
||||
return ErrorEval.getText(getDataValue());
|
||||
case EMPTY:
|
||||
return "<empty>";
|
||||
}
|
||||
return "#error(type=" + typeCode + ")#";
|
||||
}
|
||||
|
||||
private int getDataValue() {
|
||||
return _variableData[DATA_INDEX];
|
||||
}
|
||||
|
||||
public static FormulaSpecialCachedValue createCachedEmptyValue() {
|
||||
return create(EMPTY, 0);
|
||||
}
|
||||
|
||||
public static FormulaSpecialCachedValue createForString() {
|
||||
return create(STRING, 0);
|
||||
}
|
||||
|
||||
public static FormulaSpecialCachedValue createCachedBoolean(boolean b) {
|
||||
return create(BOOLEAN, b ? 1 : 0);
|
||||
}
|
||||
|
||||
public static FormulaSpecialCachedValue createCachedErrorCode(int errorCode) {
|
||||
return create(ERROR_CODE, errorCode);
|
||||
}
|
||||
|
||||
private static FormulaSpecialCachedValue create(int code, int data) {
|
||||
byte[] vd = { (byte) code, 0, (byte) data, 0, 0, 0, };
|
||||
return new FormulaSpecialCachedValue(vd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + '[' + formatValue() + ']';
|
||||
}
|
||||
|
||||
public int getValueType() {
|
||||
int typeCode = getTypeCode();
|
||||
switch (typeCode) {
|
||||
case EMPTY: // is this correct?
|
||||
case STRING:
|
||||
return CellType.STRING.getCode();
|
||||
case BOOLEAN:
|
||||
return CellType.BOOLEAN.getCode();
|
||||
case ERROR_CODE:
|
||||
return CellType.ERROR.getCode();
|
||||
}
|
||||
throw new IllegalStateException("Unexpected type id (" + typeCode + ")");
|
||||
}
|
||||
|
||||
public boolean getBooleanValue() {
|
||||
if (getTypeCode() != BOOLEAN) {
|
||||
throw new IllegalStateException("Not a boolean cached value - " + formatValue());
|
||||
}
|
||||
return getDataValue() != 0;
|
||||
}
|
||||
|
||||
public int getErrorValue() {
|
||||
if (getTypeCode() != ERROR_CODE) {
|
||||
throw new IllegalStateException("Not an error cached value - " + formatValue());
|
||||
}
|
||||
return getDataValue();
|
||||
}
|
||||
}
|
|
@ -22,28 +22,31 @@ import org.apache.poi.util.IOUtils;
|
|||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
|
||||
/**
|
||||
* This structure appears as part of an Obj record that represents a checkbox or radio button.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class FtCblsSubRecord extends SubRecord implements Cloneable {
|
||||
public final static short sid = 0x0C;
|
||||
public final class FtCblsSubRecord extends SubRecord {
|
||||
public static final short sid = 0x0C;
|
||||
private static final int ENCODED_SIZE = 20;
|
||||
|
||||
private byte[] reserved;
|
||||
private final byte[] reserved;
|
||||
|
||||
/**
|
||||
* Construct a new <code>FtCblsSubRecord</code> and
|
||||
* fill its data with the default values
|
||||
*/
|
||||
public FtCblsSubRecord()
|
||||
{
|
||||
public FtCblsSubRecord() {
|
||||
reserved = new byte[ENCODED_SIZE];
|
||||
}
|
||||
|
||||
public FtCblsSubRecord(FtCblsSubRecord other) {
|
||||
super(other);
|
||||
reserved = other.reserved.clone();
|
||||
}
|
||||
|
||||
public FtCblsSubRecord(LittleEndianInput in, int size) {
|
||||
if (size != ENCODED_SIZE) {
|
||||
throw new RecordFormatException("Unexpected size (" + size + ")");
|
||||
|
@ -93,12 +96,16 @@ public final class FtCblsSubRecord extends SubRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FtCblsSubRecord clone() {
|
||||
FtCblsSubRecord rec = new FtCblsSubRecord();
|
||||
byte[] recdata = new byte[reserved.length];
|
||||
System.arraycopy(reserved, 0, recdata, 0, recdata.length);
|
||||
rec.reserved = recdata;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtCblsSubRecord copy() {
|
||||
return new FtCblsSubRecord(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,15 +21,16 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
|
||||
/**
|
||||
* The FtCf structure specifies the clipboard format of the picture-type Obj record containing this FtCf.
|
||||
*/
|
||||
public final class FtCfSubRecord extends SubRecord implements Cloneable {
|
||||
public final static short sid = 0x07;
|
||||
public final static short length = 0x02;
|
||||
|
||||
public final class FtCfSubRecord extends SubRecord {
|
||||
public static final short sid = 0x07;
|
||||
public static final short length = 0x02;
|
||||
|
||||
/**
|
||||
* Specifies the format of the picture is an enhanced metafile.
|
||||
*/
|
||||
|
@ -39,20 +40,24 @@ public final class FtCfSubRecord extends SubRecord implements Cloneable {
|
|||
* Specifies the format of the picture is a bitmap.
|
||||
*/
|
||||
public static final short BITMAP_BIT = (short)0x0009;
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the picture is in an unspecified format that is
|
||||
* neither and enhanced metafile nor a bitmap.
|
||||
*/
|
||||
public static final short UNSPECIFIED_BIT = (short)0xFFFF;
|
||||
|
||||
|
||||
private short flags;
|
||||
|
||||
/**
|
||||
* Construct a new <code>FtPioGrbitSubRecord</code> and
|
||||
* fill its data with the default values
|
||||
*/
|
||||
public FtCfSubRecord() {
|
||||
public FtCfSubRecord() {}
|
||||
|
||||
public FtCfSubRecord(FtCfSubRecord other) {
|
||||
super(other);
|
||||
flags = other.flags;
|
||||
}
|
||||
|
||||
public FtCfSubRecord(LittleEndianInput in, int size) {
|
||||
|
@ -99,10 +104,16 @@ public final class FtCfSubRecord extends SubRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FtCfSubRecord clone() {
|
||||
FtCfSubRecord rec = new FtCfSubRecord();
|
||||
rec.flags = this.flags;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtCfSubRecord copy() {
|
||||
return new FtCfSubRecord(this);
|
||||
}
|
||||
|
||||
public short getFlags() {
|
||||
|
|
|
@ -21,27 +21,28 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
|
||||
/**
|
||||
* This structure appears as part of an Obj record that represents image display properties.
|
||||
*/
|
||||
public final class FtPioGrbitSubRecord extends SubRecord implements Cloneable {
|
||||
public final static short sid = 0x08;
|
||||
public final static short length = 0x02;
|
||||
|
||||
public final class FtPioGrbitSubRecord extends SubRecord {
|
||||
public static final short sid = 0x08;
|
||||
public static final short length = 0x02;
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the picture's aspect ratio is preserved when rendered in
|
||||
* A bit that specifies whether the picture's aspect ratio is preserved when rendered in
|
||||
* different views (Normal view, Page Break Preview view, Page Layout view and printing).
|
||||
*/
|
||||
public static final int AUTO_PICT_BIT = 1 << 0;
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the pictFmla field of the Obj record that contains
|
||||
* A bit that specifies whether the pictFmla field of the Obj record that contains
|
||||
* this FtPioGrbit specifies a DDE reference.
|
||||
*/
|
||||
public static final int DDE_BIT = 1 << 1;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether this object is expected to be updated on print to
|
||||
* reflect the values in the cell associated with the object.
|
||||
|
@ -52,44 +53,48 @@ public final class FtPioGrbitSubRecord extends SubRecord implements Cloneable {
|
|||
* A bit that specifies whether the picture is displayed as an icon.
|
||||
*/
|
||||
public static final int ICON_BIT = 1 << 3;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether this object is an ActiveX control.
|
||||
* It MUST NOT be the case that both fCtl and fDde are equal to 1.
|
||||
*/
|
||||
public static final int CTL_BIT = 1 << 4;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the object data are stored in an
|
||||
* embedding storage (= 0) or in the controls stream (ctls) (= 1).
|
||||
*/
|
||||
public static final int PRSTM_BIT = 1 << 5;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether this is a camera picture.
|
||||
*/
|
||||
public static final int CAMERA_BIT = 1 << 7;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether this picture's size has been explicitly set.
|
||||
* 0 = picture size has been explicitly set, 1 = has not been set
|
||||
*/
|
||||
public static final int DEFAULT_SIZE_BIT = 1 << 8;
|
||||
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the OLE server for the object is called
|
||||
* to load the object's data automatically when the parent workbook is opened.
|
||||
*/
|
||||
public static final int AUTO_LOAD_BIT = 1 << 9;
|
||||
|
||||
|
||||
|
||||
private short flags;
|
||||
|
||||
/**
|
||||
* Construct a new <code>FtPioGrbitSubRecord</code> and
|
||||
* fill its data with the default values
|
||||
*/
|
||||
public FtPioGrbitSubRecord() {
|
||||
public FtPioGrbitSubRecord() {}
|
||||
|
||||
public FtPioGrbitSubRecord(FtPioGrbitSubRecord other) {
|
||||
super(other);
|
||||
flags = other.flags;
|
||||
}
|
||||
|
||||
public FtPioGrbitSubRecord(LittleEndianInput in, int size) {
|
||||
|
@ -110,12 +115,12 @@ public final class FtPioGrbitSubRecord extends SubRecord implements Cloneable {
|
|||
} else {
|
||||
flags &= (0xFFFF ^ bitmask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean getFlagByBit(int bitmask) {
|
||||
return ((flags & bitmask) != 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert this record to string.
|
||||
* Used by BiffViewer and other utilities.
|
||||
|
@ -153,10 +158,16 @@ public final class FtPioGrbitSubRecord extends SubRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public FtPioGrbitSubRecord clone() {
|
||||
FtPioGrbitSubRecord rec = new FtPioGrbitSubRecord();
|
||||
rec.flags = this.flags;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FtPioGrbitSubRecord copy() {
|
||||
return new FtPioGrbitSubRecord(this);
|
||||
}
|
||||
|
||||
public short getFlags() {
|
||||
|
|
|
@ -18,28 +18,25 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Gridset Record.<P>
|
||||
* Description: flag denoting whether the user specified that gridlines are used when
|
||||
* printing.<P>
|
||||
* REFERENCE: PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
*
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Flag denoting whether the user specified that gridlines are used when printing.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
public final class GridsetRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x82;
|
||||
public final class GridsetRecord extends StandardRecord {
|
||||
public static final short sid = 0x82;
|
||||
public short field_1_gridset_flag;
|
||||
|
||||
public GridsetRecord() {
|
||||
public GridsetRecord() {}
|
||||
|
||||
public GridsetRecord(GridsetRecord other) {
|
||||
super(other);
|
||||
field_1_gridset_flag = other.field_1_gridset_flag;
|
||||
}
|
||||
|
||||
public GridsetRecord(RecordInputStream in)
|
||||
{
|
||||
public GridsetRecord(RecordInputStream in) {
|
||||
field_1_gridset_flag = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -87,9 +84,15 @@ public final class GridsetRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public GridsetRecord clone() {
|
||||
GridsetRecord rec = new GridsetRecord();
|
||||
rec.field_1_gridset_flag = field_1_gridset_flag;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GridsetRecord copy() {
|
||||
return new GridsetRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,14 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* ftGmo (0x0006)<p>
|
||||
* The group marker record is used as a position holder for groups.
|
||||
*/
|
||||
public final class GroupMarkerSubRecord extends SubRecord implements Cloneable {
|
||||
public final static short sid = 0x0006;
|
||||
public final class GroupMarkerSubRecord extends SubRecord {
|
||||
public static final short sid = 0x0006;
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
||||
|
@ -41,6 +42,11 @@ public final class GroupMarkerSubRecord extends SubRecord implements Cloneable {
|
|||
reserved = EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
public GroupMarkerSubRecord(GroupMarkerSubRecord other) {
|
||||
super(other);
|
||||
reserved = other.reserved.clone();
|
||||
}
|
||||
|
||||
public GroupMarkerSubRecord(LittleEndianInput in, int size) {
|
||||
byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
|
||||
in.readFully(buf);
|
||||
|
@ -74,10 +80,15 @@ public final class GroupMarkerSubRecord extends SubRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public GroupMarkerSubRecord clone() {
|
||||
GroupMarkerSubRecord rec = new GroupMarkerSubRecord();
|
||||
rec.reserved = new byte[reserved.length];
|
||||
System.arraycopy(reserved, 0, rec.reserved, 0, reserved.length);
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupMarkerSubRecord copy() {
|
||||
return new GroupMarkerSubRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,34 +15,41 @@
|
|||
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.Removal;
|
||||
|
||||
/**
|
||||
* Title: Guts Record <P>
|
||||
* Description: Row/column gutter sizes <P>
|
||||
* REFERENCE: PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Row/column gutter sizes
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class GutsRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x80;
|
||||
private short field_1_left_row_gutter; // size of the row gutter to the left of the rows
|
||||
private short field_2_top_col_gutter; // size of the column gutter above the columns
|
||||
private short field_3_row_level_max; // maximum outline level for row gutters
|
||||
private short field_4_col_level_max; // maximum outline level for column gutters
|
||||
public final class GutsRecord extends StandardRecord {
|
||||
public static final short sid = 0x80;
|
||||
/** size of the row gutter to the left of the rows */
|
||||
private short field_1_left_row_gutter;
|
||||
/** size of the column gutter above the columns */
|
||||
private short field_2_top_col_gutter;
|
||||
/** maximum outline level for row gutters */
|
||||
private short field_3_row_level_max;
|
||||
/** maximum outline level for column gutters */
|
||||
private short field_4_col_level_max;
|
||||
|
||||
public GutsRecord()
|
||||
{
|
||||
public GutsRecord() {}
|
||||
|
||||
public GutsRecord(GutsRecord other) {
|
||||
super(other);
|
||||
field_1_left_row_gutter = other.field_1_left_row_gutter;
|
||||
field_2_top_col_gutter = other.field_2_top_col_gutter;
|
||||
field_3_row_level_max = other.field_3_row_level_max;
|
||||
field_4_col_level_max = other.field_4_col_level_max;
|
||||
}
|
||||
|
||||
public GutsRecord(RecordInputStream in)
|
||||
{
|
||||
public GutsRecord(RecordInputStream in) {
|
||||
field_1_left_row_gutter = in.readShort();
|
||||
field_2_top_col_gutter = in.readShort();
|
||||
field_3_row_level_max = in.readShort();
|
||||
|
@ -171,12 +178,15 @@ public final class GutsRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public GutsRecord clone() {
|
||||
GutsRecord rec = new GutsRecord();
|
||||
rec.field_1_left_row_gutter = field_1_left_row_gutter;
|
||||
rec.field_2_top_col_gutter = field_2_top_col_gutter;
|
||||
rec.field_3_row_level_max = field_3_row_level_max;
|
||||
rec.field_4_col_level_max = field_4_col_level_max;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GutsRecord copy() {
|
||||
return new GutsRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,24 +17,25 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: HCenter record (0x0083)<P>
|
||||
* Description: whether to center between horizontal margins<P>
|
||||
* REFERENCE: PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Whether to center between horizontal margins
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
public final class HCenterRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x0083;
|
||||
private short field_1_hcenter;
|
||||
public final class HCenterRecord extends StandardRecord {
|
||||
public static final short sid = 0x0083;
|
||||
private short field_1_hcenter;
|
||||
|
||||
public HCenterRecord() {
|
||||
public HCenterRecord() {}
|
||||
|
||||
public HCenterRecord(HCenterRecord other) {
|
||||
super(other);
|
||||
field_1_hcenter = other.field_1_hcenter;
|
||||
}
|
||||
|
||||
public HCenterRecord(RecordInputStream in)
|
||||
{
|
||||
public HCenterRecord(RecordInputStream in) {
|
||||
field_1_hcenter = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -43,11 +44,7 @@ public final class HCenterRecord extends StandardRecord implements Cloneable {
|
|||
* @param hc center - t/f
|
||||
*/
|
||||
public void setHCenter(boolean hc) {
|
||||
if (hc) {
|
||||
field_1_hcenter = 1;
|
||||
} else {
|
||||
field_1_hcenter = 0;
|
||||
}
|
||||
field_1_hcenter = (short)(hc ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,9 +77,15 @@ public final class HCenterRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public HCenterRecord clone() {
|
||||
HCenterRecord rec = new HCenterRecord();
|
||||
rec.field_1_hcenter = field_1_hcenter;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HCenterRecord copy() {
|
||||
return new HCenterRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ import org.apache.poi.util.StringUtil;
|
|||
|
||||
/**
|
||||
* Common header/footer base class
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public abstract class HeaderFooterBase extends StandardRecord {
|
||||
private boolean field_2_hasMultibyte;
|
||||
|
@ -33,6 +31,12 @@ public abstract class HeaderFooterBase extends StandardRecord {
|
|||
setText(text);
|
||||
}
|
||||
|
||||
protected HeaderFooterBase(HeaderFooterBase other) {
|
||||
super(other);
|
||||
field_2_hasMultibyte = other.field_2_hasMultibyte;
|
||||
field_3_text = other.field_3_text;
|
||||
}
|
||||
|
||||
protected HeaderFooterBase(RecordInputStream in) {
|
||||
if (in.remaining() > 0) {
|
||||
int field_1_footer_len = in.readShort();
|
||||
|
@ -107,4 +111,7 @@ public abstract class HeaderFooterBase extends StandardRecord {
|
|||
}
|
||||
return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract HeaderFooterBase copy();
|
||||
}
|
||||
|
|
|
@ -17,28 +17,31 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* The HEADERFOOTER record stores information added in Office Excel 2007 for headers/footers.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class HeaderFooterRecord extends StandardRecord implements Cloneable {
|
||||
|
||||
public final class HeaderFooterRecord extends StandardRecord {
|
||||
public static final short sid = 0x089C;
|
||||
private static final byte[] BLANK_GUID = new byte[16];
|
||||
|
||||
public final static short sid = 0x089C;
|
||||
private byte[] _rawData;
|
||||
|
||||
public HeaderFooterRecord(byte[] data) {
|
||||
_rawData = data;
|
||||
}
|
||||
|
||||
public HeaderFooterRecord(HeaderFooterRecord other) {
|
||||
super(other);
|
||||
_rawData = (other._rawData == null) ? null : other._rawData.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* construct a HeaderFooterRecord record. No fields are interpreted and the record will
|
||||
* be serialized in its original form more or less
|
||||
|
@ -58,7 +61,7 @@ public final class HeaderFooterRecord extends StandardRecord implements Cloneabl
|
|||
protected int getDataSize() {
|
||||
return _rawData.length;
|
||||
}
|
||||
|
||||
|
||||
public short getSid()
|
||||
{
|
||||
return sid;
|
||||
|
@ -79,7 +82,7 @@ public final class HeaderFooterRecord extends StandardRecord implements Cloneabl
|
|||
}
|
||||
|
||||
/**
|
||||
* @return whether this record belongs to the current sheet
|
||||
* @return whether this record belongs to the current sheet
|
||||
*/
|
||||
public boolean isCurrentSheet(){
|
||||
return Arrays.equals(getGuid(), BLANK_GUID);
|
||||
|
@ -96,10 +99,17 @@ public final class HeaderFooterRecord extends StandardRecord implements Cloneabl
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public HeaderFooterRecord clone() {
|
||||
//HACK: do a "cheat" clone, see Record.java for more information
|
||||
return (HeaderFooterRecord)cloneViaReserialise();
|
||||
return copy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public HeaderFooterRecord copy() {
|
||||
return new HeaderFooterRecord(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -17,21 +17,22 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Header Record<P>
|
||||
* Description: Specifies a header for a sheet<P>
|
||||
* REFERENCE: PG 321 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* @author Shawn Laubach (slaubach at apache dot org) Modified 3/14/02
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* Specifies a header for a sheet
|
||||
*/
|
||||
public final class HeaderRecord extends HeaderFooterBase implements Cloneable {
|
||||
public final static short sid = 0x0014;
|
||||
public final class HeaderRecord extends HeaderFooterBase {
|
||||
public static final short sid = 0x0014;
|
||||
|
||||
public HeaderRecord(String text) {
|
||||
super(text);
|
||||
}
|
||||
|
||||
public HeaderRecord(HeaderRecord other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public HeaderRecord(RecordInputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
@ -50,7 +51,15 @@ public final class HeaderRecord extends HeaderFooterBase implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public HeaderRecord clone() {
|
||||
return new HeaderRecord(getText());
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeaderRecord copy() {
|
||||
return new HeaderRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,35 +15,33 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: Hide Object Record<P>
|
||||
* Description: flag defines whether to hide placeholders and object<P>
|
||||
* REFERENCE: PG 321 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* Flag defines whether to hide placeholders and object
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
public final class HideObjRecord extends StandardRecord {
|
||||
public static final short sid = 0x8d;
|
||||
public static final short HIDE_ALL = 2;
|
||||
public static final short SHOW_PLACEHOLDERS = 1;
|
||||
public static final short SHOW_ALL = 0;
|
||||
|
||||
public final class HideObjRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0x8d;
|
||||
public final static short HIDE_ALL = 2;
|
||||
public final static short SHOW_PLACEHOLDERS = 1;
|
||||
public final static short SHOW_ALL = 0;
|
||||
private short field_1_hide_obj;
|
||||
private short field_1_hide_obj;
|
||||
|
||||
public HideObjRecord()
|
||||
{
|
||||
public HideObjRecord() {}
|
||||
|
||||
public HideObjRecord(HideObjRecord other) {
|
||||
super(other);
|
||||
field_1_hide_obj = other.field_1_hide_obj;
|
||||
}
|
||||
|
||||
public HideObjRecord(RecordInputStream in)
|
||||
{
|
||||
public HideObjRecord(RecordInputStream in) {
|
||||
field_1_hide_obj = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -98,4 +96,9 @@ public final class HideObjRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HideObjRecord copy() {
|
||||
return new HideObjRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,21 +17,24 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Iterator;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* HorizontalPageBreak (0x001B) record that stores page breaks at rows
|
||||
*
|
||||
*
|
||||
* @see PageBreakRecord
|
||||
*/
|
||||
public final class HorizontalPageBreakRecord extends PageBreakRecord implements Cloneable {
|
||||
public final class HorizontalPageBreakRecord extends PageBreakRecord {
|
||||
|
||||
public static final short sid = 0x001B;
|
||||
|
||||
/**
|
||||
* Creates an empty horizontal page break record
|
||||
*/
|
||||
public HorizontalPageBreakRecord() {
|
||||
public HorizontalPageBreakRecord() {}
|
||||
|
||||
public HorizontalPageBreakRecord(HorizontalPageBreakRecord other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,13 +49,15 @@ public final class HorizontalPageBreakRecord extends PageBreakRecord implements
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public PageBreakRecord clone() {
|
||||
PageBreakRecord result = new HorizontalPageBreakRecord();
|
||||
Iterator<Break> iterator = getBreaksIterator();
|
||||
while (iterator.hasNext()) {
|
||||
Break original = iterator.next();
|
||||
result.addBreak(original.main, original.subFrom, original.subTo);
|
||||
}
|
||||
return result;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HorizontalPageBreakRecord copy() {
|
||||
return new HorizontalPageBreakRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
@ -34,13 +35,14 @@ import org.apache.poi.util.StringUtil;
|
|||
* from the Excel-97 format.
|
||||
* Supports only external links for now (eg http://)
|
||||
*/
|
||||
public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x01B8;
|
||||
public final class HyperlinkRecord extends StandardRecord {
|
||||
public static final short sid = 0x01B8;
|
||||
private static POILogger logger = POILogFactory.getLogger(HyperlinkRecord.class);
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
||||
|
||||
// TODO: replace with ClassID
|
||||
static final class GUID {
|
||||
/*
|
||||
* this class is currently only used here, but could be moved to a
|
||||
|
@ -61,6 +63,13 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
*/
|
||||
private final long _d4;
|
||||
|
||||
public GUID(GUID other) {
|
||||
_d1 = other._d1;
|
||||
_d2 = other._d2;
|
||||
_d3 = other._d3;
|
||||
_d4 = other._d4;
|
||||
}
|
||||
|
||||
public GUID(LittleEndianInput in) {
|
||||
this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
|
||||
}
|
||||
|
@ -199,24 +208,24 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Link flags
|
||||
*/
|
||||
static final int HLINK_URL = 0x01; // File link or URL.
|
||||
static final int HLINK_ABS = 0x02; // Absolute path.
|
||||
static final int HLINK_LABEL = 0x14; // Has label/description.
|
||||
static final int HLINK_URL = 0x01; // File link or URL.
|
||||
static final int HLINK_ABS = 0x02; // Absolute path.
|
||||
static final int HLINK_LABEL = 0x14; // Has label/description.
|
||||
/** Place in worksheet. If set, the {@link #_textMark} field will be present */
|
||||
static final int HLINK_PLACE = 0x08;
|
||||
static final int HLINK_PLACE = 0x08;
|
||||
private static final int HLINK_TARGET_FRAME = 0x80; // has 'target frame'
|
||||
private static final int HLINK_UNC_PATH = 0x100; // has UNC path
|
||||
|
||||
final static GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B");
|
||||
final static GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B");
|
||||
final static GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046");
|
||||
static final GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B");
|
||||
static final GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B");
|
||||
static final GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046");
|
||||
/** expected Tail of a URL link */
|
||||
private final static byte[] URL_TAIL = HexRead.readFromString("79 58 81 F4 3B 1D 7F 48 AF 2C 82 5D C4 85 27 63 00 00 00 00 A5 AB 00 00");
|
||||
private static final byte[] URL_TAIL = HexRead.readFromString("79 58 81 F4 3B 1D 7F 48 AF 2C 82 5D C4 85 27 63 00 00 00 00 A5 AB 00 00");
|
||||
/** expected Tail of a file link */
|
||||
private final static byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00");
|
||||
private static final byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00");
|
||||
|
||||
private static final int TAIL_SIZE = FILE_TAIL.length;
|
||||
|
||||
|
@ -246,17 +255,31 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
* This field is optional. If present, the {@link #HLINK_PLACE} must be set.
|
||||
*/
|
||||
private String _textMark;
|
||||
|
||||
|
||||
private byte[] _uninterpretedTail;
|
||||
|
||||
/**
|
||||
* Create a new hyperlink
|
||||
*/
|
||||
public HyperlinkRecord()
|
||||
{
|
||||
public HyperlinkRecord() {}
|
||||
|
||||
|
||||
public HyperlinkRecord(HyperlinkRecord other) {
|
||||
super(other);
|
||||
_range = (other._range == null) ? null : other._range.copy();
|
||||
_guid = (other._guid == null) ? null : new GUID(other._guid);
|
||||
_fileOpts = other._fileOpts;
|
||||
_linkOpts = other._linkOpts;
|
||||
_label = other._label;
|
||||
_targetFrame = other._targetFrame;
|
||||
_moniker = (other._moniker == null) ? null : new GUID(other._moniker);
|
||||
_shortFilename = other._shortFilename;
|
||||
_address = other._address;
|
||||
_textMark = other._textMark;
|
||||
_uninterpretedTail = (other._uninterpretedTail == null) ? null : other._uninterpretedTail.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the 0-based column of the first cell that contains this hyperlink
|
||||
*/
|
||||
|
@ -266,7 +289,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Set the first column (zero-based) of the range that contains this hyperlink
|
||||
*
|
||||
*
|
||||
* @param firstCol the first column (zero-based)
|
||||
*/
|
||||
public void setFirstColumn(int firstCol) {
|
||||
|
@ -282,7 +305,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Set the last column (zero-based) of the range that contains this hyperlink
|
||||
*
|
||||
*
|
||||
* @param lastCol the last column (zero-based)
|
||||
*/
|
||||
public void setLastColumn(int lastCol) {
|
||||
|
@ -298,7 +321,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Set the first row (zero-based) of the range that contains this hyperlink
|
||||
*
|
||||
*
|
||||
* @param firstRow the first row (zero-based)
|
||||
*/
|
||||
public void setFirstRow(int firstRow) {
|
||||
|
@ -314,7 +337,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Set the last row (zero-based) of the range that contains this hyperlink
|
||||
*
|
||||
*
|
||||
* @param lastRow the last row (zero-based)
|
||||
*/
|
||||
public void setLastRow(int lastRow) {
|
||||
|
@ -423,7 +446,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
/**
|
||||
* Link options. Must be a combination of HLINK_* constants.
|
||||
* For testing only
|
||||
*
|
||||
*
|
||||
* @return Link options
|
||||
*/
|
||||
int getLinkOptions(){
|
||||
|
@ -541,7 +564,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
if (in.remaining() > 0) {
|
||||
logger.log(POILogger.WARN,
|
||||
logger.log(POILogger.WARN,
|
||||
"Hyperlink data remains: " + in.remaining() +
|
||||
" : " +HexDump.toHex(in.readRemainder())
|
||||
);
|
||||
|
@ -699,31 +722,31 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Based on the link options, is this a url?
|
||||
*
|
||||
*
|
||||
* @return true, if this is a url link
|
||||
*/
|
||||
public boolean isUrlLink() {
|
||||
return (_linkOpts & HLINK_URL) > 0
|
||||
return (_linkOpts & HLINK_URL) > 0
|
||||
&& (_linkOpts & HLINK_ABS) > 0;
|
||||
}
|
||||
/**
|
||||
* Based on the link options, is this a file?
|
||||
*
|
||||
*
|
||||
* @return true, if this is a file link
|
||||
*/
|
||||
public boolean isFileLink() {
|
||||
return (_linkOpts & HLINK_URL) > 0
|
||||
return (_linkOpts & HLINK_URL) > 0
|
||||
&& (_linkOpts & HLINK_ABS) == 0;
|
||||
}
|
||||
/**
|
||||
* Based on the link options, is this a document?
|
||||
*
|
||||
*
|
||||
* @return true, if this is a docment link
|
||||
*/
|
||||
public boolean isDocumentLink() {
|
||||
return (_linkOpts & HLINK_PLACE) > 0;
|
||||
return (_linkOpts & HLINK_PLACE) > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a new url link
|
||||
*/
|
||||
|
@ -766,19 +789,15 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public HyperlinkRecord clone() {
|
||||
HyperlinkRecord rec = new HyperlinkRecord();
|
||||
rec._range = _range.copy();
|
||||
rec._guid = _guid;
|
||||
rec._linkOpts = _linkOpts;
|
||||
rec._fileOpts = _fileOpts;
|
||||
rec._label = _label;
|
||||
rec._address = _address;
|
||||
rec._moniker = _moniker;
|
||||
rec._shortFilename = _shortFilename;
|
||||
rec._targetFrame = _targetFrame;
|
||||
rec._textMark = _textMark;
|
||||
rec._uninterpretedTail = _uninterpretedTail;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HyperlinkRecord copy() {
|
||||
return new HyperlinkRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,27 +20,29 @@ package org.apache.poi.hssf.record;
|
|||
import org.apache.poi.util.IntList;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Index Record (0x020B)<p>
|
||||
* Description: Occurs right after BOF, tells you where the DBCELL records are for a sheet
|
||||
* Important for locating cells<p>
|
||||
*
|
||||
* REFERENCE: PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Occurs right after BOF, tells you where the DBCELL records are for a sheet Important for locating cells
|
||||
*/
|
||||
public final class IndexRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x020B;
|
||||
public final class IndexRecord extends StandardRecord {
|
||||
public static final short sid = 0x020B;
|
||||
private int field_2_first_row; // first row on the sheet
|
||||
private int field_3_last_row_add1; // last row
|
||||
private int field_4_zero; // supposed to be zero
|
||||
private IntList field_5_dbcells; // array of offsets to DBCELL records
|
||||
|
||||
public IndexRecord()
|
||||
{
|
||||
public IndexRecord() {}
|
||||
|
||||
public IndexRecord(IndexRecord other) {
|
||||
super(other);
|
||||
field_2_first_row = other.field_2_first_row;
|
||||
field_3_last_row_add1 = other.field_3_last_row_add1;
|
||||
field_4_zero = other.field_4_zero;
|
||||
field_5_dbcells = (other.field_5_dbcells == null) ? null : new IntList(other.field_5_dbcells);
|
||||
}
|
||||
|
||||
public IndexRecord(RecordInputStream in)
|
||||
{
|
||||
public IndexRecord(RecordInputStream in) {
|
||||
int field_1_zero = in.readInt();
|
||||
if (field_1_zero != 0) {
|
||||
throw new RecordFormatException("Expected zero for field 1 but got " + field_1_zero);
|
||||
|
@ -48,7 +50,7 @@ public final class IndexRecord extends StandardRecord implements Cloneable {
|
|||
field_2_first_row = in.readInt();
|
||||
field_3_last_row_add1 = in.readInt();
|
||||
field_4_zero = in.readInt();
|
||||
|
||||
|
||||
int nCells = in.remaining() / 4;
|
||||
field_5_dbcells = new IntList(nCells);
|
||||
for(int i=0; i<nCells; i++) {
|
||||
|
@ -139,14 +141,14 @@ public final class IndexRecord extends StandardRecord implements Cloneable {
|
|||
return 16 // 4 ints
|
||||
+ getNumDbcells() * 4;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* @param blockCount the number of blocks to be indexed
|
||||
* @return the size of an IndexRecord when it needs to index the specified number of blocks
|
||||
*/
|
||||
public static int getRecordSizeForBlockCount(int blockCount) {
|
||||
return 20 + 4 * blockCount;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getSid() {
|
||||
|
@ -154,13 +156,15 @@ public final class IndexRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public IndexRecord clone() {
|
||||
IndexRecord rec = new IndexRecord();
|
||||
rec.field_2_first_row = field_2_first_row;
|
||||
rec.field_3_last_row_add1 = field_3_last_row_add1;
|
||||
rec.field_4_zero = field_4_zero;
|
||||
rec.field_5_dbcells = new IntList();
|
||||
rec.field_5_dbcells.addAll(field_5_dbcells);
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexRecord copy() {
|
||||
return new IndexRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,7 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||
import org.apache.poi.util.RecordFormatException;
|
||||
|
||||
/**
|
||||
* Title: Interface End Record (0x00E2)<P>
|
||||
* Description: Shows where the Interface Records end (MMS)
|
||||
* (has no fields)<P>
|
||||
* REFERENCE: PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* Shows where the Interface Records ends (MMS)
|
||||
*/
|
||||
public final class InterfaceEndRecord extends StandardRecord {
|
||||
|
||||
|
@ -61,4 +57,9 @@ public final class InterfaceEndRecord extends StandardRecord {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceEndRecord copy() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,19 +21,22 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* Title: Interface Header Record (0x00E1)<P>
|
||||
* Description: Defines the beginning of Interface records (MMS)<P>
|
||||
* REFERENCE: PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* Defines the beginning of Interface records (MMS)
|
||||
*/
|
||||
public final class InterfaceHdrRecord extends StandardRecord {
|
||||
public final static short sid = 0x00E1;
|
||||
private final int _codepage;
|
||||
public static final short sid = 0x00E1;
|
||||
|
||||
/**
|
||||
* suggested (and probably correct) default
|
||||
*/
|
||||
public final static int CODEPAGE = 0x04B0;
|
||||
public static final int CODEPAGE = 0x04B0;
|
||||
|
||||
private final int _codepage;
|
||||
|
||||
public InterfaceHdrRecord(InterfaceHdrRecord other) {
|
||||
super(other);
|
||||
_codepage = other._codepage;
|
||||
}
|
||||
|
||||
public InterfaceHdrRecord(int codePage) {
|
||||
_codepage = codePage;
|
||||
|
@ -63,4 +66,9 @@ public final class InterfaceHdrRecord extends StandardRecord {
|
|||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterfaceHdrRecord copy() {
|
||||
return new InterfaceHdrRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,28 +21,30 @@ import org.apache.poi.util.BitField;
|
|||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Iteration Record (0x0011)<p>
|
||||
* Description: Tells whether to iterate over formula calculations or not
|
||||
* (if a formula is dependent upon another formula's result)
|
||||
* (odd feature for something that can only have 32 elements in
|
||||
* a formula!)<p>
|
||||
* REFERENCE: PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Tells whether to iterate over formula calculations or not.
|
||||
* If a formula is dependent upon another formula's result.
|
||||
* (odd feature for something that can only have 32 elements in a formula!)
|
||||
*/
|
||||
public final class IterationRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x0011;
|
||||
public final class IterationRecord extends StandardRecord {
|
||||
public static final short sid = 0x0011;
|
||||
|
||||
private static final BitField iterationOn = BitFieldFactory.getInstance(0x0001);
|
||||
|
||||
private int _flags;
|
||||
|
||||
public IterationRecord(IterationRecord other) {
|
||||
super(other);
|
||||
_flags = other._flags;
|
||||
}
|
||||
|
||||
public IterationRecord(boolean iterateOn) {
|
||||
_flags = iterationOn.setBoolean(0, iterateOn);
|
||||
}
|
||||
|
||||
public IterationRecord(RecordInputStream in)
|
||||
{
|
||||
public IterationRecord(RecordInputStream in) {
|
||||
_flags = in.readShort();
|
||||
}
|
||||
|
||||
|
@ -85,7 +87,15 @@ public final class IterationRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public IterationRecord clone() {
|
||||
return new IterationRecord(getIteration());
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IterationRecord copy() {
|
||||
return new IterationRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,36 +21,43 @@ import org.apache.poi.util.HexDump;
|
|||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Label Record (0x0204) - read only support for strings stored directly in the cell...
|
||||
* Don't use this (except to read), use LabelSST instead <P>
|
||||
* REFERENCE: PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
*
|
||||
* Don't use this (except to read), use LabelSST instead
|
||||
*
|
||||
* @see org.apache.poi.hssf.record.LabelSSTRecord
|
||||
*/
|
||||
public final class LabelRecord extends Record implements CellValueRecordInterface, Cloneable {
|
||||
private final static POILogger logger = POILogFactory.getLogger(LabelRecord.class);
|
||||
public final class LabelRecord extends Record implements CellValueRecordInterface {
|
||||
private static final POILogger logger = POILogFactory.getLogger(LabelRecord.class);
|
||||
|
||||
public final static short sid = 0x0204;
|
||||
public static final short sid = 0x0204;
|
||||
|
||||
private int field_1_row;
|
||||
private short field_2_column;
|
||||
private short field_3_xf_index;
|
||||
private short field_4_string_len;
|
||||
private byte field_5_unicode_flag;
|
||||
private String field_6_value;
|
||||
private int field_1_row;
|
||||
private short field_2_column;
|
||||
private short field_3_xf_index;
|
||||
private short field_4_string_len;
|
||||
private byte field_5_unicode_flag;
|
||||
private String field_6_value;
|
||||
|
||||
/** Creates new LabelRecord */
|
||||
public LabelRecord()
|
||||
{
|
||||
public LabelRecord() {}
|
||||
|
||||
public LabelRecord(LabelRecord other) {
|
||||
super(other);
|
||||
field_1_row = other.field_1_row;
|
||||
field_2_column = other.field_2_column;
|
||||
field_3_xf_index = other.field_3_xf_index;
|
||||
field_4_string_len = other.field_4_string_len;
|
||||
field_5_unicode_flag = other.field_5_unicode_flag;
|
||||
field_6_value = other.field_6_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in the RecordInputstream to read the record from
|
||||
*/
|
||||
public LabelRecord(RecordInputStream in)
|
||||
{
|
||||
public LabelRecord(RecordInputStream in) {
|
||||
field_1_row = in.readUShort();
|
||||
field_2_column = in.readShort();
|
||||
field_3_xf_index = in.readShort();
|
||||
|
@ -182,14 +189,15 @@ public final class LabelRecord extends Record implements CellValueRecordInterfac
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public LabelRecord clone() {
|
||||
LabelRecord rec = new LabelRecord();
|
||||
rec.field_1_row = field_1_row;
|
||||
rec.field_2_column = field_2_column;
|
||||
rec.field_3_xf_index = field_3_xf_index;
|
||||
rec.field_4_string_len = field_4_string_len;
|
||||
rec.field_5_unicode_flag = field_5_unicode_flag;
|
||||
rec.field_6_value = field_6_value;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelRecord copy() {
|
||||
return new LabelRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,18 +19,20 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Label SST Record<P>
|
||||
* Description: Refers to a string in the shared string table and is a column value.<P>
|
||||
* REFERENCE: PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
* Refers to a string in the shared string table and is a column value.
|
||||
*/
|
||||
public final class LabelSSTRecord extends CellRecord implements Cloneable {
|
||||
public final static short sid = 0xfd;
|
||||
public final class LabelSSTRecord extends CellRecord {
|
||||
public static final short sid = 0xfd;
|
||||
private int field_4_sst_index;
|
||||
|
||||
public LabelSSTRecord() {
|
||||
// fields uninitialised
|
||||
public LabelSSTRecord() {}
|
||||
|
||||
public LabelSSTRecord(LabelSSTRecord other) {
|
||||
super(other);
|
||||
field_4_sst_index = other.field_4_sst_index;
|
||||
}
|
||||
|
||||
public LabelSSTRecord(RecordInputStream in) {
|
||||
|
@ -58,7 +60,7 @@ public final class LabelSSTRecord extends CellRecord implements Cloneable {
|
|||
public int getSSTIndex() {
|
||||
return field_4_sst_index;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getRecordName() {
|
||||
return "LABELSST";
|
||||
|
@ -85,10 +87,15 @@ public final class LabelSSTRecord extends CellRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public LabelSSTRecord clone() {
|
||||
LabelSSTRecord rec = new LabelSSTRecord();
|
||||
copyBaseFields(rec);
|
||||
rec.field_4_sst_index = field_4_sst_index;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelSSTRecord copy() {
|
||||
return new LabelSSTRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
==================================================================== */
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.common.Duplicatable;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.RecordFormatException;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
|
@ -89,6 +91,24 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
*/
|
||||
private boolean[] _bsels;
|
||||
|
||||
LbsDataSubRecord() {}
|
||||
|
||||
public LbsDataSubRecord(LbsDataSubRecord other) {
|
||||
super(other);
|
||||
_cbFContinued = other._cbFContinued;
|
||||
_unknownPreFormulaInt = other._unknownPreFormulaInt;
|
||||
_linkPtg = (other._linkPtg == null) ? null : other._linkPtg.copy();
|
||||
_unknownPostFormulaByte = other._unknownPostFormulaByte;
|
||||
_cLines = other._cLines;
|
||||
_iSel = other._iSel;
|
||||
_flags = other._flags;
|
||||
_idEdit = other._idEdit;
|
||||
_dropData = (other._dropData == null) ? null : other._dropData.copy();
|
||||
_rgLines = (other._rgLines == null) ? null : other._rgLines.clone();
|
||||
_bsels = (other._bsels == null) ? null : other._bsels.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param in the stream to read data from
|
||||
* @param cbFContinued the seconf short in the record header
|
||||
|
@ -154,10 +174,6 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
|
||||
}
|
||||
|
||||
LbsDataSubRecord(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return a new instance of LbsDataSubRecord to construct auto-filters
|
||||
|
@ -259,9 +275,16 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public LbsDataSubRecord clone() {
|
||||
// TODO: is immutable ???
|
||||
return this;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LbsDataSubRecord copy() {
|
||||
return new LbsDataSubRecord(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -303,7 +326,7 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
/**
|
||||
* This structure specifies properties of the dropdown list control
|
||||
*/
|
||||
public static class LbsDropData {
|
||||
public static class LbsDropData implements Duplicatable {
|
||||
/**
|
||||
* Combo dropdown control
|
||||
*/
|
||||
|
@ -318,7 +341,7 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
public static final int STYLE_COMBO_SIMPLE_DROPDOWN = 2;
|
||||
|
||||
/**
|
||||
* An unsigned integer that specifies the style of this dropdown.
|
||||
* An unsigned integer that specifies the style of this dropdown.
|
||||
*/
|
||||
private int _wStyle;
|
||||
|
||||
|
@ -343,12 +366,20 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
*/
|
||||
private Byte _unused;
|
||||
|
||||
public LbsDropData(){
|
||||
public LbsDropData() {
|
||||
_str = "";
|
||||
_unused = 0;
|
||||
}
|
||||
|
||||
public LbsDropData(LittleEndianInput in){
|
||||
public LbsDropData(LbsDropData other) {
|
||||
_wStyle = other._wStyle;
|
||||
_cLine = other._cLine;
|
||||
_dxMin = other._dxMin;
|
||||
_str = other._str;
|
||||
_unused = other._unused;
|
||||
}
|
||||
|
||||
public LbsDropData(LittleEndianInput in) {
|
||||
_wStyle = in.readUShort();
|
||||
_cLine = in.readUShort();
|
||||
_dxMin = in.readUShort();
|
||||
|
@ -367,7 +398,7 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
* <li>1: Combo Edit dropdown control</li>
|
||||
* <li>2: Simple dropdown control (just the dropdown button)</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @param style the style - see possible values
|
||||
*/
|
||||
public void setStyle(int style){
|
||||
|
@ -376,7 +407,7 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
|
||||
/**
|
||||
* Set the number of lines to be displayed in the dropdown.
|
||||
*
|
||||
*
|
||||
* @param num the number of lines to be displayed in the dropdown
|
||||
*/
|
||||
public void setNumLines(int num){
|
||||
|
@ -417,5 +448,10 @@ public class LbsDataSubRecord extends SubRecord {
|
|||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LbsDropData copy() {
|
||||
return new LbsDropData(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,18 +18,23 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Record for the left margin.
|
||||
*/
|
||||
public final class LeftMarginRecord extends StandardRecord implements Margin, Cloneable {
|
||||
public final static short sid = 0x0026;
|
||||
public final class LeftMarginRecord extends StandardRecord implements Margin {
|
||||
public static final short sid = 0x0026;
|
||||
private double field_1_margin;
|
||||
|
||||
public LeftMarginRecord() { }
|
||||
public LeftMarginRecord() {}
|
||||
|
||||
public LeftMarginRecord(RecordInputStream in)
|
||||
{
|
||||
public LeftMarginRecord(LeftMarginRecord other) {
|
||||
super(other);
|
||||
field_1_margin = other.field_1_margin;
|
||||
}
|
||||
|
||||
public LeftMarginRecord(RecordInputStream in) {
|
||||
field_1_margin = in.readDouble();
|
||||
}
|
||||
|
||||
|
@ -70,9 +75,15 @@ public final class LeftMarginRecord extends StandardRecord implements Margin, Cl
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public LeftMarginRecord clone() {
|
||||
LeftMarginRecord rec = new LeftMarginRecord();
|
||||
rec.field_1_margin = this.field_1_margin;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeftMarginRecord copy() {
|
||||
return new LeftMarginRecord(this);
|
||||
}
|
||||
}
|
|
@ -15,38 +15,36 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Title: MMS Record<P>
|
||||
* Description: defines how many add menu and del menu options are stored
|
||||
* in the file. Should always be set to 0 for HSSF workbooks<P>
|
||||
* REFERENCE: PG 328 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
|
||||
* @author Andrew C. Oliver (acoliver at apache dot org)
|
||||
* defines how many add menu and del menu options are stored in the file.
|
||||
* Should always be set to 0 for HSSF workbooks.
|
||||
*
|
||||
* @version 2.0-pre
|
||||
*/
|
||||
|
||||
public final class MMSRecord
|
||||
extends StandardRecord
|
||||
{
|
||||
public final static short sid = 0xC1;
|
||||
private byte field_1_addMenuCount; // = 0;
|
||||
private byte field_2_delMenuCount; // = 0;
|
||||
public final class MMSRecord extends StandardRecord {
|
||||
public static final short sid = 0xC1;
|
||||
private byte field_1_addMenuCount;
|
||||
private byte field_2_delMenuCount;
|
||||
|
||||
public MMSRecord()
|
||||
{
|
||||
public MMSRecord() {}
|
||||
|
||||
public MMSRecord(MMSRecord other) {
|
||||
field_1_addMenuCount = other.field_1_addMenuCount;
|
||||
field_2_delMenuCount = other.field_2_delMenuCount;
|
||||
}
|
||||
|
||||
public MMSRecord(RecordInputStream in)
|
||||
{
|
||||
public MMSRecord(RecordInputStream in) {
|
||||
if (in.remaining()==0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
field_1_addMenuCount = in.readByte();
|
||||
field_2_delMenuCount = in.readByte();
|
||||
}
|
||||
|
@ -117,4 +115,9 @@ public final class MMSRecord
|
|||
{
|
||||
return sid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MMSRecord copy() {
|
||||
return new MMSRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,22 +17,33 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Merged Cells Record (0x00E5)<p>
|
||||
*
|
||||
* Description: Optional record defining a square area of cells to "merged" into one cell.
|
||||
* Optional record defining a square area of cells to "merged" into one cell.
|
||||
*/
|
||||
public final class MergeCellsRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x00E5;
|
||||
/** sometimes the regions array is shared with other MergedCellsRecords */
|
||||
public final class MergeCellsRecord extends StandardRecord {
|
||||
public static final short sid = 0x00E5;
|
||||
|
||||
/** sometimes the regions array is shared with other MergedCellsRecords */
|
||||
private final CellRangeAddress[] _regions;
|
||||
private final int _startIndex;
|
||||
private final int _numberOfRegions;
|
||||
|
||||
public MergeCellsRecord(MergeCellsRecord other) {
|
||||
super(other);
|
||||
_regions = (other._regions == null) ? null
|
||||
: Stream.of(other._regions).map(CellRangeAddress::copy).toArray(CellRangeAddress[]::new);
|
||||
_startIndex = other._startIndex;
|
||||
_numberOfRegions = other._numberOfRegions;
|
||||
}
|
||||
|
||||
|
||||
public MergeCellsRecord(CellRangeAddress[] regions, int startIndex, int numberOfRegions) {
|
||||
_regions = regions;
|
||||
_startIndex = startIndex;
|
||||
|
@ -63,7 +74,7 @@ public final class MergeCellsRecord extends StandardRecord implements Cloneable
|
|||
|
||||
/**
|
||||
* @param index the n-th MergedRegion
|
||||
*
|
||||
*
|
||||
* @return MergedRegion at the given index representing the area that is Merged (r1,c1 - r2,c2)
|
||||
*/
|
||||
public CellRangeAddress getAreaAt(int index) {
|
||||
|
@ -107,12 +118,15 @@ public final class MergeCellsRecord extends StandardRecord implements Cloneable
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public MergeCellsRecord clone() {
|
||||
int nRegions = _numberOfRegions;
|
||||
CellRangeAddress[] clonedRegions = new CellRangeAddress[nRegions];
|
||||
for (int i = 0; i < clonedRegions.length; i++) {
|
||||
clonedRegions[i] = _regions[_startIndex + i].copy();
|
||||
}
|
||||
return new MergeCellsRecord(clonedRegions, 0, nRegions);
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeCellsRecord copy() {
|
||||
return new MergeCellsRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,17 +18,15 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
|
||||
/**
|
||||
* Title: Multiple Blank cell record(0x00BE)<p>
|
||||
* Description: Represents a set of columns in a row with no value but with styling.<p>
|
||||
* Represents a set of columns in a row with no value but with styling.
|
||||
*
|
||||
* REFERENCE: PG 329 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
*
|
||||
* @see BlankRecord
|
||||
*/
|
||||
public final class MulBlankRecord extends StandardRecord {
|
||||
public final static short sid = 0x00BE;
|
||||
public static final short sid = 0x00BE;
|
||||
|
||||
private final int _row;
|
||||
private final int _firstCol;
|
||||
|
@ -55,7 +53,7 @@ public final class MulBlankRecord extends StandardRecord {
|
|||
public int getFirstColumn() {
|
||||
return _firstCol;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ending column (last cell this holds in the row). Zero based
|
||||
*/
|
||||
|
@ -122,8 +120,8 @@ public final class MulBlankRecord extends StandardRecord {
|
|||
out.writeShort(_row);
|
||||
out.writeShort(_firstCol);
|
||||
int nItems = _xfs.length;
|
||||
for (int i = 0; i < nItems; i++) {
|
||||
out.writeShort(_xfs[i]);
|
||||
for (short xf : _xfs) {
|
||||
out.writeShort(xf);
|
||||
}
|
||||
out.writeShort(_lastCol);
|
||||
}
|
||||
|
@ -134,7 +132,15 @@ public final class MulBlankRecord extends StandardRecord {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public MulBlankRecord clone() {
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MulBlankRecord copy() {
|
||||
// immutable - so OK to return this
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -23,18 +23,15 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||
import org.apache.poi.util.RecordFormatException;
|
||||
|
||||
/**
|
||||
* MULRK (0x00BD)<p>
|
||||
*
|
||||
* Used to store multiple RK numbers on a row. 1 MulRk = Multiple Cell values.
|
||||
* HSSF just converts this into multiple NUMBER records. READ-ONLY SUPPORT!<P>
|
||||
* REFERENCE: PG 330 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
*
|
||||
* HSSF just converts this into multiple NUMBER records. READ-ONLY SUPPORT!
|
||||
*
|
||||
* @since 2.0-pre
|
||||
*/
|
||||
public final class MulRKRecord extends StandardRecord {
|
||||
public final static short sid = 0x00BD;
|
||||
public static final short sid = 0x00BD;
|
||||
|
||||
private final int field_1_row;
|
||||
private final int field_1_row;
|
||||
private final short field_2_first_col;
|
||||
private final RkRec[] field_3_rks;
|
||||
private final short field_4_last_col;
|
||||
|
@ -69,9 +66,9 @@ public final class MulRKRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* returns the xf index for column (coffset = column - field_2_first_col)
|
||||
*
|
||||
*
|
||||
* @param coffset the coffset = column - field_2_first_col
|
||||
*
|
||||
*
|
||||
* @return the XF index for the column
|
||||
*/
|
||||
public short getXFAt(int coffset) {
|
||||
|
@ -80,9 +77,9 @@ public final class MulRKRecord extends StandardRecord {
|
|||
|
||||
/**
|
||||
* returns the rk number for column (coffset = column - field_2_first_col)
|
||||
*
|
||||
*
|
||||
* @param coffset the coffset = column - field_2_first_col
|
||||
*
|
||||
*
|
||||
* @return the value (decoded into a double)
|
||||
*/
|
||||
public double getRKNumberAt(int coffset) {
|
||||
|
@ -151,4 +148,10 @@ public final class MulRKRecord extends StandardRecord {
|
|||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MulRKRecord copy() {
|
||||
// immutable - so OK to return this
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,145 +18,154 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: NAMECMT Record (0x0894)<p>
|
||||
*
|
||||
* Description: Defines a comment associated with a specified name.
|
||||
* Defines a comment associated with a specified name.
|
||||
*/
|
||||
public final class NameCommentRecord extends StandardRecord {
|
||||
public final static short sid = 0x0894;
|
||||
public static final short sid = 0x0894;
|
||||
|
||||
private final short field_1_record_type;
|
||||
private final short field_2_frt_cell_ref_flag;
|
||||
private final long field_3_reserved;
|
||||
//private short field_4_name_length;
|
||||
//private short field_5_comment_length;
|
||||
private String field_6_name_text;
|
||||
private String field_7_comment_text;
|
||||
private final short field_1_record_type;
|
||||
private final short field_2_frt_cell_ref_flag;
|
||||
private final long field_3_reserved;
|
||||
//private short field_4_name_length;
|
||||
//private short field_5_comment_length;
|
||||
private String field_6_name_text;
|
||||
private String field_7_comment_text;
|
||||
|
||||
public NameCommentRecord(final String name, final String comment) {
|
||||
field_1_record_type = 0;
|
||||
field_2_frt_cell_ref_flag = 0;
|
||||
field_3_reserved = 0;
|
||||
field_6_name_text = name;
|
||||
field_7_comment_text = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(final LittleEndianOutput out) {
|
||||
final int field_4_name_length = field_6_name_text.length();
|
||||
final int field_5_comment_length = field_7_comment_text.length();
|
||||
|
||||
out.writeShort(field_1_record_type);
|
||||
out.writeShort(field_2_frt_cell_ref_flag);
|
||||
out.writeLong(field_3_reserved);
|
||||
out.writeShort(field_4_name_length);
|
||||
out.writeShort(field_5_comment_length);
|
||||
|
||||
boolean isNameMultiByte = StringUtil.hasMultibyte(field_6_name_text);
|
||||
out.writeByte(isNameMultiByte ? 1 : 0);
|
||||
if (isNameMultiByte) {
|
||||
StringUtil.putUnicodeLE(field_6_name_text, out);
|
||||
} else {
|
||||
StringUtil.putCompressedUnicode(field_6_name_text, out);
|
||||
public NameCommentRecord(NameCommentRecord other) {
|
||||
field_1_record_type = other.field_1_record_type;
|
||||
field_2_frt_cell_ref_flag = other.field_2_frt_cell_ref_flag;
|
||||
field_3_reserved = other.field_3_reserved;
|
||||
field_6_name_text = other.field_6_name_text;
|
||||
field_7_comment_text = other.field_7_comment_text;
|
||||
}
|
||||
boolean isCommentMultiByte = StringUtil.hasMultibyte(field_7_comment_text);
|
||||
out.writeByte(isCommentMultiByte ? 1 : 0);
|
||||
if (isCommentMultiByte) {
|
||||
StringUtil.putUnicodeLE(field_7_comment_text, out);
|
||||
} else {
|
||||
StringUtil.putCompressedUnicode(field_7_comment_text, out);
|
||||
|
||||
public NameCommentRecord(final String name, final String comment) {
|
||||
field_1_record_type = 0;
|
||||
field_2_frt_cell_ref_flag = 0;
|
||||
field_3_reserved = 0;
|
||||
field_6_name_text = name;
|
||||
field_7_comment_text = comment;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDataSize() {
|
||||
return 18 // 4 shorts + 1 long + 2 spurious 'nul's
|
||||
+ (StringUtil.hasMultibyte(field_6_name_text) ? field_6_name_text.length()*2 : field_6_name_text.length())
|
||||
+ (StringUtil.hasMultibyte(field_7_comment_text) ? field_7_comment_text.length()*2 : field_7_comment_text.length());
|
||||
}
|
||||
/**
|
||||
* @param ris the RecordInputstream to read the record from
|
||||
*/
|
||||
public NameCommentRecord(final RecordInputStream ris) {
|
||||
field_1_record_type = ris.readShort();
|
||||
field_2_frt_cell_ref_flag = ris.readShort();
|
||||
field_3_reserved = ris.readLong();
|
||||
final int field_4_name_length = ris.readShort();
|
||||
final int field_5_comment_length = ris.readShort();
|
||||
|
||||
/**
|
||||
* @param ris the RecordInputstream to read the record from
|
||||
*/
|
||||
public NameCommentRecord(final RecordInputStream ris) {
|
||||
field_1_record_type = ris.readShort();
|
||||
field_2_frt_cell_ref_flag = ris.readShort();
|
||||
field_3_reserved = ris.readLong();
|
||||
final int field_4_name_length = ris.readShort();
|
||||
final int field_5_comment_length = ris.readShort();
|
||||
|
||||
if (ris.readByte() == 0) {
|
||||
field_6_name_text = StringUtil.readCompressedUnicode(ris, field_4_name_length);
|
||||
} else {
|
||||
field_6_name_text = StringUtil.readUnicodeLE(ris, field_4_name_length);
|
||||
if (ris.readByte() == 0) {
|
||||
field_6_name_text = StringUtil.readCompressedUnicode(ris, field_4_name_length);
|
||||
} else {
|
||||
field_6_name_text = StringUtil.readUnicodeLE(ris, field_4_name_length);
|
||||
}
|
||||
if (ris.readByte() == 0) {
|
||||
field_7_comment_text = StringUtil.readCompressedUnicode(ris, field_5_comment_length);
|
||||
} else {
|
||||
field_7_comment_text = StringUtil.readUnicodeLE(ris, field_5_comment_length);
|
||||
}
|
||||
}
|
||||
if (ris.readByte() == 0) {
|
||||
field_7_comment_text = StringUtil.readCompressedUnicode(ris, field_5_comment_length);
|
||||
} else {
|
||||
field_7_comment_text = StringUtil.readUnicodeLE(ris, field_5_comment_length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the non static version of the id for this record.
|
||||
*/
|
||||
@Override
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
@Override
|
||||
public void serialize(final LittleEndianOutput out) {
|
||||
final int field_4_name_length = field_6_name_text.length();
|
||||
final int field_5_comment_length = field_7_comment_text.length();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
out.writeShort(field_1_record_type);
|
||||
out.writeShort(field_2_frt_cell_ref_flag);
|
||||
out.writeLong(field_3_reserved);
|
||||
out.writeShort(field_4_name_length);
|
||||
out.writeShort(field_5_comment_length);
|
||||
|
||||
sb.append("[NAMECMT]\n");
|
||||
sb.append(" .record type = ").append(HexDump.shortToHex(field_1_record_type)).append("\n");
|
||||
sb.append(" .frt cell ref flag = ").append(HexDump.byteToHex(field_2_frt_cell_ref_flag)).append("\n");
|
||||
sb.append(" .reserved = ").append(field_3_reserved).append("\n");
|
||||
sb.append(" .name length = ").append(field_6_name_text.length()).append("\n");
|
||||
sb.append(" .comment length = ").append(field_7_comment_text.length()).append("\n");
|
||||
sb.append(" .name = ").append(field_6_name_text).append("\n");
|
||||
sb.append(" .comment = ").append(field_7_comment_text).append("\n");
|
||||
sb.append("[/NAMECMT]\n");
|
||||
boolean isNameMultiByte = StringUtil.hasMultibyte(field_6_name_text);
|
||||
out.writeByte(isNameMultiByte ? 1 : 0);
|
||||
if (isNameMultiByte) {
|
||||
StringUtil.putUnicodeLE(field_6_name_text, out);
|
||||
} else {
|
||||
StringUtil.putCompressedUnicode(field_6_name_text, out);
|
||||
}
|
||||
boolean isCommentMultiByte = StringUtil.hasMultibyte(field_7_comment_text);
|
||||
out.writeByte(isCommentMultiByte ? 1 : 0);
|
||||
if (isCommentMultiByte) {
|
||||
StringUtil.putUnicodeLE(field_7_comment_text, out);
|
||||
} else {
|
||||
StringUtil.putCompressedUnicode(field_7_comment_text, out);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
@Override
|
||||
protected int getDataSize() {
|
||||
return 18 // 4 shorts + 1 long + 2 spurious 'nul's
|
||||
+ (StringUtil.hasMultibyte(field_6_name_text) ? field_6_name_text.length() * 2 : field_6_name_text.length())
|
||||
+ (StringUtil.hasMultibyte(field_7_comment_text) ? field_7_comment_text.length() * 2 : field_7_comment_text.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the NameRecord to which this comment applies.
|
||||
*/
|
||||
public String getNameText() {
|
||||
return field_6_name_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name we're associated with, normally used
|
||||
* when renaming that Name
|
||||
*
|
||||
* @param newName the new name
|
||||
*/
|
||||
public void setNameText(String newName) {
|
||||
field_6_name_text = newName;
|
||||
}
|
||||
/**
|
||||
* return the non static version of the id for this record.
|
||||
*/
|
||||
@Override
|
||||
public short getSid() {
|
||||
return sid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the text of the comment.
|
||||
*/
|
||||
public String getCommentText() {
|
||||
return field_7_comment_text;
|
||||
}
|
||||
|
||||
public void setCommentText(String comment) {
|
||||
field_7_comment_text = comment;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
public short getRecordType() {
|
||||
return field_1_record_type;
|
||||
}
|
||||
sb.append("[NAMECMT]\n");
|
||||
sb.append(" .record type = ").append(HexDump.shortToHex(field_1_record_type)).append("\n");
|
||||
sb.append(" .frt cell ref flag = ").append(HexDump.byteToHex(field_2_frt_cell_ref_flag)).append("\n");
|
||||
sb.append(" .reserved = ").append(field_3_reserved).append("\n");
|
||||
sb.append(" .name length = ").append(field_6_name_text.length()).append("\n");
|
||||
sb.append(" .comment length = ").append(field_7_comment_text.length()).append("\n");
|
||||
sb.append(" .name = ").append(field_6_name_text).append("\n");
|
||||
sb.append(" .comment = ").append(field_7_comment_text).append("\n");
|
||||
sb.append("[/NAMECMT]\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of the NameRecord to which this comment applies.
|
||||
*/
|
||||
public String getNameText() {
|
||||
return field_6_name_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name we're associated with, normally used
|
||||
* when renaming that Name
|
||||
*
|
||||
* @param newName the new name
|
||||
*/
|
||||
public void setNameText(String newName) {
|
||||
field_6_name_text = newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the text of the comment.
|
||||
*/
|
||||
public String getCommentText() {
|
||||
return field_7_comment_text;
|
||||
}
|
||||
|
||||
public void setCommentText(String comment) {
|
||||
field_7_comment_text = comment;
|
||||
}
|
||||
|
||||
public short getRecordType() {
|
||||
return field_1_record_type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameCommentRecord copy() {
|
||||
return new NameCommentRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,44 +19,46 @@ package org.apache.poi.hssf.record;
|
|||
|
||||
import org.apache.poi.hssf.record.cont.ContinuableRecord;
|
||||
import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
|
||||
import org.apache.poi.ss.formula.Formula;
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
|
||||
import org.apache.poi.ss.formula.Formula;
|
||||
import org.apache.poi.util.*;
|
||||
import org.apache.poi.util.HexDump;
|
||||
import org.apache.poi.util.LittleEndianByteArrayInputStream;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Title: DEFINEDNAME Record (0x0018)<p>
|
||||
* Description: Defines a named range within a workbook.
|
||||
* Defines a named range within a workbook.
|
||||
*/
|
||||
public final class NameRecord extends ContinuableRecord {
|
||||
public final static short sid = 0x0018;
|
||||
public static final short sid = 0x0018;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_CONSOLIDATE_AREA = 1;
|
||||
public static final byte BUILTIN_CONSOLIDATE_AREA = 1;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_AUTO_OPEN = 2;
|
||||
public static final byte BUILTIN_AUTO_OPEN = 2;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_AUTO_CLOSE = 3;
|
||||
public static final byte BUILTIN_AUTO_CLOSE = 3;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_DATABASE = 4;
|
||||
public static final byte BUILTIN_DATABASE = 4;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_CRITERIA = 5;
|
||||
public static final byte BUILTIN_CRITERIA = 5;
|
||||
|
||||
public final static byte BUILTIN_PRINT_AREA = 6;
|
||||
public final static byte BUILTIN_PRINT_TITLE = 7;
|
||||
public static final byte BUILTIN_PRINT_AREA = 6;
|
||||
public static final byte BUILTIN_PRINT_TITLE = 7;
|
||||
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_RECORDER = 8;
|
||||
public static final byte BUILTIN_RECORDER = 8;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_DATA_FORM = 9;
|
||||
public static final byte BUILTIN_DATA_FORM = 9;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_AUTO_ACTIVATE = 10;
|
||||
public static final byte BUILTIN_AUTO_ACTIVATE = 10;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_AUTO_DEACTIVATE = 11;
|
||||
public static final byte BUILTIN_AUTO_DEACTIVATE = 11;
|
||||
/**Included for completeness sake, not implemented */
|
||||
public final static byte BUILTIN_SHEET_TITLE = 12;
|
||||
public static final byte BUILTIN_SHEET_TITLE = 12;
|
||||
|
||||
public final static byte BUILTIN_FILTER_DB = 13;
|
||||
public static final byte BUILTIN_FILTER_DB = 13;
|
||||
|
||||
private static final class Option {
|
||||
public static final int OPT_HIDDEN_NAME = 0x0001;
|
||||
|
@ -98,10 +100,26 @@ public final class NameRecord extends ContinuableRecord {
|
|||
field_17_status_bar_text = "";
|
||||
}
|
||||
|
||||
public NameRecord(NameRecord other) {
|
||||
super(other);
|
||||
field_1_option_flag = other.field_1_option_flag;
|
||||
field_2_keyboard_shortcut = other.field_2_keyboard_shortcut;
|
||||
field_5_externSheetIndex_plus1 = other.field_5_externSheetIndex_plus1;
|
||||
field_6_sheetNumber = other.field_6_sheetNumber;
|
||||
field_11_nameIsMultibyte = other.field_11_nameIsMultibyte;
|
||||
field_12_built_in_code = other.field_12_built_in_code;
|
||||
field_12_name_text = other.field_12_name_text;
|
||||
field_13_name_definition = other.field_13_name_definition;
|
||||
field_14_custom_menu_text = other.field_14_custom_menu_text;
|
||||
field_15_description_text = other.field_15_description_text;
|
||||
field_16_help_topic_text = other.field_16_help_topic_text;
|
||||
field_17_status_bar_text = other.field_17_status_bar_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to create a built-in named region
|
||||
* @param builtin Built-in byte representation for the name record, use the public constants
|
||||
* @param sheetNumber the sheet which the name applies to
|
||||
* @param sheetNumber the sheet which the name applies to
|
||||
*/
|
||||
public NameRecord(byte builtin, int sheetNumber)
|
||||
{
|
||||
|
@ -276,7 +294,7 @@ public final class NameRecord extends ContinuableRecord {
|
|||
|
||||
/**
|
||||
* Convenience Function to determine if the name is a built-in name
|
||||
*
|
||||
*
|
||||
* @return true, if the name is a built-in name
|
||||
*/
|
||||
public boolean isBuiltInName()
|
||||
|
@ -590,4 +608,9 @@ public final class NameRecord extends ContinuableRecord {
|
|||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameRecord copy() {
|
||||
return new NameRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,27 +18,28 @@
|
|||
package org.apache.poi.hssf.record;
|
||||
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.Removal;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
|
||||
/**
|
||||
* NOTE: Comment Associated with a Cell (0x001C)
|
||||
*/
|
||||
public final class NoteRecord extends StandardRecord implements Cloneable {
|
||||
public final static short sid = 0x001C;
|
||||
public final class NoteRecord extends StandardRecord {
|
||||
public static final short sid = 0x001C;
|
||||
|
||||
public static final NoteRecord[] EMPTY_ARRAY = { };
|
||||
|
||||
/**
|
||||
* Flag indicating that the comment is hidden (default)
|
||||
*/
|
||||
public final static short NOTE_HIDDEN = 0x0;
|
||||
public static final short NOTE_HIDDEN = 0x0;
|
||||
|
||||
/**
|
||||
* Flag indicating that the comment is visible
|
||||
*/
|
||||
public final static short NOTE_VISIBLE = 0x2;
|
||||
public static final short NOTE_VISIBLE = 0x2;
|
||||
|
||||
private static final Byte DEFAULT_PADDING = Byte.valueOf((byte)0);
|
||||
private static final Byte DEFAULT_PADDING = (byte) 0;
|
||||
|
||||
private int field_1_row;
|
||||
private int field_2_col;
|
||||
|
@ -46,6 +47,7 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
private int field_4_shapeid;
|
||||
private boolean field_5_hasMultibyte;
|
||||
private String field_6_author;
|
||||
|
||||
/**
|
||||
* Saves padding byte value to reduce delta during round-trip serialization.<br>
|
||||
*
|
||||
|
@ -64,6 +66,17 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
field_7_padding = DEFAULT_PADDING; // seems to be always present regardless of author text
|
||||
}
|
||||
|
||||
public NoteRecord(NoteRecord other) {
|
||||
super(other);
|
||||
field_1_row = other.field_1_row;
|
||||
field_2_col = other.field_2_col;
|
||||
field_3_flags = other.field_3_flags;
|
||||
field_4_shapeid = other.field_4_shapeid;
|
||||
field_5_hasMultibyte = other.field_5_hasMultibyte;
|
||||
field_6_author = other.field_6_author;
|
||||
field_7_padding = other.field_7_padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return id of this record.
|
||||
*/
|
||||
|
@ -73,7 +86,7 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Read the record data from the supplied <code>RecordInputStream</code>
|
||||
*
|
||||
*
|
||||
* @param in the RecordInputStream to read from
|
||||
*/
|
||||
public NoteRecord(RecordInputStream in) {
|
||||
|
@ -194,10 +207,10 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
public void setFlags(short flags) {
|
||||
field_3_flags = flags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For unit testing only!
|
||||
*
|
||||
*
|
||||
* @return true, if author element uses multi byte
|
||||
*/
|
||||
protected boolean authorIsMultibyte() {
|
||||
|
@ -206,7 +219,7 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Object id for OBJ record that contains the comment
|
||||
*
|
||||
*
|
||||
* @return the Object id for OBJ record that contains the comment
|
||||
*/
|
||||
public int getShapeId() {
|
||||
|
@ -215,7 +228,7 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
|
||||
/**
|
||||
* Object id for OBJ record that contains the comment
|
||||
*
|
||||
*
|
||||
* @param id the Object id for OBJ record that contains the comment
|
||||
*/
|
||||
public void setShapeId(int id) {
|
||||
|
@ -242,13 +255,15 @@ public final class NoteRecord extends StandardRecord implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S2975")
|
||||
@Deprecated
|
||||
@Removal(version = "5.0.0")
|
||||
public NoteRecord clone() {
|
||||
NoteRecord rec = new NoteRecord();
|
||||
rec.field_1_row = field_1_row;
|
||||
rec.field_2_col = field_2_col;
|
||||
rec.field_3_flags = field_3_flags;
|
||||
rec.field_4_shapeid = field_4_shapeid;
|
||||
rec.field_6_author = field_6_author;
|
||||
return rec;
|
||||
return copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoteRecord copy() {
|
||||
return new NoteRecord(this);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue