Start to support CF12 headers for #58130
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1690494 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8c1cb7e48a
commit
c63ff25ebb
@ -180,6 +180,7 @@ public final class BiffViewer {
|
|||||||
case BottomMarginRecord.sid: return new BottomMarginRecord(in);
|
case BottomMarginRecord.sid: return new BottomMarginRecord(in);
|
||||||
case BoundSheetRecord.sid: return new BoundSheetRecord(in);
|
case BoundSheetRecord.sid: return new BoundSheetRecord(in);
|
||||||
case CFHeaderRecord.sid: return new CFHeaderRecord(in);
|
case CFHeaderRecord.sid: return new CFHeaderRecord(in);
|
||||||
|
case CFHeader12Record.sid: return new CFHeader12Record(in);
|
||||||
case CFRuleRecord.sid: return new CFRuleRecord(in);
|
case CFRuleRecord.sid: return new CFRuleRecord(in);
|
||||||
case CalcCountRecord.sid: return new CalcCountRecord(in);
|
case CalcCountRecord.sid: return new CalcCountRecord(in);
|
||||||
case CalcModeRecord.sid: return new CalcModeRecord(in);
|
case CalcModeRecord.sid: return new CalcModeRecord(in);
|
||||||
|
75
src/java/org/apache/poi/hssf/record/CFHeader12Record.java
Normal file
75
src/java/org/apache/poi/hssf/record/CFHeader12Record.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hssf.record;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.common.FtrHeader;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.util.LittleEndianOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditional Formatting Header v12 record CFHEADER12 (0x0879),
|
||||||
|
* for conditional formattings introduced in Excel 2007 and newer.
|
||||||
|
*/
|
||||||
|
public final class CFHeader12Record extends CFHeaderRecord {
|
||||||
|
public static final short sid = 0x0879;
|
||||||
|
|
||||||
|
private FtrHeader futureHeader;
|
||||||
|
|
||||||
|
/** Creates new CFHeaderRecord */
|
||||||
|
public CFHeader12Record() {
|
||||||
|
super();
|
||||||
|
futureHeader = new FtrHeader();
|
||||||
|
futureHeader.setRecordType(sid);
|
||||||
|
}
|
||||||
|
public CFHeader12Record(CellRangeAddress[] regions, int nRules) {
|
||||||
|
super(regions, nRules);
|
||||||
|
futureHeader = new FtrHeader();
|
||||||
|
futureHeader.setRecordType(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CFHeader12Record(RecordInputStream in)
|
||||||
|
{
|
||||||
|
futureHeader = new FtrHeader(in);
|
||||||
|
read(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getRecordName() {
|
||||||
|
return "CFHEADER12";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getDataSize() {
|
||||||
|
return FtrHeader.getDataSize() + super.getDataSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void serialize(LittleEndianOutput out) {
|
||||||
|
futureHeader.serialize(out);
|
||||||
|
super.serialize(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getSid() {
|
||||||
|
return sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() {
|
||||||
|
CFHeader12Record result = new CFHeader12Record();
|
||||||
|
result.futureHeader = (FtrHeader)futureHeader.clone();
|
||||||
|
// TODO Clone the rest via the base
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -26,12 +26,13 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||||||
* Conditional Formatting Header record CFHEADER (0x01B0).
|
* Conditional Formatting Header record CFHEADER (0x01B0).
|
||||||
* Used to describe a {@link CFRuleRecord}.
|
* Used to describe a {@link CFRuleRecord}.
|
||||||
* @see CFHeader12Record
|
* @see CFHeader12Record
|
||||||
|
* TODO Move most of the logic into a base class
|
||||||
*/
|
*/
|
||||||
public final class CFHeaderRecord extends StandardRecord {
|
public class CFHeaderRecord extends StandardRecord {
|
||||||
public static final short sid = 0x01B0;
|
public static final short sid = 0x01B0;
|
||||||
|
|
||||||
private int field_1_numcf;
|
private int field_1_numcf;
|
||||||
private int field_2_need_recalculation;
|
private int field_2_need_recalculation_and_id;
|
||||||
private CellRangeAddress field_3_enclosing_cell_range;
|
private CellRangeAddress field_3_enclosing_cell_range;
|
||||||
private CellRangeAddressList field_4_cell_ranges;
|
private CellRangeAddressList field_4_cell_ranges;
|
||||||
|
|
||||||
@ -47,40 +48,51 @@ public final class CFHeaderRecord extends StandardRecord {
|
|||||||
field_1_numcf = nRules;
|
field_1_numcf = nRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CFHeaderRecord(RecordInputStream in)
|
public CFHeaderRecord(RecordInputStream in) {
|
||||||
{
|
read(in);
|
||||||
|
}
|
||||||
|
protected void read(RecordInputStream in) {
|
||||||
field_1_numcf = in.readShort();
|
field_1_numcf = in.readShort();
|
||||||
field_2_need_recalculation = in.readShort();
|
field_2_need_recalculation_and_id = in.readShort();
|
||||||
field_3_enclosing_cell_range = new CellRangeAddress(in);
|
field_3_enclosing_cell_range = new CellRangeAddress(in);
|
||||||
field_4_cell_ranges = new CellRangeAddressList(in);
|
field_4_cell_ranges = new CellRangeAddressList(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumberOfConditionalFormats()
|
public int getNumberOfConditionalFormats() {
|
||||||
{
|
|
||||||
return field_1_numcf;
|
return field_1_numcf;
|
||||||
}
|
}
|
||||||
public void setNumberOfConditionalFormats(int n)
|
public void setNumberOfConditionalFormats(int n) {
|
||||||
{
|
|
||||||
field_1_numcf=n;
|
field_1_numcf=n;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getNeedRecalculation()
|
public boolean getNeedRecalculation() {
|
||||||
{
|
// Held on the 1st bit
|
||||||
return field_2_need_recalculation==1?true:false;
|
return field_2_need_recalculation_and_id % 2 == 1;
|
||||||
}
|
}
|
||||||
|
public void setNeedRecalculation(boolean b) {
|
||||||
public void setNeedRecalculation(boolean b)
|
// held on the first bit
|
||||||
{
|
if (b == getNeedRecalculation()) return;
|
||||||
field_2_need_recalculation=b?1:0;
|
if (b) field_2_need_recalculation_and_id++;
|
||||||
|
else field_2_need_recalculation_and_id--;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CellRangeAddress getEnclosingCellRange()
|
public int getID()
|
||||||
{
|
{
|
||||||
|
// Remaining 15 bits of field 2
|
||||||
|
return field_2_need_recalculation_and_id>>1;
|
||||||
|
}
|
||||||
|
public void setID(int id)
|
||||||
|
{
|
||||||
|
// Remaining 15 bits of field 2
|
||||||
|
boolean needsRecalc = getNeedRecalculation();
|
||||||
|
field_2_need_recalculation_and_id = (id<<1);
|
||||||
|
if (needsRecalc) field_2_need_recalculation_and_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CellRangeAddress getEnclosingCellRange() {
|
||||||
return field_3_enclosing_cell_range;
|
return field_3_enclosing_cell_range;
|
||||||
}
|
}
|
||||||
|
public void setEnclosingCellRange(CellRangeAddress cr) {
|
||||||
public void setEnclosingCellRange(CellRangeAddress cr)
|
|
||||||
{
|
|
||||||
field_3_enclosing_cell_range = cr;
|
field_3_enclosing_cell_range = cr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,8 +101,7 @@ public final class CFHeaderRecord extends StandardRecord {
|
|||||||
* modify the enclosing cell range accordingly.
|
* modify the enclosing cell range accordingly.
|
||||||
* @param cellRanges - list of CellRange objects
|
* @param cellRanges - list of CellRange objects
|
||||||
*/
|
*/
|
||||||
public void setCellRanges(CellRangeAddress[] cellRanges)
|
public void setCellRanges(CellRangeAddress[] cellRanges) {
|
||||||
{
|
|
||||||
if(cellRanges == null)
|
if(cellRanges == null)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("cellRanges must not be null");
|
throw new IllegalArgumentException("cellRanges must not be null");
|
||||||
@ -111,11 +122,13 @@ public final class CFHeaderRecord extends StandardRecord {
|
|||||||
return field_4_cell_ranges.getCellRangeAddresses();
|
return field_4_cell_ranges.getCellRangeAddresses();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString()
|
protected String getRecordName() {
|
||||||
{
|
return "CFHEADER";
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
|
||||||
buffer.append("[CFHEADER]\n");
|
buffer.append("[").append(getRecordName()).append("]\n");
|
||||||
buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n");
|
buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n");
|
||||||
buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n");
|
buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n");
|
||||||
buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n");
|
buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n");
|
||||||
@ -126,7 +139,7 @@ public final class CFHeaderRecord extends StandardRecord {
|
|||||||
buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
|
buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
|
||||||
}
|
}
|
||||||
buffer.append("]\n");
|
buffer.append("]\n");
|
||||||
buffer.append("[/CFHEADER]\n");
|
buffer.append("[/").append(getRecordName()).append("]\n");
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +150,8 @@ public final class CFHeaderRecord extends StandardRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void serialize(LittleEndianOutput out) {
|
public void serialize(LittleEndianOutput out) {
|
||||||
|
|
||||||
out.writeShort(field_1_numcf);
|
out.writeShort(field_1_numcf);
|
||||||
out.writeShort(field_2_need_recalculation);
|
out.writeShort(field_2_need_recalculation_and_id);
|
||||||
field_3_enclosing_cell_range.serialize(out);
|
field_3_enclosing_cell_range.serialize(out);
|
||||||
field_4_cell_ranges.serialize(out);
|
field_4_cell_ranges.serialize(out);
|
||||||
}
|
}
|
||||||
@ -148,11 +160,10 @@ public final class CFHeaderRecord extends StandardRecord {
|
|||||||
return sid;
|
return sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object clone()
|
public Object clone() {
|
||||||
{
|
|
||||||
CFHeaderRecord result = new CFHeaderRecord();
|
CFHeaderRecord result = new CFHeaderRecord();
|
||||||
result.field_1_numcf = field_1_numcf;
|
result.field_1_numcf = field_1_numcf;
|
||||||
result.field_2_need_recalculation = field_2_need_recalculation;
|
result.field_2_need_recalculation_and_id = field_2_need_recalculation_and_id;
|
||||||
result.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
|
result.field_3_enclosing_cell_range = field_3_enclosing_cell_range;
|
||||||
result.field_4_cell_ranges = field_4_cell_ranges.copy();
|
result.field_4_cell_ranges = field_4_cell_ranges.copy();
|
||||||
return result;
|
return result;
|
||||||
|
@ -155,6 +155,7 @@ public final class RecordFactory {
|
|||||||
CalcCountRecord.class,
|
CalcCountRecord.class,
|
||||||
CalcModeRecord.class,
|
CalcModeRecord.class,
|
||||||
CFHeaderRecord.class,
|
CFHeaderRecord.class,
|
||||||
|
CFHeader12Record.class,
|
||||||
CFRuleRecord.class,
|
CFRuleRecord.class,
|
||||||
ChartRecord.class,
|
ChartRecord.class,
|
||||||
ChartTitleFormatRecord.class,
|
ChartTitleFormatRecord.class,
|
||||||
@ -166,7 +167,7 @@ public final class RecordFactory {
|
|||||||
CRNRecord.class,
|
CRNRecord.class,
|
||||||
DateWindow1904Record.class,
|
DateWindow1904Record.class,
|
||||||
DBCellRecord.class,
|
DBCellRecord.class,
|
||||||
DConRefRecord.class,
|
DConRefRecord.class,
|
||||||
DefaultColWidthRecord.class,
|
DefaultColWidthRecord.class,
|
||||||
DefaultRowHeightRecord.class,
|
DefaultRowHeightRecord.class,
|
||||||
DeltaRecord.class,
|
DeltaRecord.class,
|
||||||
|
@ -32,7 +32,7 @@ public final class FtrHeader {
|
|||||||
private short recordType;
|
private short recordType;
|
||||||
/** This is a FrtFlags */
|
/** This is a FrtFlags */
|
||||||
private short grbitFrt;
|
private short grbitFrt;
|
||||||
/** MUST be 8 bytes and all zero */
|
/** MUST be 8 bytes and all zero TODO Correct this! */
|
||||||
private byte[] reserved;
|
private byte[] reserved;
|
||||||
|
|
||||||
public FtrHeader() {
|
public FtrHeader() {
|
||||||
@ -86,4 +86,12 @@ public final class FtrHeader {
|
|||||||
public void setReserved(byte[] reserved) {
|
public void setReserved(byte[] reserved) {
|
||||||
this.reserved = reserved;
|
this.reserved = reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object clone() {
|
||||||
|
FtrHeader result = new FtrHeader();
|
||||||
|
result.recordType = recordType;
|
||||||
|
result.grbitFrt = grbitFrt;
|
||||||
|
result.reserved = reserved;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user