Patch from Jens Gotze from bug #49581 - Ability to add, modify and remove series from HSSF Charts
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@964855 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7732426887
commit
bea0801c24
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.7-beta2" date="2010-??-??">
|
<release version="3.7-beta2" date="2010-??-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add">49581 - Ability to add, modify and remove series from HSSF Charts</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">49185 - Support for HSSFNames where the comment is stored in a NameCommentRecord</action>
|
<action dev="POI-DEVELOPERS" type="add">49185 - Support for HSSFNames where the comment is stored in a NameCommentRecord</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">49599 - Correct writing of NoteRecord author text when switching between ASCII and Unicode</action>
|
<action dev="POI-DEVELOPERS" type="fix">49599 - Correct writing of NoteRecord author text when switching between ASCII and Unicode</action>
|
||||||
<action dev="POI-DEVELOPERS" type="fix">HWPF: Improve reading of auto-saved ("complex") documents</action>
|
<action dev="POI-DEVELOPERS" type="fix">HWPF: Improve reading of auto-saved ("complex") documents</action>
|
||||||
|
@ -232,6 +232,7 @@ public final class RecordFactory {
|
|||||||
ChartStartObjectRecord.class,
|
ChartStartObjectRecord.class,
|
||||||
ChartEndObjectRecord.class,
|
ChartEndObjectRecord.class,
|
||||||
CatLabRecord.class,
|
CatLabRecord.class,
|
||||||
|
DataFormatRecord.class,
|
||||||
EndRecord.class,
|
EndRecord.class,
|
||||||
LinkedDataRecord.class,
|
LinkedDataRecord.class,
|
||||||
SeriesToChartGroupRecord.class,
|
SeriesToChartGroupRecord.class,
|
||||||
|
@ -35,6 +35,9 @@ public final class ChartEndBlockRecord extends StandardRecord {
|
|||||||
private short iObjectKind;
|
private short iObjectKind;
|
||||||
private byte[] unused;
|
private byte[] unused;
|
||||||
|
|
||||||
|
public ChartEndBlockRecord() {
|
||||||
|
}
|
||||||
|
|
||||||
public ChartEndBlockRecord(RecordInputStream in) {
|
public ChartEndBlockRecord(RecordInputStream in) {
|
||||||
rt = in.readShort();
|
rt = in.readShort();
|
||||||
grbitFrt = in.readShort();
|
grbitFrt = in.readShort();
|
||||||
@ -80,4 +83,16 @@ public final class ChartEndBlockRecord extends StandardRecord {
|
|||||||
buffer.append("[/ENDBLOCK]\n");
|
buffer.append("[/ENDBLOCK]\n");
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChartEndBlockRecord clone() {
|
||||||
|
ChartEndBlockRecord record = new ChartEndBlockRecord();
|
||||||
|
|
||||||
|
record.rt = rt ;
|
||||||
|
record.grbitFrt = grbitFrt ;
|
||||||
|
record.iObjectKind = iObjectKind ;
|
||||||
|
record.unused = unused.clone() ;
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,9 @@ public final class ChartStartBlockRecord extends StandardRecord {
|
|||||||
private short iObjectInstance1;
|
private short iObjectInstance1;
|
||||||
private short iObjectInstance2;
|
private short iObjectInstance2;
|
||||||
|
|
||||||
|
public ChartStartBlockRecord() {
|
||||||
|
}
|
||||||
|
|
||||||
public ChartStartBlockRecord(RecordInputStream in) {
|
public ChartStartBlockRecord(RecordInputStream in) {
|
||||||
rt = in.readShort();
|
rt = in.readShort();
|
||||||
grbitFrt = in.readShort();
|
grbitFrt = in.readShort();
|
||||||
@ -80,4 +83,18 @@ public final class ChartStartBlockRecord extends StandardRecord {
|
|||||||
buffer.append("[/STARTBLOCK]\n");
|
buffer.append("[/STARTBLOCK]\n");
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChartStartBlockRecord clone() {
|
||||||
|
ChartStartBlockRecord record = new ChartStartBlockRecord();
|
||||||
|
|
||||||
|
record.rt = rt;
|
||||||
|
record.grbitFrt = grbitFrt;
|
||||||
|
record.iObjectKind = iObjectKind;
|
||||||
|
record.iObjectContext = iObjectContext;
|
||||||
|
record.iObjectInstance1 = iObjectInstance1;
|
||||||
|
record.iObjectInstance2 = iObjectInstance2;
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.hssf.record.chart.*;
|
import org.apache.poi.hssf.record.chart.*;
|
||||||
@ -35,8 +36,10 @@ import org.apache.poi.hssf.record.SCLRecord;
|
|||||||
import org.apache.poi.hssf.record.UnknownRecord;
|
import org.apache.poi.hssf.record.UnknownRecord;
|
||||||
import org.apache.poi.hssf.record.VCenterRecord;
|
import org.apache.poi.hssf.record.VCenterRecord;
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||||
|
import org.apache.poi.hssf.record.formula.AreaPtgBase;
|
||||||
import org.apache.poi.hssf.record.formula.Ptg;
|
import org.apache.poi.hssf.record.formula.Ptg;
|
||||||
import org.apache.poi.hssf.record.chart.LinkedDataRecord;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddressBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has methods for construction of a chart object.
|
* Has methods for construction of a chart object.
|
||||||
@ -44,6 +47,7 @@ import org.apache.poi.hssf.record.chart.LinkedDataRecord;
|
|||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public final class HSSFChart {
|
public final class HSSFChart {
|
||||||
|
private HSSFSheet sheet;
|
||||||
private ChartRecord chartRecord;
|
private ChartRecord chartRecord;
|
||||||
|
|
||||||
private LegendRecord legendRecord;
|
private LegendRecord legendRecord;
|
||||||
@ -51,10 +55,54 @@ public final class HSSFChart {
|
|||||||
private SeriesTextRecord chartTitleText;
|
private SeriesTextRecord chartTitleText;
|
||||||
private List<ValueRangeRecord> valueRanges = new ArrayList<ValueRangeRecord>();
|
private List<ValueRangeRecord> valueRanges = new ArrayList<ValueRangeRecord>();
|
||||||
|
|
||||||
|
private HSSFChartType type = HSSFChartType.Unknown;
|
||||||
|
|
||||||
private List<HSSFSeries> series = new ArrayList<HSSFSeries>();
|
private List<HSSFSeries> series = new ArrayList<HSSFSeries>();
|
||||||
|
|
||||||
private HSSFChart(ChartRecord chartRecord) {
|
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.chartRecord = chartRecord;
|
||||||
|
this.sheet = sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,22 +194,20 @@ public final class HSSFChart {
|
|||||||
for(RecordBase r : records) {
|
for(RecordBase r : records) {
|
||||||
|
|
||||||
if(r instanceof ChartRecord) {
|
if(r instanceof ChartRecord) {
|
||||||
lastChart = new HSSFChart((ChartRecord)r);
|
lastSeries = null;
|
||||||
|
|
||||||
|
lastChart = new HSSFChart(sheet,(ChartRecord)r);
|
||||||
charts.add(lastChart);
|
charts.add(lastChart);
|
||||||
}
|
} else if(r instanceof LegendRecord) {
|
||||||
if(r instanceof LegendRecord) {
|
|
||||||
lastChart.legendRecord = (LegendRecord)r;
|
lastChart.legendRecord = (LegendRecord)r;
|
||||||
}
|
} else if(r instanceof SeriesRecord) {
|
||||||
if(r instanceof SeriesRecord) {
|
|
||||||
HSSFSeries series = lastChart.new HSSFSeries( (SeriesRecord)r );
|
HSSFSeries series = lastChart.new HSSFSeries( (SeriesRecord)r );
|
||||||
lastChart.series.add(series);
|
lastChart.series.add(series);
|
||||||
lastSeries = series;
|
lastSeries = series;
|
||||||
}
|
} else if(r instanceof ChartTitleFormatRecord) {
|
||||||
if(r instanceof ChartTitleFormatRecord) {
|
|
||||||
lastChart.chartTitleFormat =
|
lastChart.chartTitleFormat =
|
||||||
(ChartTitleFormatRecord)r;
|
(ChartTitleFormatRecord)r;
|
||||||
}
|
} else if(r instanceof SeriesTextRecord) {
|
||||||
if(r instanceof SeriesTextRecord) {
|
|
||||||
// Applies to a series, unless we've seen
|
// Applies to a series, unless we've seen
|
||||||
// a legend already
|
// a legend already
|
||||||
SeriesTextRecord str = (SeriesTextRecord)r;
|
SeriesTextRecord str = (SeriesTextRecord)r;
|
||||||
@ -173,13 +219,28 @@ public final class HSSFChart {
|
|||||||
} else {
|
} else {
|
||||||
lastChart.chartTitleText = str;
|
lastChart.chartTitleText = str;
|
||||||
}
|
}
|
||||||
}
|
} else if (r instanceof LinkedDataRecord) {
|
||||||
if(r instanceof LinkedDataRecord) {
|
LinkedDataRecord linkedDataRecord = (LinkedDataRecord) r;
|
||||||
LinkedDataRecord data = (LinkedDataRecord)r;
|
if (lastSeries != null) {
|
||||||
lastSeries.insertData( data );
|
lastSeries.insertData(linkedDataRecord);
|
||||||
}
|
}
|
||||||
if(r instanceof ValueRangeRecord){
|
} else if(r instanceof ValueRangeRecord){
|
||||||
lastChart.valueRanges.add((ValueRangeRecord)r);
|
lastChart.valueRanges.add((ValueRangeRecord)r);
|
||||||
|
} else if (r instanceof Record) {
|
||||||
|
if (lastChart != null)
|
||||||
|
{
|
||||||
|
Record record = (Record) r;
|
||||||
|
for (HSSFChartType type : HSSFChartType.values()) {
|
||||||
|
if (type == HSSFChartType.Unknown)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (record.getSid() == type.getSid()) {
|
||||||
|
lastChart.type = type ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,14 +969,13 @@ public final class HSSFChart {
|
|||||||
private LinkedDataRecord dataValues;
|
private LinkedDataRecord dataValues;
|
||||||
private LinkedDataRecord dataCategoryLabels;
|
private LinkedDataRecord dataCategoryLabels;
|
||||||
private LinkedDataRecord dataSecondaryCategoryLabels;
|
private LinkedDataRecord dataSecondaryCategoryLabels;
|
||||||
private int dataReaded = 0;
|
|
||||||
|
|
||||||
/* package */ HSSFSeries(SeriesRecord series) {
|
/* package */ HSSFSeries(SeriesRecord series) {
|
||||||
this.series = series;
|
this.series = series;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertData(LinkedDataRecord data){
|
/* package */ void insertData(LinkedDataRecord data){
|
||||||
switch(dataReaded){
|
switch(data.getLinkType()){
|
||||||
case 0: dataName = data;
|
case 0: dataName = data;
|
||||||
break;
|
break;
|
||||||
case 1: dataValues = data;
|
case 1: dataValues = data;
|
||||||
@ -925,7 +985,11 @@ public final class HSSFChart {
|
|||||||
case 3: dataSecondaryCategoryLabels = data;
|
case 3: dataSecondaryCategoryLabels = data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dataReaded++;
|
}
|
||||||
|
|
||||||
|
/* package */ void setSeriesTitleText(SeriesTextRecord seriesTitleText)
|
||||||
|
{
|
||||||
|
this.seriesTitleText = seriesTitleText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getNumValues() {
|
public short getNumValues() {
|
||||||
@ -996,5 +1060,281 @@ public final class HSSFChart {
|
|||||||
public SeriesRecord getSeries() {
|
public SeriesRecord getSeries() {
|
||||||
return series;
|
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<Ptg>();
|
||||||
|
|
||||||
|
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[ptgList.size()]));
|
||||||
|
|
||||||
|
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<RecordBase>();
|
||||||
|
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<RecordBase>();
|
||||||
|
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) ((LinkedDataRecord)record).clone();
|
||||||
|
if (newSeries != null) {
|
||||||
|
newSeries.insertData(linkedDataRecord);
|
||||||
|
}
|
||||||
|
newRecord = linkedDataRecord;
|
||||||
|
} else if (record instanceof DataFormatRecord) {
|
||||||
|
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 series) {
|
||||||
|
int idx = 0;
|
||||||
|
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();
|
||||||
|
idx++;
|
||||||
|
|
||||||
|
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 (series.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,12 @@ package org.apache.poi.hssf.usermodel;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.HSSFITestDataProvider;
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.record.chart.SeriesRecord;
|
import org.apache.poi.hssf.record.chart.SeriesRecord;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFChart.HSSFSeries;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddressBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link HSSFChart}
|
* Tests for {@link HSSFChart}
|
||||||
@ -127,4 +131,99 @@ public final class TestHSSFChart extends TestCase {
|
|||||||
assertEquals("Base Numbers", charts[0].getSeries()[1].getSeriesTitle());
|
assertEquals("Base Numbers", charts[0].getSeries()[1].getSeriesTitle());
|
||||||
assertEquals("Sheet 3 Chart with Title", charts[0].getChartTitle());
|
assertEquals("Sheet 3 Chart with Title", charts[0].getChartTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExistingSheet3() throws Exception {
|
||||||
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49581.xls");
|
||||||
|
|
||||||
|
HSSFSheet sheet = wb.getSheetAt( 2 ) ;
|
||||||
|
HSSFChart[] charts = HSSFChart.getSheetCharts( sheet ) ;
|
||||||
|
assertEquals(1, charts.length);
|
||||||
|
|
||||||
|
for ( HSSFChart chart : charts ) {
|
||||||
|
for ( HSSFSeries series : chart.getSeries() ) {
|
||||||
|
chart.removeSeries( series ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save and re-check
|
||||||
|
wb = HSSFITestDataProvider.instance.writeOutAndReadBack(wb);
|
||||||
|
sheet = wb.getSheetAt( 2 ) ;
|
||||||
|
assertEquals(1, HSSFChart.getSheetCharts(sheet).length);
|
||||||
|
|
||||||
|
HSSFChart c = HSSFChart.getSheetCharts(sheet)[0];
|
||||||
|
assertEquals(0, c.getSeries().length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExistingSheet2() throws Exception {
|
||||||
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49581.xls");
|
||||||
|
HSSFSheet sheet = wb.getSheetAt( 1 ) ;
|
||||||
|
HSSFChart[] charts = HSSFChart.getSheetCharts( sheet ) ;
|
||||||
|
|
||||||
|
assertEquals(1, charts.length);
|
||||||
|
for ( HSSFChart chart : charts ) {
|
||||||
|
HSSFSeries series ;
|
||||||
|
|
||||||
|
// Starts with one
|
||||||
|
assertEquals(1, chart.getSeries().length);
|
||||||
|
|
||||||
|
// Add two more
|
||||||
|
series = chart.createSeries() ;
|
||||||
|
series.setCategoryLabelsCellRange( new CellRangeAddress( 3, 4, 0, 0 ) ) ;
|
||||||
|
series.setValuesCellRange( new CellRangeAddress( 3, 4, 1, 1 ) ) ;
|
||||||
|
|
||||||
|
series = chart.createSeries() ;
|
||||||
|
series.setCategoryLabelsCellRange( new CellRangeAddress( 6, 7, 0, 0 ) ) ;
|
||||||
|
series.setValuesCellRange( new CellRangeAddress( 6, 7, 1, 1 ) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save and re-check
|
||||||
|
wb = HSSFITestDataProvider.instance.writeOutAndReadBack(wb);
|
||||||
|
sheet = wb.getSheetAt( 1 ) ;
|
||||||
|
assertEquals(1, HSSFChart.getSheetCharts(sheet).length);
|
||||||
|
|
||||||
|
HSSFChart c = HSSFChart.getSheetCharts(sheet)[0];
|
||||||
|
assertEquals(3, c.getSeries().length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExistingSheet1() throws Exception {
|
||||||
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("49581.xls");
|
||||||
|
HSSFSheet sheet = wb.getSheetAt( 0 ) ;
|
||||||
|
HSSFChart[] charts = HSSFChart.getSheetCharts( sheet ) ;
|
||||||
|
|
||||||
|
for ( HSSFChart chart : charts ) {
|
||||||
|
//System.out.println( chart.getType() ) ;
|
||||||
|
HSSFSeries[] seriesArray = chart.getSeries() ;
|
||||||
|
//System.out.println( "seriesArray.length=" + seriesArray.length ) ;
|
||||||
|
for ( HSSFSeries series : seriesArray )
|
||||||
|
{
|
||||||
|
//System.out.println( "serie.getNumValues()=" + series.getNumValues() ) ;
|
||||||
|
CellRangeAddressBase range ;
|
||||||
|
|
||||||
|
range = series.getValuesCellRange() ;
|
||||||
|
//System.out.println( range.toString() ) ;
|
||||||
|
range.setLastRow( range.getLastRow() + 1 ) ;
|
||||||
|
series.setValuesCellRange( range ) ;
|
||||||
|
|
||||||
|
range = series.getCategoryLabelsCellRange() ;
|
||||||
|
//System.out.println( range.toString() ) ;
|
||||||
|
range.setLastRow( range.getLastRow() + 1 ) ;
|
||||||
|
series.setCategoryLabelsCellRange( range ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int id = 0 ; id < 2 ; id++ )
|
||||||
|
{
|
||||||
|
HSSFSeries newSeries = chart.createSeries() ;
|
||||||
|
newSeries.setValuesCellRange( new CellRangeAddress( 1 + id, 4, 3, 3 ) ) ;
|
||||||
|
String oldSeriesTitle = newSeries.getSeriesTitle() ;
|
||||||
|
if ( oldSeriesTitle != null )
|
||||||
|
{
|
||||||
|
//System.out.println( "old series title: " + oldSeriesTitle ) ;
|
||||||
|
newSeries.setSeriesTitle( "new series" ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HSSFChart chart = charts[ 2 ] ;
|
||||||
|
chart.removeSeries( chart.getSeries()[ 0 ] ) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BIN
test-data/spreadsheet/49581.xls
Normal file
BIN
test-data/spreadsheet/49581.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user