aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorPJ Fanning <fanningpj@apache.org>2019-11-18 08:56:06 +0000
committerPJ Fanning <fanningpj@apache.org>2019-11-18 08:56:06 +0000
commit948b0e8f08c05f475ec92f94f127878c6bc5f37b (patch)
treeabf5f0a99246e9990ff179c5c5a3ebf1a1d885c9 /src/java
parent63bb22887d86a1e31a9753dc6801aad6c1df78fd (diff)
downloadpoi-948b0e8f08c05f475ec92f94f127878c6bc5f37b.tar.gz
poi-948b0e8f08c05f475ec92f94f127878c6bc5f37b.zip
convert tabs to spaces
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1869962 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/poi/hssf/record/HyperlinkRecord.java294
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFChart.java2552
2 files changed, 1423 insertions, 1423 deletions
diff --git a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
index e4454bcf66..4f51179b01 100644
--- a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
+++ b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
@@ -42,52 +42,52 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
static final class GUID {
- /*
- * this class is currently only used here, but could be moved to a
- * common package if needed
- */
- private static final int TEXT_FORMAT_LENGTH = 36;
-
- public static final int ENCODED_SIZE = 16;
-
- /** 4 bytes - little endian */
- private final int _d1;
- /** 2 bytes - little endian */
- private final int _d2;
- /** 2 bytes - little endian */
- private final int _d3;
- /**
- * 8 bytes - serialized as big endian, stored with inverted endianness here
- */
- private final long _d4;
-
- public GUID(LittleEndianInput in) {
- this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
- }
-
- public GUID(int d1, int d2, int d3, long d4) {
- _d1 = d1;
- _d2 = d2;
- _d3 = d3;
- _d4 = d4;
- }
-
- public void serialize(LittleEndianOutput out) {
- out.writeInt(_d1);
- out.writeShort(_d2);
- out.writeShort(_d3);
- out.writeLong(_d4);
- }
-
- @Override
- public boolean equals(Object obj) {
+ /*
+ * this class is currently only used here, but could be moved to a
+ * common package if needed
+ */
+ private static final int TEXT_FORMAT_LENGTH = 36;
+
+ public static final int ENCODED_SIZE = 16;
+
+ /** 4 bytes - little endian */
+ private final int _d1;
+ /** 2 bytes - little endian */
+ private final int _d2;
+ /** 2 bytes - little endian */
+ private final int _d3;
+ /**
+ * 8 bytes - serialized as big endian, stored with inverted endianness here
+ */
+ private final long _d4;
+
+ public GUID(LittleEndianInput in) {
+ this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
+ }
+
+ public GUID(int d1, int d2, int d3, long d4) {
+ _d1 = d1;
+ _d2 = d2;
+ _d3 = d3;
+ _d4 = d4;
+ }
+
+ public void serialize(LittleEndianOutput out) {
+ out.writeInt(_d1);
+ out.writeShort(_d2);
+ out.writeShort(_d3);
+ out.writeLong(_d4);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
if (!(obj instanceof GUID)) {
return false;
}
- GUID other = (GUID) obj;
- return _d1 == other._d1 && _d2 == other._d2
- && _d3 == other._d3 && _d4 == other._d4;
- }
+ GUID other = (GUID) obj;
+ return _d1 == other._d1 && _d2 == other._d2
+ && _d3 == other._d3 && _d4 == other._d4;
+ }
@Override
public int hashCode() {
@@ -96,108 +96,108 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
}
public int getD1() {
- return _d1;
- }
-
- public int getD2() {
- return _d2;
- }
-
- public int getD3() {
- return _d3;
- }
-
- public long getD4() {
- byte[] result = new byte[Long.SIZE/Byte.SIZE];
- long l = _d4;
- for (int i = result.length-1; i >= 0; i--) {
- result[i] = (byte)(l & 0xFF);
- l >>= 8;
- }
-
- return LittleEndian.getLong(result, 0);
- }
-
- public String formatAsString() {
-
- StringBuilder sb = new StringBuilder(36);
-
- int PREFIX_LEN = "0x".length();
- sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN));
- sb.append("-");
- sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN));
- sb.append("-");
- sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN));
- sb.append("-");
- String d4Chars = HexDump.longToHex(getD4());
- sb.append(d4Chars, PREFIX_LEN, PREFIX_LEN+4);
- sb.append("-");
- sb.append(d4Chars.substring(PREFIX_LEN+4));
- return sb.toString();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(formatAsString());
- sb.append("]");
- return sb.toString();
- }
-
- /**
- * Read a GUID in standard text form e.g.<br>
- * 13579BDF-0246-8ACE-0123-456789ABCDEF
- * <br> -&gt; <br>
- * 0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF
- */
- public static GUID parse(String rep) {
- char[] cc = rep.toCharArray();
- if (cc.length != TEXT_FORMAT_LENGTH) {
- throw new RecordFormatException("supplied text is the wrong length for a GUID");
- }
- int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0);
- int d1 = parseShort(cc, 9);
- int d2 = parseShort(cc, 14);
+ return _d1;
+ }
+
+ public int getD2() {
+ return _d2;
+ }
+
+ public int getD3() {
+ return _d3;
+ }
+
+ public long getD4() {
+ byte[] result = new byte[Long.SIZE/Byte.SIZE];
+ long l = _d4;
+ for (int i = result.length-1; i >= 0; i--) {
+ result[i] = (byte)(l & 0xFF);
+ l >>= 8;
+ }
+
+ return LittleEndian.getLong(result, 0);
+ }
+
+ public String formatAsString() {
+
+ StringBuilder sb = new StringBuilder(36);
+
+ int PREFIX_LEN = "0x".length();
+ sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN));
+ sb.append("-");
+ sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN));
+ sb.append("-");
+ sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN));
+ sb.append("-");
+ String d4Chars = HexDump.longToHex(getD4());
+ sb.append(d4Chars, PREFIX_LEN, PREFIX_LEN+4);
+ sb.append("-");
+ sb.append(d4Chars.substring(PREFIX_LEN+4));
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(getClass().getName()).append(" [");
+ sb.append(formatAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+
+ /**
+ * Read a GUID in standard text form e.g.<br>
+ * 13579BDF-0246-8ACE-0123-456789ABCDEF
+ * <br> -&gt; <br>
+ * 0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF
+ */
+ public static GUID parse(String rep) {
+ char[] cc = rep.toCharArray();
+ if (cc.length != TEXT_FORMAT_LENGTH) {
+ throw new RecordFormatException("supplied text is the wrong length for a GUID");
+ }
+ int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0);
+ int d1 = parseShort(cc, 9);
+ int d2 = parseShort(cc, 14);
System.arraycopy(cc, 19, cc, 20, 4);
- long d3 = parseLELong(cc, 20);
-
- return new GUID(d0, d1, d2, d3);
- }
-
- private static long parseLELong(char[] cc, int startIndex) {
- long acc = 0;
- for (int i = startIndex + 14; i >= startIndex; i -= 2) {
- acc <<= 4;
- acc += parseHexChar(cc[i + 0]);
- acc <<= 4;
- acc += parseHexChar(cc[i + 1]);
- }
- return acc;
- }
-
- private static int parseShort(char[] cc, int startIndex) {
- int acc = 0;
- for (int i = 0; i < 4; i++) {
- acc <<= 4;
- acc += parseHexChar(cc[startIndex + i]);
- }
- return acc;
- }
-
- private static int parseHexChar(char c) {
- if (c >= '0' && c <= '9') {
- return c - '0';
- }
- if (c >= 'A' && c <= 'F') {
- return c - 'A' + 10;
- }
- if (c >= 'a' && c <= 'f') {
- return c - 'a' + 10;
- }
- throw new RecordFormatException("Bad hex char '" + c + "'");
- }
- }
+ long d3 = parseLELong(cc, 20);
+
+ return new GUID(d0, d1, d2, d3);
+ }
+
+ private static long parseLELong(char[] cc, int startIndex) {
+ long acc = 0;
+ for (int i = startIndex + 14; i >= startIndex; i -= 2) {
+ acc <<= 4;
+ acc += parseHexChar(cc[i + 0]);
+ acc <<= 4;
+ acc += parseHexChar(cc[i + 1]);
+ }
+ return acc;
+ }
+
+ private static int parseShort(char[] cc, int startIndex) {
+ int acc = 0;
+ for (int i = 0; i < 4; i++) {
+ acc <<= 4;
+ acc += parseHexChar(cc[startIndex + i]);
+ }
+ return acc;
+ }
+
+ private static int parseHexChar(char c) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+ throw new RecordFormatException("Bad hex char '" + c + "'");
+ }
+ }
/**
* Link flags
@@ -628,7 +628,7 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
size += 4; //address length
size += _address.length()*2;
if (_uninterpretedTail != null) {
- size += TAIL_SIZE;
+ size += TAIL_SIZE;
}
} else if (FILE_MONIKER.equals(_moniker)){
size += 2; //file_opts
@@ -652,8 +652,8 @@ public final class HyperlinkRecord extends StandardRecord implements Cloneable {
private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) {
- byte[] result = new byte[TAIL_SIZE];
- in.readFully(result);
+ byte[] result = new byte[TAIL_SIZE];
+ in.readFully(result);
// if (false) { // Quite a few examples in the unit tests which don't have the exact expected tail
// for (int i = 0; i < expectedTail.length; i++) {
// if (expectedTail[i] != result[i]) {
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java b/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java
index c08511fa46..0895fe94f1 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFChart.java
@@ -78,1294 +78,1294 @@ import org.apache.poi.ss.util.CellRangeAddressBase;
* @author Glen Stampoultzis (glens at apache.org)
*/
public final class HSSFChart {
- private HSSFSheet sheet;
- private ChartRecord chartRecord;
+ private HSSFSheet sheet;
+ private ChartRecord chartRecord;
- private LegendRecord legendRecord;
- @SuppressWarnings("unused")
+ private LegendRecord legendRecord;
+ @SuppressWarnings("unused")
private ChartTitleFormatRecord chartTitleFormat;
- private SeriesTextRecord chartTitleText;
- private List<ValueRangeRecord> valueRanges = new ArrayList<>();
-
- private HSSFChartType type = HSSFChartType.Unknown;
-
- private List<HSSFSeries> series = new ArrayList<>();
-
- public enum HSSFChartType {
- Area {
- @Override
- public short getSid() {
- return 0x101A;
- }
- },
- Bar {
- @Override
- public short getSid() {
- return 0x1017;
- }
- },
- Line {
- @Override
- public short getSid() {
- return 0x1018;
- }
- },
- Pie {
- @Override
- public short getSid() {
- return 0x1019;
- }
- },
- Scatter {
- @Override
- public short getSid() {
- return 0x101B;
- }
- },
- Unknown {
- @Override
- public short getSid() {
- return 0;
- }
- };
-
- public abstract short getSid();
- }
-
- private HSSFChart(HSSFSheet sheet, ChartRecord chartRecord) {
- this.chartRecord = chartRecord;
- this.sheet = sheet;
- }
-
- /**
- * Creates a bar chart. API needs some work. :)
- * <p>
- * NOTE: Does not yet work... checking it in just so others
- * can take a look.
- */
- public void createBarChart( HSSFWorkbook workbook, HSSFSheet parentSheet )
- {
-
- List<Record> records = new ArrayList<>();
- records.add( createMSDrawingObjectRecord() );
- records.add( createOBJRecord() );
- records.add( createBOFRecord() );
- records.add(new HeaderRecord(""));
- records.add(new FooterRecord(""));
- records.add( createHCenterRecord() );
- records.add( createVCenterRecord() );
- records.add( createPrintSetupRecord() );
- // unknown 33
- records.add( createFontBasisRecord1() );
- records.add( createFontBasisRecord2() );
- records.add(new ProtectRecord(false));
- records.add( createUnitsRecord() );
- records.add( createChartRecord( 0, 0, 30434904, 19031616 ) );
- records.add( createBeginRecord() );
- records.add( createSCLRecord( (short) 1, (short) 1 ) );
- records.add( createPlotGrowthRecord( 65536, 65536 ) );
- records.add( createFrameRecord1() );
- records.add( createBeginRecord() );
- records.add( createLineFormatRecord(true) );
- records.add( createAreaFormatRecord1() );
- records.add( createEndRecord() );
- records.add( createSeriesRecord() );
- records.add( createBeginRecord() );
- records.add( createTitleLinkedDataRecord() );
- records.add( createValuesLinkedDataRecord() );
- records.add( createCategoriesLinkedDataRecord() );
- records.add( createDataFormatRecord() );
- // records.add(createBeginRecord());
- // unknown
- // records.add(createEndRecord());
- records.add( createSeriesToChartGroupRecord() );
- records.add( createEndRecord() );
- records.add( createSheetPropsRecord() );
- records.add( createDefaultTextRecord( DefaultDataLabelTextPropertiesRecord.CATEGORY_DATA_TYPE_ALL_TEXT_CHARACTERISTIC ) );
- records.add( createAllTextRecord() );
- records.add( createBeginRecord() );
- // unknown
- records.add( createFontIndexRecord( 5 ) );
- records.add( createDirectLinkRecord() );
- records.add( createEndRecord() );
- records.add( createDefaultTextRecord( (short) 3 ) ); // eek, undocumented text type
- records.add( createUnknownTextRecord() );
- records.add( createBeginRecord() );
- records.add( createFontIndexRecord( (short) 6 ) );
- records.add( createDirectLinkRecord() );
- records.add( createEndRecord() );
-
- records.add( createAxisUsedRecord( (short) 1 ) );
- createAxisRecords( records );
-
- records.add( createEndRecord() );
- records.add( createDimensionsRecord() );
- records.add( createSeriesIndexRecord(2) );
- records.add( createSeriesIndexRecord(1) );
- records.add( createSeriesIndexRecord(3) );
- records.add(EOFRecord.instance);
-
-
-
- parentSheet.insertChartRecords( records );
- workbook.insertChartRecord();
- }
-
- /**
- * Returns all the charts for the given sheet.
- *
- * NOTE: You won't be able to do very much with
- * these charts yet, as this is very limited support
- */
- public static HSSFChart[] getSheetCharts(HSSFSheet sheet) {
- List<HSSFChart> charts = new ArrayList<>();
- HSSFChart lastChart = null;
- HSSFSeries lastSeries = null;
- // Find records of interest
- List<RecordBase> records = sheet.getSheet().getRecords();
- for(RecordBase r : records) {
-
- if(r instanceof ChartRecord) {
- lastSeries = null;
- lastChart = new HSSFChart(sheet,(ChartRecord)r);
- charts.add(lastChart);
+ private SeriesTextRecord chartTitleText;
+ private List<ValueRangeRecord> valueRanges = new ArrayList<>();
+
+ private HSSFChartType type = HSSFChartType.Unknown;
+
+ private List<HSSFSeries> series = new ArrayList<>();
+
+ public enum HSSFChartType {
+ Area {
+ @Override
+ public short getSid() {
+ return 0x101A;
+ }
+ },
+ Bar {
+ @Override
+ public short getSid() {
+ return 0x1017;
+ }
+ },
+ Line {
+ @Override
+ public short getSid() {
+ return 0x1018;
+ }
+ },
+ Pie {
+ @Override
+ public short getSid() {
+ return 0x1019;
+ }
+ },
+ Scatter {
+ @Override
+ public short getSid() {
+ return 0x101B;
+ }
+ },
+ Unknown {
+ @Override
+ public short getSid() {
+ return 0;
+ }
+ };
+
+ public abstract short getSid();
+ }
+
+ private HSSFChart(HSSFSheet sheet, ChartRecord chartRecord) {
+ this.chartRecord = chartRecord;
+ this.sheet = sheet;
+ }
+
+ /**
+ * Creates a bar chart. API needs some work. :)
+ * <p>
+ * NOTE: Does not yet work... checking it in just so others
+ * can take a look.
+ */
+ public void createBarChart( HSSFWorkbook workbook, HSSFSheet parentSheet )
+ {
+
+ List<Record> records = new ArrayList<>();
+ records.add( createMSDrawingObjectRecord() );
+ records.add( createOBJRecord() );
+ records.add( createBOFRecord() );
+ records.add(new HeaderRecord(""));
+ records.add(new FooterRecord(""));
+ records.add( createHCenterRecord() );
+ records.add( createVCenterRecord() );
+ records.add( createPrintSetupRecord() );
+ // unknown 33
+ records.add( createFontBasisRecord1() );
+ records.add( createFontBasisRecord2() );
+ records.add(new ProtectRecord(false));
+ records.add( createUnitsRecord() );
+ records.add( createChartRecord( 0, 0, 30434904, 19031616 ) );
+ records.add( createBeginRecord() );
+ records.add( createSCLRecord( (short) 1, (short) 1 ) );
+ records.add( createPlotGrowthRecord( 65536, 65536 ) );
+ records.add( createFrameRecord1() );
+ records.add( createBeginRecord() );
+ records.add( createLineFormatRecord(true) );
+ records.add( createAreaFormatRecord1() );
+ records.add( createEndRecord() );
+ records.add( createSeriesRecord() );
+ records.add( createBeginRecord() );
+ records.add( createTitleLinkedDataRecord() );
+ records.add( createValuesLinkedDataRecord() );
+ records.add( createCategoriesLinkedDataRecord() );
+ records.add( createDataFormatRecord() );
+ // records.add(createBeginRecord());
+ // unknown
+ // records.add(createEndRecord());
+ records.add( createSeriesToChartGroupRecord() );
+ records.add( createEndRecord() );
+ records.add( createSheetPropsRecord() );
+ records.add( createDefaultTextRecord( DefaultDataLabelTextPropertiesRecord.CATEGORY_DATA_TYPE_ALL_TEXT_CHARACTERISTIC ) );
+ records.add( createAllTextRecord() );
+ records.add( createBeginRecord() );
+ // unknown
+ records.add( createFontIndexRecord( 5 ) );
+ records.add( createDirectLinkRecord() );
+ records.add( createEndRecord() );
+ records.add( createDefaultTextRecord( (short) 3 ) ); // eek, undocumented text type
+ records.add( createUnknownTextRecord() );
+ records.add( createBeginRecord() );
+ records.add( createFontIndexRecord( (short) 6 ) );
+ records.add( createDirectLinkRecord() );
+ records.add( createEndRecord() );
+
+ records.add( createAxisUsedRecord( (short) 1 ) );
+ createAxisRecords( records );
+
+ records.add( createEndRecord() );
+ records.add( createDimensionsRecord() );
+ records.add( createSeriesIndexRecord(2) );
+ records.add( createSeriesIndexRecord(1) );
+ records.add( createSeriesIndexRecord(3) );
+ records.add(EOFRecord.instance);
+
+
+
+ parentSheet.insertChartRecords( records );
+ workbook.insertChartRecord();
+ }
+
+ /**
+ * Returns all the charts for the given sheet.
+ *
+ * NOTE: You won't be able to do very much with
+ * these charts yet, as this is very limited support
+ */
+ public static HSSFChart[] getSheetCharts(HSSFSheet sheet) {
+ List<HSSFChart> charts = new ArrayList<>();
+ HSSFChart lastChart = null;
+ HSSFSeries lastSeries = null;
+ // Find records of interest
+ List<RecordBase> records = sheet.getSheet().getRecords();
+ for(RecordBase r : records) {
+
+ if(r instanceof ChartRecord) {
+ lastSeries = null;
+ lastChart = new HSSFChart(sheet,(ChartRecord)r);
+ charts.add(lastChart);
} else if (r instanceof LinkedDataRecord) {
LinkedDataRecord linkedDataRecord = (LinkedDataRecord) r;
if (lastSeries != null) {
lastSeries.insertData(linkedDataRecord);
}
- }
+ }
if (lastChart == null) {
continue;
}
if (r instanceof LegendRecord) {
- lastChart.legendRecord = (LegendRecord)r;
- } else if(r instanceof SeriesRecord) {
- HSSFSeries series = new HSSFSeries( (SeriesRecord)r );
- lastChart.series.add(series);
- lastSeries = series;
- } else if(r instanceof ChartTitleFormatRecord) {
- lastChart.chartTitleFormat = (ChartTitleFormatRecord)r;
- } else if(r instanceof SeriesTextRecord) {
- // Applies to a series, unless we've seen a legend already
- SeriesTextRecord str = (SeriesTextRecord)r;
- if(lastChart.legendRecord == null && lastChart.series.size() > 0) {
- HSSFSeries series = lastChart.series.get(lastChart.series.size()-1);
- series.seriesTitleText = str;
- } else {
- lastChart.chartTitleText = str;
- }
- } else if(r instanceof ValueRangeRecord){
- lastChart.valueRanges.add((ValueRangeRecord)r);
- } else if (r instanceof Record) {
- Record record = (Record) r;
- for (HSSFChartType type : HSSFChartType.values()) {
- if (type == HSSFChartType.Unknown) {
- continue;
- }
- if (record.getSid() == type.getSid()) {
- lastChart.type = type;
- break;
- }
- }
- }
- }
-
- return charts.toArray(new HSSFChart[0]);
- }
-
- /** Get the X offset of the chart */
- public int getChartX() { return chartRecord.getX(); }
- /** Get the Y offset of the chart */
- public int getChartY() { return chartRecord.getY(); }
- /** Get the width of the chart. {@link ChartRecord} */
- public int getChartWidth() { return chartRecord.getWidth(); }
- /** Get the height of the chart. {@link ChartRecord} */
- public int getChartHeight() { return chartRecord.getHeight(); }
-
- /** Sets the X offset of the chart */
- public void setChartX(int x) { chartRecord.setX(x); }
- /** Sets the Y offset of the chart */
- public void setChartY(int y) { chartRecord.setY(y); }
- /** Sets the width of the chart. {@link ChartRecord} */
- public void setChartWidth(int width) { chartRecord.setWidth(width); }
- /** Sets the height of the chart. {@link ChartRecord} */
- public void setChartHeight(int height) { chartRecord.setHeight(height); }
-
- /**
- * Returns the series of the chart
- */
- public HSSFSeries[] getSeries() {
- return series.toArray(new HSSFSeries[0]);
- }
-
- /**
- * Returns the chart's title, if there is one,
- * or null if not
- */
- public String getChartTitle() {
- if(chartTitleText != null) {
- return chartTitleText.getText();
- }
- return null;
- }
-
- /**
- * Changes the chart's title, but only if there
- * was one already.
- * TODO - add in the records if not
- */
- public void setChartTitle(String title) {
- if(chartTitleText != null) {
- chartTitleText.setText(title);
- } else {
- throw new IllegalStateException("No chart title found to change");
- }
- }
-
- /**
- * Set value range (basic Axis Options)
- * @param axisIndex 0 - primary axis, 1 - secondary axis
- * @param minimum minimum value; Double.NaN - automatic; null - no change
- * @param maximum maximum value; Double.NaN - automatic; null - no change
- * @param majorUnit major unit value; Double.NaN - automatic; null - no change
- * @param minorUnit minor unit value; Double.NaN - automatic; null - no change
- */
- public void setValueRange( int axisIndex, Double minimum, Double maximum, Double majorUnit, Double minorUnit){
- ValueRangeRecord valueRange = valueRanges.get( axisIndex );
- if( valueRange == null ) return;
- if( minimum != null ){
- valueRange.setAutomaticMinimum(minimum.isNaN());
- valueRange.setMinimumAxisValue(minimum);
- }
- if( maximum != null ){
- valueRange.setAutomaticMaximum(maximum.isNaN());
- valueRange.setMaximumAxisValue(maximum);
- }
- if( majorUnit != null ){
- valueRange.setAutomaticMajor(majorUnit.isNaN());
- valueRange.setMajorIncrement(majorUnit);
- }
- if( minorUnit != null ){
- valueRange.setAutomaticMinor(minorUnit.isNaN());
- valueRange.setMinorIncrement(minorUnit);
- }
- }
-
- private SeriesIndexRecord createSeriesIndexRecord( int index )
- {
- SeriesIndexRecord r = new SeriesIndexRecord();
- r.setIndex((short)index);
- return r;
- }
-
- private DimensionsRecord createDimensionsRecord()
- {
- DimensionsRecord r = new DimensionsRecord();
- r.setFirstRow(0);
- r.setLastRow(31);
- r.setFirstCol((short)0);
- r.setLastCol((short)1);
- return r;
- }
-
- private HCenterRecord createHCenterRecord()
- {
- HCenterRecord r = new HCenterRecord();
- r.setHCenter(false);
- return r;
- }
-
- private VCenterRecord createVCenterRecord()
- {
- VCenterRecord r = new VCenterRecord();
- r.setVCenter(false);
- return r;
- }
-
- private PrintSetupRecord createPrintSetupRecord()
- {
- PrintSetupRecord r = new PrintSetupRecord();
- r.setPaperSize((short)0);
- r.setScale((short)18);
- r.setPageStart((short)1);
- r.setFitWidth((short)1);
- r.setFitHeight((short)1);
- r.setLeftToRight(false);
- r.setLandscape(false);
- r.setValidSettings(true);
- r.setNoColor(false);
- r.setDraft(false);
- r.setNotes(false);
- r.setNoOrientation(false);
- r.setUsePage(false);
- r.setHResolution((short)0);
- r.setVResolution((short)0);
- r.setHeaderMargin(0.5);
- r.setFooterMargin(0.5);
- r.setCopies((short)15); // what the ??
- return r;
- }
-
- private FontBasisRecord createFontBasisRecord1()
- {
- FontBasisRecord r = new FontBasisRecord();
- r.setXBasis((short)9120);
- r.setYBasis((short)5640);
- r.setHeightBasis((short)200);
- r.setScale((short)0);
- r.setIndexToFontTable((short)5);
- return r;
- }
-
- private FontBasisRecord createFontBasisRecord2()
- {
- FontBasisRecord r = createFontBasisRecord1();
- r.setIndexToFontTable((short)6);
- return r;
- }
-
- private BOFRecord createBOFRecord()
- {
- BOFRecord r = new BOFRecord();
- r.setVersion((short)600);
- r.setType((short)20);
- r.setBuild((short)0x1CFE);
- r.setBuildYear((short)1997);
- r.setHistoryBitMask(0x40C9);
- r.setRequiredVersion(106);
- return r;
- }
-
- private UnknownRecord createOBJRecord()
- {
- byte[] data = {
- (byte) 0x15, (byte) 0x00, (byte) 0x12, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x11, (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xB8, (byte) 0x03,
- (byte) 0x87, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
- };
-
- return new UnknownRecord( (short) 0x005D, data );
- }
-
- private UnknownRecord createMSDrawingObjectRecord()
- {
- // Since we haven't created this object yet we'll just put in the raw
- // form for the moment.
-
- byte[] data = {
- (byte)0x0F, (byte)0x00, (byte)0x02, (byte)0xF0, (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x08, (byte)0xF0, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x0F, (byte)0x00, (byte)0x03, (byte)0xF0, (byte)0xA8, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x0F, (byte)0x00, (byte)0x04, (byte)0xF0, (byte)0x28, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0xF0, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x02, (byte)0x00, (byte)0x0A, (byte)0xF0, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x0F, (byte)0x00, (byte)0x04, (byte)0xF0, (byte)0x70, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x92, (byte)0x0C, (byte)0x0A, (byte)0xF0, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x02, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x00, (byte)0x93, (byte)0x00, (byte)0x0B, (byte)0xF0, (byte)0x36, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x7F, (byte)0x00, (byte)0x04, (byte)0x01, (byte)0x04, (byte)0x01, (byte)0xBF, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x81, (byte)0x01, (byte)0x4E, (byte)0x00,
- (byte)0x00, (byte)0x08, (byte)0x83, (byte)0x01, (byte)0x4D, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0xBF, (byte)0x01, (byte)0x10, (byte)0x00, (byte)0x11, (byte)0x00, (byte)0xC0, (byte)0x01,
- (byte)0x4D, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0xFF, (byte)0x01, (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x3F, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00,
- (byte)0xBF, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0xF0, (byte)0x12, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
- (byte)0x04, (byte)0x00, (byte)0xC0, (byte)0x02, (byte)0x0A, (byte)0x00, (byte)0xF4, (byte)0x00, (byte)0x0E, (byte)0x00, (byte)0x66, (byte)0x01, (byte)0x20, (byte)0x00, (byte)0xE9, (byte)0x00,
- (byte)0x00, (byte)0x00, (byte)0x11, (byte)0xF0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
- };
-
- return new UnknownRecord((short)0x00EC, data);
- }
-
- private void createAxisRecords( List<Record> records )
- {
- records.add( createAxisParentRecord() );
- records.add( createBeginRecord() );
- records.add( createAxisRecord( AxisRecord.AXIS_TYPE_CATEGORY_OR_X_AXIS ) );
- records.add( createBeginRecord() );
- records.add( createCategorySeriesAxisRecord() );
- records.add( createAxisOptionsRecord() );
- records.add( createTickRecord1() );
- records.add( createEndRecord() );
- records.add( createAxisRecord( AxisRecord.AXIS_TYPE_VALUE_AXIS ) );
- records.add( createBeginRecord() );
- records.add( createValueRangeRecord() );
- records.add( createTickRecord2() );
- records.add( createAxisLineFormatRecord( AxisLineFormatRecord.AXIS_TYPE_MAJOR_GRID_LINE ) );
- records.add( createLineFormatRecord(false) );
- records.add( createEndRecord() );
- records.add( createPlotAreaRecord() );
- records.add( createFrameRecord2() );
- records.add( createBeginRecord() );
- records.add( createLineFormatRecord2() );
- records.add( createAreaFormatRecord2() );
- records.add( createEndRecord() );
- records.add( createChartFormatRecord() );
- records.add( createBeginRecord() );
- records.add( createBarRecord() );
- // unknown 1022
- records.add( createLegendRecord() );
- records.add( createBeginRecord() );
- // unknown 104f
- records.add( createTextRecord() );
- records.add( createBeginRecord() );
- // unknown 104f
- records.add( createLinkedDataRecord() );
- records.add( createEndRecord() );
- records.add( createEndRecord() );
- records.add( createEndRecord() );
- records.add( createEndRecord() );
- }
-
- private LinkedDataRecord createLinkedDataRecord()
- {
- LinkedDataRecord r = new LinkedDataRecord();
- r.setLinkType(LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT);
- r.setReferenceType(LinkedDataRecord.REFERENCE_TYPE_DIRECT);
- r.setCustomNumberFormat(false);
- r.setIndexNumberFmtRecord((short)0);
- r.setFormulaOfLink(null);
- return r;
- }
-
- private TextRecord createTextRecord()
- {
- TextRecord r = new TextRecord();
- r.setHorizontalAlignment(TextRecord.HORIZONTAL_ALIGNMENT_CENTER);
- r.setVerticalAlignment(TextRecord.VERTICAL_ALIGNMENT_CENTER);
- r.setDisplayMode((short)1);
- r.setRgbColor(0x00000000);
- r.setX(-37);
- r.setY(-60);
- r.setWidth(0);
- r.setHeight(0);
- r.setAutoColor(true);
- r.setShowKey(false);
- r.setShowValue(false);
- r.setVertical(false);
- r.setAutoGeneratedText(true);
- r.setGenerated(true);
- r.setAutoLabelDeleted(false);
- r.setAutoBackground(true);
- r.setRotation((short)0);
- r.setShowCategoryLabelAsPercentage(false);
- r.setShowValueAsPercentage(false);
- r.setShowBubbleSizes(false);
- r.setShowLabel(false);
- r.setIndexOfColorValue((short)77);
- r.setDataLabelPlacement((short)0);
- r.setTextRotation((short)0);
- return r;
- }
-
- private LegendRecord createLegendRecord()
- {
- LegendRecord r = new LegendRecord();
- r.setXAxisUpperLeft(3542);
- r.setYAxisUpperLeft(1566);
- r.setXSize(437);
- r.setYSize(213);
- r.setType(LegendRecord.TYPE_RIGHT);
- r.setSpacing(LegendRecord.SPACING_MEDIUM);
- r.setAutoPosition(true);
- r.setAutoSeries(true);
- r.setAutoXPositioning(true);
- r.setAutoYPositioning(true);
- r.setVertical(true);
- r.setDataTable(false);
- return r;
- }
-
- private BarRecord createBarRecord()
- {
- BarRecord r = new BarRecord();
- r.setBarSpace((short)0);
- r.setCategorySpace((short)150);
- r.setHorizontal(false);
- r.setStacked(false);
- r.setDisplayAsPercentage(false);
- r.setShadow(false);
- return r;
- }
-
- private ChartFormatRecord createChartFormatRecord()
- {
- ChartFormatRecord r = new ChartFormatRecord();
- r.setXPosition(0);
- r.setYPosition(0);
- r.setWidth(0);
- r.setHeight(0);
- r.setVaryDisplayPattern(false);
- return r;
- }
-
- private PlotAreaRecord createPlotAreaRecord()
- {
+ lastChart.legendRecord = (LegendRecord)r;
+ } else if(r instanceof SeriesRecord) {
+ HSSFSeries series = new HSSFSeries( (SeriesRecord)r );
+ lastChart.series.add(series);
+ lastSeries = series;
+ } else if(r instanceof ChartTitleFormatRecord) {
+ lastChart.chartTitleFormat = (ChartTitleFormatRecord)r;
+ } else if(r instanceof SeriesTextRecord) {
+ // Applies to a series, unless we've seen a legend already
+ SeriesTextRecord str = (SeriesTextRecord)r;
+ if(lastChart.legendRecord == null && lastChart.series.size() > 0) {
+ HSSFSeries series = lastChart.series.get(lastChart.series.size()-1);
+ series.seriesTitleText = str;
+ } else {
+ lastChart.chartTitleText = str;
+ }
+ } else if(r instanceof ValueRangeRecord){
+ lastChart.valueRanges.add((ValueRangeRecord)r);
+ } else if (r instanceof Record) {
+ Record record = (Record) r;
+ for (HSSFChartType type : HSSFChartType.values()) {
+ if (type == HSSFChartType.Unknown) {
+ continue;
+ }
+ if (record.getSid() == type.getSid()) {
+ lastChart.type = type;
+ break;
+ }
+ }
+ }
+ }
+
+ return charts.toArray(new HSSFChart[0]);
+ }
+
+ /** Get the X offset of the chart */
+ public int getChartX() { return chartRecord.getX(); }
+ /** Get the Y offset of the chart */
+ public int getChartY() { return chartRecord.getY(); }
+ /** Get the width of the chart. {@link ChartRecord} */
+ public int getChartWidth() { return chartRecord.getWidth(); }
+ /** Get the height of the chart. {@link ChartRecord} */
+ public int getChartHeight() { return chartRecord.getHeight(); }
+
+ /** Sets the X offset of the chart */
+ public void setChartX(int x) { chartRecord.setX(x); }
+ /** Sets the Y offset of the chart */
+ public void setChartY(int y) { chartRecord.setY(y); }
+ /** Sets the width of the chart. {@link ChartRecord} */
+ public void setChartWidth(int width) { chartRecord.setWidth(width); }
+ /** Sets the height of the chart. {@link ChartRecord} */
+ public void setChartHeight(int height) { chartRecord.setHeight(height); }
+
+ /**
+ * Returns the series of the chart
+ */
+ public HSSFSeries[] getSeries() {
+ return series.toArray(new HSSFSeries[0]);
+ }
+
+ /**
+ * Returns the chart's title, if there is one,
+ * or null if not
+ */
+ public String getChartTitle() {
+ if(chartTitleText != null) {
+ return chartTitleText.getText();
+ }
+ return null;
+ }
+
+ /**
+ * Changes the chart's title, but only if there
+ * was one already.
+ * TODO - add in the records if not
+ */
+ public void setChartTitle(String title) {
+ if(chartTitleText != null) {
+ chartTitleText.setText(title);
+ } else {
+ throw new IllegalStateException("No chart title found to change");
+ }
+ }
+
+ /**
+ * Set value range (basic Axis Options)
+ * @param axisIndex 0 - primary axis, 1 - secondary axis
+ * @param minimum minimum value; Double.NaN - automatic; null - no change
+ * @param maximum maximum value; Double.NaN - automatic; null - no change
+ * @param majorUnit major unit value; Double.NaN - automatic; null - no change
+ * @param minorUnit minor unit value; Double.NaN - automatic; null - no change
+ */
+ public void setValueRange( int axisIndex, Double minimum, Double maximum, Double majorUnit, Double minorUnit){
+ ValueRangeRecord valueRange = valueRanges.get( axisIndex );
+ if( valueRange == null ) return;
+ if( minimum != null ){
+ valueRange.setAutomaticMinimum(minimum.isNaN());
+ valueRange.setMinimumAxisValue(minimum);
+ }
+ if( maximum != null ){
+ valueRange.setAutomaticMaximum(maximum.isNaN());
+ valueRange.setMaximumAxisValue(maximum);
+ }
+ if( majorUnit != null ){
+ valueRange.setAutomaticMajor(majorUnit.isNaN());
+ valueRange.setMajorIncrement(majorUnit);
+ }
+ if( minorUnit != null ){
+ valueRange.setAutomaticMinor(minorUnit.isNaN());
+ valueRange.setMinorIncrement(minorUnit);
+ }
+ }
+
+ private SeriesIndexRecord createSeriesIndexRecord( int index )
+ {
+ SeriesIndexRecord r = new SeriesIndexRecord();
+ r.setIndex((short)index);
+ return r;
+ }
+
+ private DimensionsRecord createDimensionsRecord()
+ {
+ DimensionsRecord r = new DimensionsRecord();
+ r.setFirstRow(0);
+ r.setLastRow(31);
+ r.setFirstCol((short)0);
+ r.setLastCol((short)1);
+ return r;
+ }
+
+ private HCenterRecord createHCenterRecord()
+ {
+ HCenterRecord r = new HCenterRecord();
+ r.setHCenter(false);
+ return r;
+ }
+
+ private VCenterRecord createVCenterRecord()
+ {
+ VCenterRecord r = new VCenterRecord();
+ r.setVCenter(false);
+ return r;
+ }
+
+ private PrintSetupRecord createPrintSetupRecord()
+ {
+ PrintSetupRecord r = new PrintSetupRecord();
+ r.setPaperSize((short)0);
+ r.setScale((short)18);
+ r.setPageStart((short)1);
+ r.setFitWidth((short)1);
+ r.setFitHeight((short)1);
+ r.setLeftToRight(false);
+ r.setLandscape(false);
+ r.setValidSettings(true);
+ r.setNoColor(false);
+ r.setDraft(false);
+ r.setNotes(false);
+ r.setNoOrientation(false);
+ r.setUsePage(false);
+ r.setHResolution((short)0);
+ r.setVResolution((short)0);
+ r.setHeaderMargin(0.5);
+ r.setFooterMargin(0.5);
+ r.setCopies((short)15); // what the ??
+ return r;
+ }
+
+ private FontBasisRecord createFontBasisRecord1()
+ {
+ FontBasisRecord r = new FontBasisRecord();
+ r.setXBasis((short)9120);
+ r.setYBasis((short)5640);
+ r.setHeightBasis((short)200);
+ r.setScale((short)0);
+ r.setIndexToFontTable((short)5);
+ return r;
+ }
+
+ private FontBasisRecord createFontBasisRecord2()
+ {
+ FontBasisRecord r = createFontBasisRecord1();
+ r.setIndexToFontTable((short)6);
+ return r;
+ }
+
+ private BOFRecord createBOFRecord()
+ {
+ BOFRecord r = new BOFRecord();
+ r.setVersion((short)600);
+ r.setType((short)20);
+ r.setBuild((short)0x1CFE);
+ r.setBuildYear((short)1997);
+ r.setHistoryBitMask(0x40C9);
+ r.setRequiredVersion(106);
+ return r;
+ }
+
+ private UnknownRecord createOBJRecord()
+ {
+ byte[] data = {
+ (byte) 0x15, (byte) 0x00, (byte) 0x12, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x11, (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xB8, (byte) 0x03,
+ (byte) 0x87, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+ };
+
+ return new UnknownRecord( (short) 0x005D, data );
+ }
+
+ private UnknownRecord createMSDrawingObjectRecord()
+ {
+ // Since we haven't created this object yet we'll just put in the raw
+ // form for the moment.
+
+ byte[] data = {
+ (byte)0x0F, (byte)0x00, (byte)0x02, (byte)0xF0, (byte)0xC0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x08, (byte)0xF0, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x0F, (byte)0x00, (byte)0x03, (byte)0xF0, (byte)0xA8, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x0F, (byte)0x00, (byte)0x04, (byte)0xF0, (byte)0x28, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0xF0, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x02, (byte)0x00, (byte)0x0A, (byte)0xF0, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x0F, (byte)0x00, (byte)0x04, (byte)0xF0, (byte)0x70, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x92, (byte)0x0C, (byte)0x0A, (byte)0xF0, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x02, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0A, (byte)0x00, (byte)0x00, (byte)0x93, (byte)0x00, (byte)0x0B, (byte)0xF0, (byte)0x36, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x7F, (byte)0x00, (byte)0x04, (byte)0x01, (byte)0x04, (byte)0x01, (byte)0xBF, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x81, (byte)0x01, (byte)0x4E, (byte)0x00,
+ (byte)0x00, (byte)0x08, (byte)0x83, (byte)0x01, (byte)0x4D, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0xBF, (byte)0x01, (byte)0x10, (byte)0x00, (byte)0x11, (byte)0x00, (byte)0xC0, (byte)0x01,
+ (byte)0x4D, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0xFF, (byte)0x01, (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x3F, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00,
+ (byte)0xBF, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0xF0, (byte)0x12, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x04, (byte)0x00, (byte)0xC0, (byte)0x02, (byte)0x0A, (byte)0x00, (byte)0xF4, (byte)0x00, (byte)0x0E, (byte)0x00, (byte)0x66, (byte)0x01, (byte)0x20, (byte)0x00, (byte)0xE9, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x11, (byte)0xF0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
+ };
+
+ return new UnknownRecord((short)0x00EC, data);
+ }
+
+ private void createAxisRecords( List<Record> records )
+ {
+ records.add( createAxisParentRecord() );
+ records.add( createBeginRecord() );
+ records.add( createAxisRecord( AxisRecord.AXIS_TYPE_CATEGORY_OR_X_AXIS ) );
+ records.add( createBeginRecord() );
+ records.add( createCategorySeriesAxisRecord() );
+ records.add( createAxisOptionsRecord() );
+ records.add( createTickRecord1() );
+ records.add( createEndRecord() );
+ records.add( createAxisRecord( AxisRecord.AXIS_TYPE_VALUE_AXIS ) );
+ records.add( createBeginRecord() );
+ records.add( createValueRangeRecord() );
+ records.add( createTickRecord2() );
+ records.add( createAxisLineFormatRecord( AxisLineFormatRecord.AXIS_TYPE_MAJOR_GRID_LINE ) );
+ records.add( createLineFormatRecord(false) );
+ records.add( createEndRecord() );
+ records.add( createPlotAreaRecord() );
+ records.add( createFrameRecord2() );
+ records.add( createBeginRecord() );
+ records.add( createLineFormatRecord2() );
+ records.add( createAreaFormatRecord2() );
+ records.add( createEndRecord() );
+ records.add( createChartFormatRecord() );
+ records.add( createBeginRecord() );
+ records.add( createBarRecord() );
+ // unknown 1022
+ records.add( createLegendRecord() );
+ records.add( createBeginRecord() );
+ // unknown 104f
+ records.add( createTextRecord() );
+ records.add( createBeginRecord() );
+ // unknown 104f
+ records.add( createLinkedDataRecord() );
+ records.add( createEndRecord() );
+ records.add( createEndRecord() );
+ records.add( createEndRecord() );
+ records.add( createEndRecord() );
+ }
+
+ private LinkedDataRecord createLinkedDataRecord()
+ {
+ LinkedDataRecord r = new LinkedDataRecord();
+ r.setLinkType(LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT);
+ r.setReferenceType(LinkedDataRecord.REFERENCE_TYPE_DIRECT);
+ r.setCustomNumberFormat(false);
+ r.setIndexNumberFmtRecord((short)0);
+ r.setFormulaOfLink(null);
+ return r;
+ }
+
+ private TextRecord createTextRecord()
+ {
+ TextRecord r = new TextRecord();
+ r.setHorizontalAlignment(TextRecord.HORIZONTAL_ALIGNMENT_CENTER);
+ r.setVerticalAlignment(TextRecord.VERTICAL_ALIGNMENT_CENTER);
+ r.setDisplayMode((short)1);
+ r.setRgbColor(0x00000000);
+ r.setX(-37);
+ r.setY(-60);
+ r.setWidth(0);
+ r.setHeight(0);
+ r.setAutoColor(true);
+ r.setShowKey(false);
+ r.setShowValue(false);
+ r.setVertical(false);
+ r.setAutoGeneratedText(true);
+ r.setGenerated(true);
+ r.setAutoLabelDeleted(false);
+ r.setAutoBackground(true);
+ r.setRotation((short)0);
+ r.setShowCategoryLabelAsPercentage(false);
+ r.setShowValueAsPercentage(false);
+ r.setShowBubbleSizes(false);
+ r.setShowLabel(false);
+ r.setIndexOfColorValue((short)77);
+ r.setDataLabelPlacement((short)0);
+ r.setTextRotation((short)0);
+ return r;
+ }
+
+ private LegendRecord createLegendRecord()
+ {
+ LegendRecord r = new LegendRecord();
+ r.setXAxisUpperLeft(3542);
+ r.setYAxisUpperLeft(1566);
+ r.setXSize(437);
+ r.setYSize(213);
+ r.setType(LegendRecord.TYPE_RIGHT);
+ r.setSpacing(LegendRecord.SPACING_MEDIUM);
+ r.setAutoPosition(true);
+ r.setAutoSeries(true);
+ r.setAutoXPositioning(true);
+ r.setAutoYPositioning(true);
+ r.setVertical(true);
+ r.setDataTable(false);
+ return r;
+ }
+
+ private BarRecord createBarRecord()
+ {
+ BarRecord r = new BarRecord();
+ r.setBarSpace((short)0);
+ r.setCategorySpace((short)150);
+ r.setHorizontal(false);
+ r.setStacked(false);
+ r.setDisplayAsPercentage(false);
+ r.setShadow(false);
+ return r;
+ }
+
+ private ChartFormatRecord createChartFormatRecord()
+ {
+ ChartFormatRecord r = new ChartFormatRecord();
+ r.setXPosition(0);
+ r.setYPosition(0);
+ r.setWidth(0);
+ r.setHeight(0);
+ r.setVaryDisplayPattern(false);
+ return r;
+ }
+
+ private PlotAreaRecord createPlotAreaRecord()
+ {
return new PlotAreaRecord( );
- }
-
- private AxisLineFormatRecord createAxisLineFormatRecord( short format )
- {
- AxisLineFormatRecord r = new AxisLineFormatRecord();
- r.setAxisType( format );
- return r;
- }
-
- private ValueRangeRecord createValueRangeRecord()
- {
- ValueRangeRecord r = new ValueRangeRecord();
- r.setMinimumAxisValue( 0.0 );
- r.setMaximumAxisValue( 0.0 );
- r.setMajorIncrement( 0 );
- r.setMinorIncrement( 0 );
- r.setCategoryAxisCross( 0 );
- r.setAutomaticMinimum( true );
- r.setAutomaticMaximum( true );
- r.setAutomaticMajor( true );
- r.setAutomaticMinor( true );
- r.setAutomaticCategoryCrossing( true );
- r.setLogarithmicScale( false );
- r.setValuesInReverse( false );
- r.setCrossCategoryAxisAtMaximum( false );
- r.setReserved( true ); // what's this do??
- return r;
- }
-
- private TickRecord createTickRecord1()
- {
- TickRecord r = new TickRecord();
- r.setMajorTickType( (byte) 2 );
- r.setMinorTickType( (byte) 0 );
- r.setLabelPosition( (byte) 3 );
- r.setBackground( (byte) 1 );
- r.setLabelColorRgb( 0 );
- r.setZero1( (short) 0 );
- r.setZero2( (short) 0 );
- r.setZero3( (short) 45 );
- r.setAutorotate( true );
- r.setAutoTextBackground( true );
- r.setRotation( (short) 0 );
- r.setAutorotate( true );
- r.setTickColor( (short) 77 );
- return r;
- }
-
- private TickRecord createTickRecord2()
- {
- TickRecord r = createTickRecord1();
- r.setZero3((short)0);
- return r;
- }
-
- private AxisOptionsRecord createAxisOptionsRecord()
- {
- AxisOptionsRecord r = new AxisOptionsRecord();
- r.setMinimumCategory( (short) -28644 );
- r.setMaximumCategory( (short) -28715 );
- r.setMajorUnitValue( (short) 2 );
- r.setMajorUnit( (short) 0 );
- r.setMinorUnitValue( (short) 1 );
- r.setMinorUnit( (short) 0 );
- r.setBaseUnit( (short) 0 );
- r.setCrossingPoint( (short) -28644 );
- r.setDefaultMinimum( true );
- r.setDefaultMaximum( true );
- r.setDefaultMajor( true );
- r.setDefaultMinorUnit( true );
- r.setIsDate( true );
- r.setDefaultBase( true );
- r.setDefaultCross( true );
- r.setDefaultDateSettings( true );
- return r;
- }
-
- private CategorySeriesAxisRecord createCategorySeriesAxisRecord()
- {
- CategorySeriesAxisRecord r = new CategorySeriesAxisRecord();
- r.setCrossingPoint( (short) 1 );
- r.setLabelFrequency( (short) 1 );
- r.setTickMarkFrequency( (short) 1 );
- r.setValueAxisCrossing( true );
- r.setCrossesFarRight( false );
- r.setReversed( false );
- return r;
- }
-
- private AxisRecord createAxisRecord( short axisType )
- {
- AxisRecord r = new AxisRecord();
- r.setAxisType( axisType );
- return r;
- }
-
- private AxisParentRecord createAxisParentRecord()
- {
- AxisParentRecord r = new AxisParentRecord();
- r.setAxisType( AxisParentRecord.AXIS_TYPE_MAIN );
- r.setX( 479 );
- r.setY( 221 );
- r.setWidth( 2995 );
- r.setHeight( 2902 );
- return r;
- }
-
- private AxisUsedRecord createAxisUsedRecord( short numAxis )
- {
- AxisUsedRecord r = new AxisUsedRecord();
- r.setNumAxis( numAxis );
- return r;
- }
-
- private LinkedDataRecord createDirectLinkRecord()
- {
- LinkedDataRecord r = new LinkedDataRecord();
- r.setLinkType( LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT );
- r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_DIRECT );
- r.setCustomNumberFormat( false );
- r.setIndexNumberFmtRecord( (short) 0 );
- r.setFormulaOfLink(null);
- return r;
- }
-
- private FontIndexRecord createFontIndexRecord( int index )
- {
- FontIndexRecord r = new FontIndexRecord();
- r.setFontIndex( (short) index );
- return r;
- }
-
- private TextRecord createAllTextRecord()
- {
- TextRecord r = new TextRecord();
- r.setHorizontalAlignment( TextRecord.HORIZONTAL_ALIGNMENT_CENTER );
- r.setVerticalAlignment( TextRecord.VERTICAL_ALIGNMENT_CENTER );
- r.setDisplayMode( TextRecord.DISPLAY_MODE_TRANSPARENT );
- r.setRgbColor( 0 );
- r.setX( -37 );
- r.setY( -60 );
- r.setWidth( 0 );
- r.setHeight( 0 );
- r.setAutoColor( true );
- r.setShowKey( false );
- r.setShowValue( true );
- r.setVertical( false );
- r.setAutoGeneratedText( true );
- r.setGenerated( true );
- r.setAutoLabelDeleted( false );
- r.setAutoBackground( true );
- r.setRotation( (short) 0 );
- r.setShowCategoryLabelAsPercentage( false );
- r.setShowValueAsPercentage( false );
- r.setShowBubbleSizes( false );
- r.setShowLabel( false );
- r.setIndexOfColorValue( (short) 77 );
- r.setDataLabelPlacement( (short) 0 );
- r.setTextRotation( (short) 0 );
- return r;
- }
-
- private TextRecord createUnknownTextRecord()
- {
- TextRecord r = new TextRecord();
- r.setHorizontalAlignment( TextRecord.HORIZONTAL_ALIGNMENT_CENTER );
- r.setVerticalAlignment( TextRecord.VERTICAL_ALIGNMENT_CENTER );
- r.setDisplayMode( TextRecord.DISPLAY_MODE_TRANSPARENT );
- r.setRgbColor( 0 );
- r.setX( -37 );
- r.setY( -60 );
- r.setWidth( 0 );
- r.setHeight( 0 );
- r.setAutoColor( true );
- r.setShowKey( false );
- r.setShowValue( false );
- r.setVertical( false );
- r.setAutoGeneratedText( true );
- r.setGenerated( true );
- r.setAutoLabelDeleted( false );
- r.setAutoBackground( true );
- r.setRotation( (short) 0 );
- r.setShowCategoryLabelAsPercentage( false );
- r.setShowValueAsPercentage( false );
- r.setShowBubbleSizes( false );
- r.setShowLabel( false );
- r.setIndexOfColorValue( (short) 77 );
- r.setDataLabelPlacement( (short) 11088 );
- r.setTextRotation( (short) 0 );
- return r;
- }
-
- private DefaultDataLabelTextPropertiesRecord createDefaultTextRecord( short categoryDataType )
- {
- DefaultDataLabelTextPropertiesRecord r = new DefaultDataLabelTextPropertiesRecord();
- r.setCategoryDataType( categoryDataType );
- return r;
- }
-
- private SheetPropertiesRecord createSheetPropsRecord()
- {
- SheetPropertiesRecord r = new SheetPropertiesRecord();
- r.setChartTypeManuallyFormatted( false );
- r.setPlotVisibleOnly( true );
- r.setDoNotSizeWithWindow( false );
- r.setDefaultPlotDimensions( true );
- r.setAutoPlotArea( false );
- return r;
- }
-
- private SeriesToChartGroupRecord createSeriesToChartGroupRecord()
- {
- return new SeriesToChartGroupRecord();
- }
-
- private DataFormatRecord createDataFormatRecord()
- {
- DataFormatRecord r = new DataFormatRecord();
- r.setPointNumber( (short) -1 );
- r.setSeriesIndex( (short) 0 );
- r.setSeriesNumber( (short) 0 );
- r.setUseExcel4Colors( false );
- return r;
- }
-
- private LinkedDataRecord createCategoriesLinkedDataRecord()
- {
- LinkedDataRecord r = new LinkedDataRecord();
- r.setLinkType( LinkedDataRecord.LINK_TYPE_CATEGORIES );
- r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
- r.setCustomNumberFormat( false );
- r.setIndexNumberFmtRecord( (short) 0 );
- Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
- false, false, false, false, 0);
- r.setFormulaOfLink(new Ptg[] { p, });
- return r;
- }
-
- private LinkedDataRecord createValuesLinkedDataRecord()
- {
- LinkedDataRecord r = new LinkedDataRecord();
- r.setLinkType( LinkedDataRecord.LINK_TYPE_VALUES );
- r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
- r.setCustomNumberFormat( false );
- r.setIndexNumberFmtRecord( (short) 0 );
- Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
- false, false, false, false, 0);
- r.setFormulaOfLink(new Ptg[] { p, });
- return r;
- }
-
- private LinkedDataRecord createTitleLinkedDataRecord()
- {
- LinkedDataRecord r = new LinkedDataRecord();
- r.setLinkType( LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT );
- r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_DIRECT );
- r.setCustomNumberFormat( false );
- r.setIndexNumberFmtRecord( (short) 0 );
- r.setFormulaOfLink(null);
- return r;
- }
-
- private SeriesRecord createSeriesRecord()
- {
- SeriesRecord r = new SeriesRecord();
- r.setCategoryDataType( SeriesRecord.CATEGORY_DATA_TYPE_NUMERIC );
- r.setValuesDataType( SeriesRecord.VALUES_DATA_TYPE_NUMERIC );
- r.setNumCategories( (short) 32 );
- r.setNumValues( (short) 31 );
- r.setBubbleSeriesType( SeriesRecord.BUBBLE_SERIES_TYPE_NUMERIC );
- r.setNumBubbleValues( (short) 0 );
- return r;
- }
-
- private EndRecord createEndRecord()
- {
- return new EndRecord();
- }
-
- private AreaFormatRecord createAreaFormatRecord1()
- {
- AreaFormatRecord r = new AreaFormatRecord();
- r.setForegroundColor( 16777215 ); // RGB Color
- r.setBackgroundColor( 0 ); // RGB Color
- r.setPattern( (short) 1 ); // TODO: Add Pattern constants to record
- r.setAutomatic( true );
- r.setInvert( false );
- r.setForecolorIndex( (short) 78 );
- r.setBackcolorIndex( (short) 77 );
- return r;
- }
-
- private AreaFormatRecord createAreaFormatRecord2()
- {
- AreaFormatRecord r = new AreaFormatRecord();
- r.setForegroundColor(0x00c0c0c0);
- r.setBackgroundColor(0x00000000);
- r.setPattern((short)1);
- r.setAutomatic(false);
- r.setInvert(false);
- r.setForecolorIndex((short)22);
- r.setBackcolorIndex((short)79);
- return r;
- }
-
- private LineFormatRecord createLineFormatRecord( boolean drawTicks )
- {
- LineFormatRecord r = new LineFormatRecord();
- r.setLineColor( 0 );
- r.setLinePattern( LineFormatRecord.LINE_PATTERN_SOLID );
- r.setWeight( (short) -1 );
- r.setAuto( true );
- r.setDrawTicks( drawTicks );
- r.setColourPaletteIndex( (short) 77 ); // what colour is this?
- return r;
- }
-
- private LineFormatRecord createLineFormatRecord2()
- {
- LineFormatRecord r = new LineFormatRecord();
- r.setLineColor( 0x00808080 );
- r.setLinePattern( (short) 0 );
- r.setWeight( (short) 0 );
- r.setAuto( false );
- r.setDrawTicks( false );
- r.setUnknown( false );
- r.setColourPaletteIndex( (short) 23 );
- return r;
- }
-
- private FrameRecord createFrameRecord1()
- {
- FrameRecord r = new FrameRecord();
- r.setBorderType( FrameRecord.BORDER_TYPE_REGULAR );
- r.setAutoSize( false );
- r.setAutoPosition( true );
- return r;
- }
-
- private FrameRecord createFrameRecord2()
- {
- FrameRecord r = new FrameRecord();
- r.setBorderType( FrameRecord.BORDER_TYPE_REGULAR );
- r.setAutoSize( true );
- r.setAutoPosition( true );
- return r;
- }
-
- private PlotGrowthRecord createPlotGrowthRecord( int horizScale, int vertScale )
- {
- PlotGrowthRecord r = new PlotGrowthRecord();
- r.setHorizontalScale( horizScale );
- r.setVerticalScale( vertScale );
- return r;
- }
-
- private SCLRecord createSCLRecord( short numerator, short denominator )
- {
- SCLRecord r = new SCLRecord();
- r.setDenominator( denominator );
- r.setNumerator( numerator );
- return r;
- }
-
- private BeginRecord createBeginRecord()
- {
- return new BeginRecord();
- }
-
- private ChartRecord createChartRecord( int x, int y, int width, int height )
- {
- ChartRecord r = new ChartRecord();
- r.setX( x );
- r.setY( y );
- r.setWidth( width );
- r.setHeight( height );
- return r;
- }
-
- private UnitsRecord createUnitsRecord()
- {
- UnitsRecord r = new UnitsRecord();
- r.setUnits( (short) 0 );
- return r;
- }
-
-
- /**
- * A series in a chart
- */
- public static class HSSFSeries {
- private SeriesRecord series;
- private SeriesTextRecord seriesTitleText;
- private LinkedDataRecord dataName;
- private LinkedDataRecord dataValues;
- private LinkedDataRecord dataCategoryLabels;
- private LinkedDataRecord dataSecondaryCategoryLabels;
-
- /* package */ HSSFSeries(SeriesRecord series) {
- this.series = series;
- }
-
- /* package */ void insertData(LinkedDataRecord data){
- switch(data.getLinkType()){
-
- case LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT:
- dataName = data;
- break;
- case LinkedDataRecord.LINK_TYPE_VALUES:
- dataValues = data;
- break;
- case LinkedDataRecord.LINK_TYPE_CATEGORIES:
- dataCategoryLabels = data;
- break;
- case LinkedDataRecord.LINK_TYPE_SECONDARY_CATEGORIES:
- dataSecondaryCategoryLabels = data;
- break;
- default:
- throw new IllegalStateException("Invalid link type: " + data.getLinkType());
- }
- }
-
- /* package */ void setSeriesTitleText(SeriesTextRecord seriesTitleText)
- {
- this.seriesTitleText = seriesTitleText;
- }
-
- public short getNumValues() {
- return series.getNumValues();
- }
- /**
- * See {@link SeriesRecord}
- */
- public short getValueType() {
- return series.getValuesDataType();
- }
-
- /**
- * Returns the series' title, if there is one,
- * or null if not
- */
- public String getSeriesTitle() {
- if(seriesTitleText != null) {
- return seriesTitleText.getText();
- }
- return null;
- }
-
- /**
- * Changes the series' title, but only if there
- * was one already.
- * TODO - add in the records if not
- */
- public void setSeriesTitle(String title) {
- if(seriesTitleText != null) {
- seriesTitleText.setText(title);
- } else {
- throw new IllegalStateException("No series title found to change");
- }
- }
-
- /**
- * @return record with data names
- */
- public LinkedDataRecord getDataName(){
- return dataName;
- }
-
- /**
- * @return record with data values
- */
- public LinkedDataRecord getDataValues(){
- return dataValues;
- }
-
- /**
- * @return record with data category labels
- */
- public LinkedDataRecord getDataCategoryLabels(){
- return dataCategoryLabels;
- }
-
- /**
- * @return record with data secondary category labels
- */
- public LinkedDataRecord getDataSecondaryCategoryLabels() {
- return dataSecondaryCategoryLabels;
- }
-
- /**
- * @return record with series
- */
- public SeriesRecord getSeries() {
- return series;
- }
-
- private CellRangeAddressBase getCellRange(LinkedDataRecord linkedDataRecord) {
- if (linkedDataRecord == null)
- {
- return null ;
- }
-
- int firstRow = 0;
- int lastRow = 0;
- int firstCol = 0;
- int lastCol = 0;
-
- for (Ptg ptg : linkedDataRecord.getFormulaOfLink()) {
- if (ptg instanceof AreaPtgBase) {
- AreaPtgBase areaPtg = (AreaPtgBase) ptg;
-
- firstRow = areaPtg.getFirstRow();
- lastRow = areaPtg.getLastRow();
-
- firstCol = areaPtg.getFirstColumn();
- lastCol = areaPtg.getLastColumn();
- }
- }
-
- return new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
- }
-
- public CellRangeAddressBase getValuesCellRange() {
- return getCellRange(dataValues);
- }
-
- public CellRangeAddressBase getCategoryLabelsCellRange() {
- return getCellRange(dataCategoryLabels);
- }
-
- private Integer setVerticalCellRange(LinkedDataRecord linkedDataRecord,
- CellRangeAddressBase range) {
- if (linkedDataRecord == null)
- {
- return null;
- }
-
- List<Ptg> ptgList = new ArrayList<>();
-
- int rowCount = (range.getLastRow() - range.getFirstRow()) + 1;
- int colCount = (range.getLastColumn() - range.getFirstColumn()) + 1;
-
- for (Ptg ptg : linkedDataRecord.getFormulaOfLink()) {
- if (ptg instanceof AreaPtgBase) {
- AreaPtgBase areaPtg = (AreaPtgBase) ptg;
-
- areaPtg.setFirstRow(range.getFirstRow());
- areaPtg.setLastRow(range.getLastRow());
-
- areaPtg.setFirstColumn(range.getFirstColumn());
- areaPtg.setLastColumn(range.getLastColumn());
- ptgList.add(areaPtg);
- }
- }
-
- linkedDataRecord.setFormulaOfLink(ptgList.toArray(new Ptg[0]));
-
- return rowCount * colCount;
- }
-
- public void setValuesCellRange(CellRangeAddressBase range) {
- Integer count = setVerticalCellRange(dataValues, range);
- if (count == null)
- {
- return;
- }
-
- series.setNumValues((short)(int)count);
- }
-
- public void setCategoryLabelsCellRange(CellRangeAddressBase range) {
- Integer count = setVerticalCellRange(dataCategoryLabels, range);
- if (count == null)
- {
- return;
- }
-
- series.setNumCategories((short)(int)count);
- }
- }
-
- public HSSFSeries createSeries() throws Exception {
- ArrayList<RecordBase> seriesTemplate = new ArrayList<>();
- boolean seriesTemplateFilled = false;
-
- int idx = 0;
- int deep = 0;
- int chartRecordIdx = -1;
- int chartDeep = -1;
- int lastSeriesDeep = -1;
- int endSeriesRecordIdx = -1;
- int seriesIdx = 0;
- final List<RecordBase> records = sheet.getSheet().getRecords();
-
- /* store first series as template and find last series index */
- for(final RecordBase record : records) {
-
- idx++;
-
- if (record instanceof BeginRecord) {
- deep++;
- } else if (record instanceof EndRecord) {
- deep--;
-
- if (lastSeriesDeep == deep) {
- lastSeriesDeep = -1;
- endSeriesRecordIdx = idx;
- if (!seriesTemplateFilled) {
- seriesTemplate.add(record);
- seriesTemplateFilled = true;
- }
- }
-
- if (chartDeep == deep) {
- break;
- }
- }
-
- if (record instanceof ChartRecord) {
- if (record == chartRecord) {
- chartRecordIdx = idx;
- chartDeep = deep;
- }
- } else if (record instanceof SeriesRecord) {
- if (chartRecordIdx != -1) {
- seriesIdx++;
- lastSeriesDeep = deep;
- }
- }
-
- if (lastSeriesDeep != -1 && !seriesTemplateFilled) {
- seriesTemplate.add(record) ;
- }
- }
-
- /* check if a series was found */
- if (endSeriesRecordIdx == -1) {
- return null;
- }
-
- /* next index in the records list where the new series can be inserted */
- idx = endSeriesRecordIdx + 1;
-
- HSSFSeries newSeries = null;
-
- /* duplicate record of the template series */
- ArrayList<RecordBase> clonedRecords = new ArrayList<>();
- for(final RecordBase record : seriesTemplate) {
-
- Record newRecord = null;
-
- if (record instanceof BeginRecord) {
- newRecord = new BeginRecord();
- } else if (record instanceof EndRecord) {
- newRecord = new EndRecord();
- } else if (record instanceof SeriesRecord) {
- SeriesRecord seriesRecord = (SeriesRecord) ((SeriesRecord)record).clone();
- newSeries = new HSSFSeries(seriesRecord);
- newRecord = seriesRecord;
- } else if (record instanceof LinkedDataRecord) {
- LinkedDataRecord linkedDataRecord = ((LinkedDataRecord)record).clone();
- if (newSeries != null) {
- newSeries.insertData(linkedDataRecord);
- }
- newRecord = linkedDataRecord;
- } else if (record instanceof DataFormatRecord) {
- DataFormatRecord dataFormatRecord = ((DataFormatRecord)record).clone();
-
- dataFormatRecord.setSeriesIndex((short)seriesIdx) ;
- dataFormatRecord.setSeriesNumber((short)seriesIdx) ;
-
- newRecord = dataFormatRecord;
- } else if (record instanceof SeriesTextRecord) {
- SeriesTextRecord seriesTextRecord = (SeriesTextRecord) ((SeriesTextRecord)record).clone();
- if (newSeries != null) {
- newSeries.setSeriesTitleText(seriesTextRecord);
- }
- newRecord = seriesTextRecord;
- } else if (record instanceof Record) {
- newRecord = (Record) ((Record)record).clone();
- }
-
- if (newRecord != null)
- {
- clonedRecords.add(newRecord);
- }
- }
-
- /* check if a user model series object was created */
- if (newSeries == null)
- {
- return null;
- }
-
- /* transfer series to record list */
- for(final RecordBase record : clonedRecords) {
- records.add(idx++, record);
- }
-
- return newSeries;
- }
-
- public boolean removeSeries(HSSFSeries remSeries) {
- int deep = 0;
- int chartDeep = -1;
- int lastSeriesDeep = -1;
- int seriesIdx = -1;
- boolean removeSeries = false;
- boolean chartEntered = false;
- boolean result = false;
- final List<RecordBase> records = sheet.getSheet().getRecords();
-
- /* store first series as template and find last series index */
- Iterator<RecordBase> iter = records.iterator();
- while (iter.hasNext()) {
- RecordBase record = iter.next();
-
- if (record instanceof BeginRecord) {
- deep++;
- } else if (record instanceof EndRecord) {
- deep--;
-
- if (lastSeriesDeep == deep) {
- lastSeriesDeep = -1;
-
- if (removeSeries) {
- removeSeries = false;
- result = true;
- iter.remove();
- }
- }
-
- if (chartDeep == deep) {
- break;
- }
- }
-
- if (record instanceof ChartRecord) {
- if (record == chartRecord) {
- chartDeep = deep;
- chartEntered = true;
- }
- } else if (record instanceof SeriesRecord) {
- if (chartEntered) {
- if (remSeries.series == record) {
- lastSeriesDeep = deep;
- removeSeries = true;
- } else {
- seriesIdx++;
- }
- }
- } else if (record instanceof DataFormatRecord) {
- if (chartEntered && !removeSeries) {
- DataFormatRecord dataFormatRecord = (DataFormatRecord) record;
- dataFormatRecord.setSeriesIndex((short) seriesIdx);
- dataFormatRecord.setSeriesNumber((short) seriesIdx);
- }
- }
-
- if (removeSeries) {
- iter.remove();
- }
- }
-
- return result;
- }
-
- public HSSFChartType getType() {
- return type;
- }
+ }
+
+ private AxisLineFormatRecord createAxisLineFormatRecord( short format )
+ {
+ AxisLineFormatRecord r = new AxisLineFormatRecord();
+ r.setAxisType( format );
+ return r;
+ }
+
+ private ValueRangeRecord createValueRangeRecord()
+ {
+ ValueRangeRecord r = new ValueRangeRecord();
+ r.setMinimumAxisValue( 0.0 );
+ r.setMaximumAxisValue( 0.0 );
+ r.setMajorIncrement( 0 );
+ r.setMinorIncrement( 0 );
+ r.setCategoryAxisCross( 0 );
+ r.setAutomaticMinimum( true );
+ r.setAutomaticMaximum( true );
+ r.setAutomaticMajor( true );
+ r.setAutomaticMinor( true );
+ r.setAutomaticCategoryCrossing( true );
+ r.setLogarithmicScale( false );
+ r.setValuesInReverse( false );
+ r.setCrossCategoryAxisAtMaximum( false );
+ r.setReserved( true ); // what's this do??
+ return r;
+ }
+
+ private TickRecord createTickRecord1()
+ {
+ TickRecord r = new TickRecord();
+ r.setMajorTickType( (byte) 2 );
+ r.setMinorTickType( (byte) 0 );
+ r.setLabelPosition( (byte) 3 );
+ r.setBackground( (byte) 1 );
+ r.setLabelColorRgb( 0 );
+ r.setZero1( (short) 0 );
+ r.setZero2( (short) 0 );
+ r.setZero3( (short) 45 );
+ r.setAutorotate( true );
+ r.setAutoTextBackground( true );
+ r.setRotation( (short) 0 );
+ r.setAutorotate( true );
+ r.setTickColor( (short) 77 );
+ return r;
+ }
+
+ private TickRecord createTickRecord2()
+ {
+ TickRecord r = createTickRecord1();
+ r.setZero3((short)0);
+ return r;
+ }
+
+ private AxisOptionsRecord createAxisOptionsRecord()
+ {
+ AxisOptionsRecord r = new AxisOptionsRecord();
+ r.setMinimumCategory( (short) -28644 );
+ r.setMaximumCategory( (short) -28715 );
+ r.setMajorUnitValue( (short) 2 );
+ r.setMajorUnit( (short) 0 );
+ r.setMinorUnitValue( (short) 1 );
+ r.setMinorUnit( (short) 0 );
+ r.setBaseUnit( (short) 0 );
+ r.setCrossingPoint( (short) -28644 );
+ r.setDefaultMinimum( true );
+ r.setDefaultMaximum( true );
+ r.setDefaultMajor( true );
+ r.setDefaultMinorUnit( true );
+ r.setIsDate( true );
+ r.setDefaultBase( true );
+ r.setDefaultCross( true );
+ r.setDefaultDateSettings( true );
+ return r;
+ }
+
+ private CategorySeriesAxisRecord createCategorySeriesAxisRecord()
+ {
+ CategorySeriesAxisRecord r = new CategorySeriesAxisRecord();
+ r.setCrossingPoint( (short) 1 );
+ r.setLabelFrequency( (short) 1 );
+ r.setTickMarkFrequency( (short) 1 );
+ r.setValueAxisCrossing( true );
+ r.setCrossesFarRight( false );
+ r.setReversed( false );
+ return r;
+ }
+
+ private AxisRecord createAxisRecord( short axisType )
+ {
+ AxisRecord r = new AxisRecord();
+ r.setAxisType( axisType );
+ return r;
+ }
+
+ private AxisParentRecord createAxisParentRecord()
+ {
+ AxisParentRecord r = new AxisParentRecord();
+ r.setAxisType( AxisParentRecord.AXIS_TYPE_MAIN );
+ r.setX( 479 );
+ r.setY( 221 );
+ r.setWidth( 2995 );
+ r.setHeight( 2902 );
+ return r;
+ }
+
+ private AxisUsedRecord createAxisUsedRecord( short numAxis )
+ {
+ AxisUsedRecord r = new AxisUsedRecord();
+ r.setNumAxis( numAxis );
+ return r;
+ }
+
+ private LinkedDataRecord createDirectLinkRecord()
+ {
+ LinkedDataRecord r = new LinkedDataRecord();
+ r.setLinkType( LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT );
+ r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_DIRECT );
+ r.setCustomNumberFormat( false );
+ r.setIndexNumberFmtRecord( (short) 0 );
+ r.setFormulaOfLink(null);
+ return r;
+ }
+
+ private FontIndexRecord createFontIndexRecord( int index )
+ {
+ FontIndexRecord r = new FontIndexRecord();
+ r.setFontIndex( (short) index );
+ return r;
+ }
+
+ private TextRecord createAllTextRecord()
+ {
+ TextRecord r = new TextRecord();
+ r.setHorizontalAlignment( TextRecord.HORIZONTAL_ALIGNMENT_CENTER );
+ r.setVerticalAlignment( TextRecord.VERTICAL_ALIGNMENT_CENTER );
+ r.setDisplayMode( TextRecord.DISPLAY_MODE_TRANSPARENT );
+ r.setRgbColor( 0 );
+ r.setX( -37 );
+ r.setY( -60 );
+ r.setWidth( 0 );
+ r.setHeight( 0 );
+ r.setAutoColor( true );
+ r.setShowKey( false );
+ r.setShowValue( true );
+ r.setVertical( false );
+ r.setAutoGeneratedText( true );
+ r.setGenerated( true );
+ r.setAutoLabelDeleted( false );
+ r.setAutoBackground( true );
+ r.setRotation( (short) 0 );
+ r.setShowCategoryLabelAsPercentage( false );
+ r.setShowValueAsPercentage( false );
+ r.setShowBubbleSizes( false );
+ r.setShowLabel( false );
+ r.setIndexOfColorValue( (short) 77 );
+ r.setDataLabelPlacement( (short) 0 );
+ r.setTextRotation( (short) 0 );
+ return r;
+ }
+
+ private TextRecord createUnknownTextRecord()
+ {
+ TextRecord r = new TextRecord();
+ r.setHorizontalAlignment( TextRecord.HORIZONTAL_ALIGNMENT_CENTER );
+ r.setVerticalAlignment( TextRecord.VERTICAL_ALIGNMENT_CENTER );
+ r.setDisplayMode( TextRecord.DISPLAY_MODE_TRANSPARENT );
+ r.setRgbColor( 0 );
+ r.setX( -37 );
+ r.setY( -60 );
+ r.setWidth( 0 );
+ r.setHeight( 0 );
+ r.setAutoColor( true );
+ r.setShowKey( false );
+ r.setShowValue( false );
+ r.setVertical( false );
+ r.setAutoGeneratedText( true );
+ r.setGenerated( true );
+ r.setAutoLabelDeleted( false );
+ r.setAutoBackground( true );
+ r.setRotation( (short) 0 );
+ r.setShowCategoryLabelAsPercentage( false );
+ r.setShowValueAsPercentage( false );
+ r.setShowBubbleSizes( false );
+ r.setShowLabel( false );
+ r.setIndexOfColorValue( (short) 77 );
+ r.setDataLabelPlacement( (short) 11088 );
+ r.setTextRotation( (short) 0 );
+ return r;
+ }
+
+ private DefaultDataLabelTextPropertiesRecord createDefaultTextRecord( short categoryDataType )
+ {
+ DefaultDataLabelTextPropertiesRecord r = new DefaultDataLabelTextPropertiesRecord();
+ r.setCategoryDataType( categoryDataType );
+ return r;
+ }
+
+ private SheetPropertiesRecord createSheetPropsRecord()
+ {
+ SheetPropertiesRecord r = new SheetPropertiesRecord();
+ r.setChartTypeManuallyFormatted( false );
+ r.setPlotVisibleOnly( true );
+ r.setDoNotSizeWithWindow( false );
+ r.setDefaultPlotDimensions( true );
+ r.setAutoPlotArea( false );
+ return r;
+ }
+
+ private SeriesToChartGroupRecord createSeriesToChartGroupRecord()
+ {
+ return new SeriesToChartGroupRecord();
+ }
+
+ private DataFormatRecord createDataFormatRecord()
+ {
+ DataFormatRecord r = new DataFormatRecord();
+ r.setPointNumber( (short) -1 );
+ r.setSeriesIndex( (short) 0 );
+ r.setSeriesNumber( (short) 0 );
+ r.setUseExcel4Colors( false );
+ return r;
+ }
+
+ private LinkedDataRecord createCategoriesLinkedDataRecord()
+ {
+ LinkedDataRecord r = new LinkedDataRecord();
+ r.setLinkType( LinkedDataRecord.LINK_TYPE_CATEGORIES );
+ r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
+ r.setCustomNumberFormat( false );
+ r.setIndexNumberFmtRecord( (short) 0 );
+ Area3DPtg p = new Area3DPtg(0, 31, 1, 1,
+ false, false, false, false, 0);
+ r.setFormulaOfLink(new Ptg[] { p, });
+ return r;
+ }
+
+ private LinkedDataRecord createValuesLinkedDataRecord()
+ {
+ LinkedDataRecord r = new LinkedDataRecord();
+ r.setLinkType( LinkedDataRecord.LINK_TYPE_VALUES );
+ r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_WORKSHEET );
+ r.setCustomNumberFormat( false );
+ r.setIndexNumberFmtRecord( (short) 0 );
+ Area3DPtg p = new Area3DPtg(0, 31, 0, 0,
+ false, false, false, false, 0);
+ r.setFormulaOfLink(new Ptg[] { p, });
+ return r;
+ }
+
+ private LinkedDataRecord createTitleLinkedDataRecord()
+ {
+ LinkedDataRecord r = new LinkedDataRecord();
+ r.setLinkType( LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT );
+ r.setReferenceType( LinkedDataRecord.REFERENCE_TYPE_DIRECT );
+ r.setCustomNumberFormat( false );
+ r.setIndexNumberFmtRecord( (short) 0 );
+ r.setFormulaOfLink(null);
+ return r;
+ }
+
+ private SeriesRecord createSeriesRecord()
+ {
+ SeriesRecord r = new SeriesRecord();
+ r.setCategoryDataType( SeriesRecord.CATEGORY_DATA_TYPE_NUMERIC );
+ r.setValuesDataType( SeriesRecord.VALUES_DATA_TYPE_NUMERIC );
+ r.setNumCategories( (short) 32 );
+ r.setNumValues( (short) 31 );
+ r.setBubbleSeriesType( SeriesRecord.BUBBLE_SERIES_TYPE_NUMERIC );
+ r.setNumBubbleValues( (short) 0 );
+ return r;
+ }
+
+ private EndRecord createEndRecord()
+ {
+ return new EndRecord();
+ }
+
+ private AreaFormatRecord createAreaFormatRecord1()
+ {
+ AreaFormatRecord r = new AreaFormatRecord();
+ r.setForegroundColor( 16777215 ); // RGB Color
+ r.setBackgroundColor( 0 ); // RGB Color
+ r.setPattern( (short) 1 ); // TODO: Add Pattern constants to record
+ r.setAutomatic( true );
+ r.setInvert( false );
+ r.setForecolorIndex( (short) 78 );
+ r.setBackcolorIndex( (short) 77 );
+ return r;
+ }
+
+ private AreaFormatRecord createAreaFormatRecord2()
+ {
+ AreaFormatRecord r = new AreaFormatRecord();
+ r.setForegroundColor(0x00c0c0c0);
+ r.setBackgroundColor(0x00000000);
+ r.setPattern((short)1);
+ r.setAutomatic(false);
+ r.setInvert(false);
+ r.setForecolorIndex((short)22);
+ r.setBackcolorIndex((short)79);
+ return r;
+ }
+
+ private LineFormatRecord createLineFormatRecord( boolean drawTicks )
+ {
+ LineFormatRecord r = new LineFormatRecord();
+ r.setLineColor( 0 );
+ r.setLinePattern( LineFormatRecord.LINE_PATTERN_SOLID );
+ r.setWeight( (short) -1 );
+ r.setAuto( true );
+ r.setDrawTicks( drawTicks );
+ r.setColourPaletteIndex( (short) 77 ); // what colour is this?
+ return r;
+ }
+
+ private LineFormatRecord createLineFormatRecord2()
+ {
+ LineFormatRecord r = new LineFormatRecord();
+ r.setLineColor( 0x00808080 );
+ r.setLinePattern( (short) 0 );
+ r.setWeight( (short) 0 );
+ r.setAuto( false );
+ r.setDrawTicks( false );
+ r.setUnknown( false );
+ r.setColourPaletteIndex( (short) 23 );
+ return r;
+ }
+
+ private FrameRecord createFrameRecord1()
+ {
+ FrameRecord r = new FrameRecord();
+ r.setBorderType( FrameRecord.BORDER_TYPE_REGULAR );
+ r.setAutoSize( false );
+ r.setAutoPosition( true );
+ return r;
+ }
+
+ private FrameRecord createFrameRecord2()
+ {
+ FrameRecord r = new FrameRecord();
+ r.setBorderType( FrameRecord.BORDER_TYPE_REGULAR );
+ r.setAutoSize( true );
+ r.setAutoPosition( true );
+ return r;
+ }
+
+ private PlotGrowthRecord createPlotGrowthRecord( int horizScale, int vertScale )
+ {
+ PlotGrowthRecord r = new PlotGrowthRecord();
+ r.setHorizontalScale( horizScale );
+ r.setVerticalScale( vertScale );
+ return r;
+ }
+
+ private SCLRecord createSCLRecord( short numerator, short denominator )
+ {
+ SCLRecord r = new SCLRecord();
+ r.setDenominator( denominator );
+ r.setNumerator( numerator );
+ return r;
+ }
+
+ private BeginRecord createBeginRecord()
+ {
+ return new BeginRecord();
+ }
+
+ private ChartRecord createChartRecord( int x, int y, int width, int height )
+ {
+ ChartRecord r = new ChartRecord();
+ r.setX( x );
+ r.setY( y );
+ r.setWidth( width );
+ r.setHeight( height );
+ return r;
+ }
+
+ private UnitsRecord createUnitsRecord()
+ {
+ UnitsRecord r = new UnitsRecord();
+ r.setUnits( (short) 0 );
+ return r;
+ }
+
+
+ /**
+ * A series in a chart
+ */
+ public static class HSSFSeries {
+ private SeriesRecord series;
+ private SeriesTextRecord seriesTitleText;
+ private LinkedDataRecord dataName;
+ private LinkedDataRecord dataValues;
+ private LinkedDataRecord dataCategoryLabels;
+ private LinkedDataRecord dataSecondaryCategoryLabels;
+
+ /* package */ HSSFSeries(SeriesRecord series) {
+ this.series = series;
+ }
+
+ /* package */ void insertData(LinkedDataRecord data){
+ switch(data.getLinkType()){
+
+ case LinkedDataRecord.LINK_TYPE_TITLE_OR_TEXT:
+ dataName = data;
+ break;
+ case LinkedDataRecord.LINK_TYPE_VALUES:
+ dataValues = data;
+ break;
+ case LinkedDataRecord.LINK_TYPE_CATEGORIES:
+ dataCategoryLabels = data;
+ break;
+ case LinkedDataRecord.LINK_TYPE_SECONDARY_CATEGORIES:
+ dataSecondaryCategoryLabels = data;
+ break;
+ default:
+ throw new IllegalStateException("Invalid link type: " + data.getLinkType());
+ }
+ }
+
+ /* package */ void setSeriesTitleText(SeriesTextRecord seriesTitleText)
+ {
+ this.seriesTitleText = seriesTitleText;
+ }
+
+ public short getNumValues() {
+ return series.getNumValues();
+ }
+ /**
+ * See {@link SeriesRecord}
+ */
+ public short getValueType() {
+ return series.getValuesDataType();
+ }
+
+ /**
+ * Returns the series' title, if there is one,
+ * or null if not
+ */
+ public String getSeriesTitle() {
+ if(seriesTitleText != null) {
+ return seriesTitleText.getText();
+ }
+ return null;
+ }
+
+ /**
+ * Changes the series' title, but only if there
+ * was one already.
+ * TODO - add in the records if not
+ */
+ public void setSeriesTitle(String title) {
+ if(seriesTitleText != null) {
+ seriesTitleText.setText(title);
+ } else {
+ throw new IllegalStateException("No series title found to change");
+ }
+ }
+
+ /**
+ * @return record with data names
+ */
+ public LinkedDataRecord getDataName(){
+ return dataName;
+ }
+
+ /**
+ * @return record with data values
+ */
+ public LinkedDataRecord getDataValues(){
+ return dataValues;
+ }
+
+ /**
+ * @return record with data category labels
+ */
+ public LinkedDataRecord getDataCategoryLabels(){
+ return dataCategoryLabels;
+ }
+
+ /**
+ * @return record with data secondary category labels
+ */
+ public LinkedDataRecord getDataSecondaryCategoryLabels() {
+ return dataSecondaryCategoryLabels;
+ }
+
+ /**
+ * @return record with series
+ */
+ public SeriesRecord getSeries() {
+ return series;
+ }
+
+ private CellRangeAddressBase getCellRange(LinkedDataRecord linkedDataRecord) {
+ if (linkedDataRecord == null)
+ {
+ return null ;
+ }
+
+ int firstRow = 0;
+ int lastRow = 0;
+ int firstCol = 0;
+ int lastCol = 0;
+
+ for (Ptg ptg : linkedDataRecord.getFormulaOfLink()) {
+ if (ptg instanceof AreaPtgBase) {
+ AreaPtgBase areaPtg = (AreaPtgBase) ptg;
+
+ firstRow = areaPtg.getFirstRow();
+ lastRow = areaPtg.getLastRow();
+
+ firstCol = areaPtg.getFirstColumn();
+ lastCol = areaPtg.getLastColumn();
+ }
+ }
+
+ return new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
+ }
+
+ public CellRangeAddressBase getValuesCellRange() {
+ return getCellRange(dataValues);
+ }
+
+ public CellRangeAddressBase getCategoryLabelsCellRange() {
+ return getCellRange(dataCategoryLabels);
+ }
+
+ private Integer setVerticalCellRange(LinkedDataRecord linkedDataRecord,
+ CellRangeAddressBase range) {
+ if (linkedDataRecord == null)
+ {
+ return null;
+ }
+
+ List<Ptg> ptgList = new ArrayList<>();
+
+ int rowCount = (range.getLastRow() - range.getFirstRow()) + 1;
+ int colCount = (range.getLastColumn() - range.getFirstColumn()) + 1;
+
+ for (Ptg ptg : linkedDataRecord.getFormulaOfLink()) {
+ if (ptg instanceof AreaPtgBase) {
+ AreaPtgBase areaPtg = (AreaPtgBase) ptg;
+
+ areaPtg.setFirstRow(range.getFirstRow());
+ areaPtg.setLastRow(range.getLastRow());
+
+ areaPtg.setFirstColumn(range.getFirstColumn());
+ areaPtg.setLastColumn(range.getLastColumn());
+ ptgList.add(areaPtg);
+ }
+ }
+
+ linkedDataRecord.setFormulaOfLink(ptgList.toArray(new Ptg[0]));
+
+ return rowCount * colCount;
+ }
+
+ public void setValuesCellRange(CellRangeAddressBase range) {
+ Integer count = setVerticalCellRange(dataValues, range);
+ if (count == null)
+ {
+ return;
+ }
+
+ series.setNumValues((short)(int)count);
+ }
+
+ public void setCategoryLabelsCellRange(CellRangeAddressBase range) {
+ Integer count = setVerticalCellRange(dataCategoryLabels, range);
+ if (count == null)
+ {
+ return;
+ }
+
+ series.setNumCategories((short)(int)count);
+ }
+ }
+
+ public HSSFSeries createSeries() throws Exception {
+ ArrayList<RecordBase> seriesTemplate = new ArrayList<>();
+ boolean seriesTemplateFilled = false;
+
+ int idx = 0;
+ int deep = 0;
+ int chartRecordIdx = -1;
+ int chartDeep = -1;
+ int lastSeriesDeep = -1;
+ int endSeriesRecordIdx = -1;
+ int seriesIdx = 0;
+ final List<RecordBase> records = sheet.getSheet().getRecords();
+
+ /* store first series as template and find last series index */
+ for(final RecordBase record : records) {
+
+ idx++;
+
+ if (record instanceof BeginRecord) {
+ deep++;
+ } else if (record instanceof EndRecord) {
+ deep--;
+
+ if (lastSeriesDeep == deep) {
+ lastSeriesDeep = -1;
+ endSeriesRecordIdx = idx;
+ if (!seriesTemplateFilled) {
+ seriesTemplate.add(record);
+ seriesTemplateFilled = true;
+ }
+ }
+
+ if (chartDeep == deep) {
+ break;
+ }
+ }
+
+ if (record instanceof ChartRecord) {
+ if (record == chartRecord) {
+ chartRecordIdx = idx;
+ chartDeep = deep;
+ }
+ } else if (record instanceof SeriesRecord) {
+ if (chartRecordIdx != -1) {
+ seriesIdx++;
+ lastSeriesDeep = deep;
+ }
+ }
+
+ if (lastSeriesDeep != -1 && !seriesTemplateFilled) {
+ seriesTemplate.add(record) ;
+ }
+ }
+
+ /* check if a series was found */
+ if (endSeriesRecordIdx == -1) {
+ return null;
+ }
+
+ /* next index in the records list where the new series can be inserted */
+ idx = endSeriesRecordIdx + 1;
+
+ HSSFSeries newSeries = null;
+
+ /* duplicate record of the template series */
+ ArrayList<RecordBase> clonedRecords = new ArrayList<>();
+ for(final RecordBase record : seriesTemplate) {
+
+ Record newRecord = null;
+
+ if (record instanceof BeginRecord) {
+ newRecord = new BeginRecord();
+ } else if (record instanceof EndRecord) {
+ newRecord = new EndRecord();
+ } else if (record instanceof SeriesRecord) {
+ SeriesRecord seriesRecord = (SeriesRecord) ((SeriesRecord)record).clone();
+ newSeries = new HSSFSeries(seriesRecord);
+ newRecord = seriesRecord;
+ } else if (record instanceof LinkedDataRecord) {
+ LinkedDataRecord linkedDataRecord = ((LinkedDataRecord)record).clone();
+ if (newSeries != null) {
+ newSeries.insertData(linkedDataRecord);
+ }
+ newRecord = linkedDataRecord;
+ } else if (record instanceof DataFormatRecord) {
+ DataFormatRecord dataFormatRecord = ((DataFormatRecord)record).clone();
+
+ dataFormatRecord.setSeriesIndex((short)seriesIdx) ;
+ dataFormatRecord.setSeriesNumber((short)seriesIdx) ;
+
+ newRecord = dataFormatRecord;
+ } else if (record instanceof SeriesTextRecord) {
+ SeriesTextRecord seriesTextRecord = (SeriesTextRecord) ((SeriesTextRecord)record).clone();
+ if (newSeries != null) {
+ newSeries.setSeriesTitleText(seriesTextRecord);
+ }
+ newRecord = seriesTextRecord;
+ } else if (record instanceof Record) {
+ newRecord = (Record) ((Record)record).clone();
+ }
+
+ if (newRecord != null)
+ {
+ clonedRecords.add(newRecord);
+ }
+ }
+
+ /* check if a user model series object was created */
+ if (newSeries == null)
+ {
+ return null;
+ }
+
+ /* transfer series to record list */
+ for(final RecordBase record : clonedRecords) {
+ records.add(idx++, record);
+ }
+
+ return newSeries;
+ }
+
+ public boolean removeSeries(HSSFSeries remSeries) {
+ int deep = 0;
+ int chartDeep = -1;
+ int lastSeriesDeep = -1;
+ int seriesIdx = -1;
+ boolean removeSeries = false;
+ boolean chartEntered = false;
+ boolean result = false;
+ final List<RecordBase> records = sheet.getSheet().getRecords();
+
+ /* store first series as template and find last series index */
+ Iterator<RecordBase> iter = records.iterator();
+ while (iter.hasNext()) {
+ RecordBase record = iter.next();
+
+ if (record instanceof BeginRecord) {
+ deep++;
+ } else if (record instanceof EndRecord) {
+ deep--;
+
+ if (lastSeriesDeep == deep) {
+ lastSeriesDeep = -1;
+
+ if (removeSeries) {
+ removeSeries = false;
+ result = true;
+ iter.remove();
+ }
+ }
+
+ if (chartDeep == deep) {
+ break;
+ }
+ }
+
+ if (record instanceof ChartRecord) {
+ if (record == chartRecord) {
+ chartDeep = deep;
+ chartEntered = true;
+ }
+ } else if (record instanceof SeriesRecord) {
+ if (chartEntered) {
+ if (remSeries.series == record) {
+ lastSeriesDeep = deep;
+ removeSeries = true;
+ } else {
+ seriesIdx++;
+ }
+ }
+ } else if (record instanceof DataFormatRecord) {
+ if (chartEntered && !removeSeries) {
+ DataFormatRecord dataFormatRecord = (DataFormatRecord) record;
+ dataFormatRecord.setSeriesIndex((short) seriesIdx);
+ dataFormatRecord.setSeriesNumber((short) seriesIdx);
+ }
+ }
+
+ if (removeSeries) {
+ iter.remove();
+ }
+ }
+
+ return result;
+ }
+
+ public HSSFChartType getType() {
+ return type;
+ }
}