From 7921ef4f7d2f7250848ccc46be5528e9e2bfa37d Mon Sep 17 00:00:00 2001 From: Glen Stampoultzis Date: Mon, 16 Dec 2002 11:16:41 +0000 Subject: [PATCH] Some charting work (this is not currently working so don't expect much). git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352938 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/usermodel/HSSFChart.java | 818 ++++++++++++++++++ src/documentation/xdocs/hssf/chart.xml | 58 +- src/java/org/apache/poi/hssf/model/Sheet.java | 33 +- .../org/apache/poi/hssf/model/Workbook.java | 247 +++--- .../hssf/record/LinkedDataFormulaField.java | 7 + .../poi/hssf/record/LinkedDataRecord.java | 2 +- .../apache/poi/hssf/record/ProtectRecord.java | 2 +- .../apache/poi/hssf/record/UnknownRecord.java | 2 +- .../apache/poi/hssf/usermodel/HSSFSheet.java | 14 +- .../poi/hssf/usermodel/HSSFWorkbook.java | 30 +- .../definitions/linked_data_record.xml | 2 +- 11 files changed, 1086 insertions(+), 129 deletions(-) create mode 100644 src/contrib/src/org/apache/poi/hssf/usermodel/HSSFChart.java diff --git a/src/contrib/src/org/apache/poi/hssf/usermodel/HSSFChart.java b/src/contrib/src/org/apache/poi/hssf/usermodel/HSSFChart.java new file mode 100644 index 000000000..b23b1669e --- /dev/null +++ b/src/contrib/src/org/apache/poi/hssf/usermodel/HSSFChart.java @@ -0,0 +1,818 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache POI" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache POI", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.poi.hssf.usermodel; + +import org.apache.poi.hssf.record.*; +import org.apache.poi.hssf.record.formula.Area3DPtg; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Has methods for construction of a chart object. + * + * @author Glen Stampoultzis (glens at apache.org) + */ +public class HSSFChart +{ + + /** + * Creates a bar chart. API needs some work. :) + *

+ * NOTE: Does not yet work... checking it in just so others + * can take a look. + */ + public void createBarChart( HSSFWorkbook workbook, HSSFSheet sheet ) + { + + List records = new ArrayList(); + records.add( createMSDrawingObjectRecord() ); + records.add( createOBJRecord() ); + records.add( createBOFRecord() ); + records.add( createHeaderRecord() ); + records.add( createFooterRecord() ); + records.add( createHCenterRecord() ); + records.add( createVCenterRecord() ); + records.add( createPrintSetupRecord() ); + // unknown 33 + records.add( createFontBasisRecord1() ); + records.add( createFontBasisRecord2() ); + records.add( createProtectRecord() ); + 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( createEOFRecord() ); + + + + sheet.insertChartRecords( records ); + workbook.insertChartRecord(); + } + + private EOFRecord createEOFRecord() + { + return new EOFRecord(); + } + + 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 ProtectRecord createProtectRecord() + { + ProtectRecord r = new ProtectRecord(); + r.setProtect(false); + return r; + } + + private FooterRecord createFooterRecord() + { + FooterRecord r = new FooterRecord(); + r.setFooter(null); + return r; + } + + private HeaderRecord createHeaderRecord() + { + HeaderRecord r = new HeaderRecord(); + r.setHeader(null); + 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, (short) 0x001a, 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, (short)0x00C8, data); + } + + private void createAxisRecords( List 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( new LinkedDataFormulaField() ); + 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() + { + PlotAreaRecord r = new PlotAreaRecord( ); + return r; + } + + 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( new LinkedDataFormulaField() ); + 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 ); + LinkedDataFormulaField formula = new LinkedDataFormulaField(); + Stack tokens = new Stack(); + Area3DPtg p = new Area3DPtg(); + p.setExternSheetIndex( (short) 0 ); + p.setFirstColumn( (short) 1 ); + p.setLastColumn( (short) 1 ); + p.setFirstRow( (short) 0 ); + p.setLastRow( (short) 31 ); + tokens.add( p ); + formula.setFormulaTokens( tokens ); + r.setFormulaOfLink( formula ); + 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 ); + LinkedDataFormulaField formula = new LinkedDataFormulaField(); + Stack tokens = new Stack(); + Area3DPtg p = new Area3DPtg(); + p.setExternSheetIndex( (short) 0 ); + p.setFirstColumn( (short) 0 ); + p.setLastColumn( (short) 0 ); + p.setFirstRow( (short) 0 ); + p.setLastRow( (short) 31 ); + tokens.add( p ); + formula.setFormulaTokens( tokens ); + r.setFormulaOfLink( formula ); + 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( new LinkedDataFormulaField() ); + 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; + } +} diff --git a/src/documentation/xdocs/hssf/chart.xml b/src/documentation/xdocs/hssf/chart.xml index 49320f81f..6a303ffbf 100644 --- a/src/documentation/xdocs/hssf/chart.xml +++ b/src/documentation/xdocs/hssf/chart.xml @@ -12,8 +12,8 @@

This document is intended as a work in progress for describing - our current understanding of how the chart records are - are written to produce a valid chart. + our current understanding of how the chart records are are + written to produce a valid chart.

@@ -1287,6 +1287,60 @@ [END] [/END] + ============================================ + rectype = 0x200, recsize = 0xe + -BEGIN DUMP--------------------------------- + 00000000 00 00 00 00 1F 00 00 00 00 00 01 00 00 00 .............. + -END DUMP----------------------------------- + recordid = 0x200, size =14 + [DIMENSIONS] + .firstrow = 0 + .lastrow = 1f + .firstcol = 0 + .lastcol = 1 + .zero = 0 + [/DIMENSIONS] + + ============================================ + rectype = 0x1065, recsize = 0x2 + -BEGIN DUMP--------------------------------- + 00000000 02 00 .. + -END DUMP----------------------------------- + recordid = 0x1065, size =2 + [SINDEX] + .index = 0x0002 (2 ) + [/SINDEX] + + ============================================ + rectype = 0x1065, recsize = 0x2 + -BEGIN DUMP--------------------------------- + 00000000 01 00 .. + -END DUMP----------------------------------- + recordid = 0x1065, size =2 + [SINDEX] + .index = 0x0001 (1 ) + [/SINDEX] + + ============================================ + rectype = 0x1065, recsize = 0x2 + -BEGIN DUMP--------------------------------- + 00000000 03 00 .. + -END DUMP----------------------------------- + recordid = 0x1065, size =2 + [SINDEX] + .index = 0x0003 (3 ) + [/SINDEX] + + ============================================ + rectype = 0xa, recsize = 0x0 + -BEGIN DUMP--------------------------------- + **NO RECORD DATA** + -END DUMP----------------------------------- + recordid = 0xa, size =0 + [EOF] + [/EOF] + +

The next section breaks those records down into an easier diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index 866168668..89f0704cf 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -194,7 +194,7 @@ public class Sheet implements Model { retval.columnSizes = new ArrayList(); } - retval.columnSizes.add(( ColumnInfoRecord ) rec); + retval.columnSizes.add(rec); } else if (rec.getSid() == DefaultColWidthRecord.sid) { @@ -2023,6 +2023,29 @@ public class Sheet implements Model return null; } + /** + * Finds the first occurance of a record matching a particular sid and + * returns it's position. + * @param sid the sid to search for + * @return the record position of the matching record or -1 if no match + * is made. + */ + public int findFirstRecordLocBySid( short sid ) + { + int index = 0; + for (Iterator iterator = records.iterator(); iterator.hasNext(); ) + { + Record record = ( Record ) iterator.next(); + + if (record.getSid() == sid) + { + return index; + } + index++; + } + return -1; + } + /** * Returns the HeaderRecord. * @return HeaderRecord for the sheet. @@ -2149,28 +2172,28 @@ public class Sheet implements Model m = (Margin)findFirstRecordBySid(LeftMarginRecord.sid); if (m == null) { m = new LeftMarginRecord(); - records.add(getDimsLoc() + 1, (Record)m); + records.add(getDimsLoc() + 1, m); } break; case RightMargin : m = (Margin)findFirstRecordBySid(RightMarginRecord.sid); if (m == null) { m = new RightMarginRecord(); - records.add(getDimsLoc() + 1, (Record)m); + records.add(getDimsLoc() + 1, m); } break; case TopMargin : m = (Margin)findFirstRecordBySid(TopMarginRecord.sid); if (m == null) { m = new TopMarginRecord(); - records.add(getDimsLoc() + 1, (Record)m); + records.add(getDimsLoc() + 1, m); } break; case BottomMargin : m = (Margin)findFirstRecordBySid(BottomMarginRecord.sid); if (m == null) { m = new BottomMarginRecord(); - records.add(getDimsLoc() + 1, (Record)m); + records.add(getDimsLoc() + 1, m); } break; default : throw new RuntimeException("Unknown margin constant: " + margin); diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index c1cf5b3e7..78fa0d0d9 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -55,23 +55,18 @@ package org.apache.poi.hssf.model; -import java.io.*; +import org.apache.poi.hssf.record.*; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.hssf.util.SheetReferences; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; import java.util.ArrayList; -import java.util.List; import java.util.Iterator; +import java.util.List; import java.util.Locale; - -import org.apache.poi.util.POILogger; -import org.apache.poi.util.POILogFactory; - -import org.apache.poi.hssf.record.*; -import org.apache.poi.hssf.util.SheetReferences; -import org.apache.poi.hssf.util.HSSFColor; - /** - * Workbook * Low level model implementation of a Workbook. Provides creational methods * for settings and objects contained in the workbook object. *

@@ -84,6 +79,10 @@ import org.apache.poi.hssf.util.HSSFColor; * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf * before even attempting to use this. * + * @todo Need a good way of keeping track of bookmarks in a list. Currently + * we are manually incrementing multiple indexes whenever new records + * are added. This mechanism makes it very easy to introduce bugs. + * * @author Shawn Laubach (slaubach at apache dot org) (Data Formats) * @author Andrew C. Oliver (acoliver at apache dot org) * @author Glen Stampoultzis (glens at apache.org) @@ -137,31 +136,20 @@ public class Workbook implements Model { protected ArrayList names = new ArrayList(); - protected int bspos = - 0; // holds the position of the last bound sheet. - protected int tabpos = - 0; // holds the position of the tabid record - protected int fontpos = - 0; // hold the position of the last font record - protected int numfonts = - 0; // hold the number of font records - protected int xfpos = - 0; // hold the position of the last extended font record - protected int numxfs = - 0; // hold the number of extended format records - private int backuppos = - 0; // holds the position of the backup record. - private int namepos = - 0; // holds the position of last name record - private int supbookpos = - 0; // holds the position of sup book - private short maxformatid = - -1; // holds the max format id - private boolean uses1904datewindowing = - false; // whether 1904 date windowing is being used + protected int protpos = 0; // holds the position of the protect record. + protected int bspos = 0; // holds the position of the last bound sheet. + protected int tabpos = 0; // holds the position of the tabid record + protected int fontpos = 0; // hold the position of the last font record + protected int numfonts = 0; // hold the number of font records + protected int xfpos = 0; // hold the position of the last extended font record + protected int numxfs = 0; // hold the number of extended format records + private int backuppos = 0; // holds the position of the backup record. + private int namepos = 0; // holds the position of last name record + private int supbookpos = 0; // holds the position of sup book + private short maxformatid = -1; // holds the max format id + private boolean uses1904datewindowing = false; // whether 1904 date windowing is being used - private static POILogger log = - POILogFactory.getLogger(Workbook.class); + private static POILogger log = POILogFactory.getLogger(Workbook.class); /** * Creates new Workbook with no intitialization --useless right now @@ -228,6 +216,11 @@ public class Workbook implements Model { retval.tabpos = k; break; + case ProtectRecord.sid : + log.log(DEBUG, "found protect record at " + k); + retval.protpos = k; + break; + case BackupRecord.sid : log.log(DEBUG, "found backup record at " + k); retval.backuppos = k; @@ -276,79 +269,83 @@ public class Workbook implements Model { * Creates an empty workbook object with three blank sheets and all the empty * fields. Use this to create a workbook from scratch. */ + public static Workbook createWorkbook() + { + log.log( DEBUG, "creating new workbook from scratch" ); + Workbook retval = new Workbook(); + ArrayList records = new ArrayList( 30 ); + ArrayList formats = new ArrayList( 8 ); - public static Workbook createWorkbook() { - log.log(DEBUG, "creating new workbook from scratch"); - Workbook retval = new Workbook(); - ArrayList records = new ArrayList(30); - ArrayList formats = new ArrayList(8); - - records.add(retval.createBOF()); - records.add(retval.createInterfaceHdr()); - records.add(retval.createMMS()); - records.add(retval.createInterfaceEnd()); - records.add(retval.createWriteAccess()); - records.add(retval.createCodepage()); - records.add(retval.createDSF()); - records.add(retval.createTabId()); + records.add( retval.createBOF() ); + records.add( retval.createInterfaceHdr() ); + records.add( retval.createMMS() ); + records.add( retval.createInterfaceEnd() ); + records.add( retval.createWriteAccess() ); + records.add( retval.createCodepage() ); + records.add( retval.createDSF() ); + records.add( retval.createTabId() ); retval.tabpos = records.size() - 1; - records.add(retval.createFnGroupCount()); - records.add(retval.createWindowProtect()); - records.add(retval.createProtect()); - records.add(retval.createPassword()); - records.add(retval.createProtectionRev4()); - records.add(retval.createPasswordRev4()); - records.add(retval.createWindowOne()); - records.add(retval.createBackup()); + records.add( retval.createFnGroupCount() ); + records.add( retval.createWindowProtect() ); + records.add( retval.createProtect() ); + retval.protpos = records.size() - 1; + records.add( retval.createPassword() ); + records.add( retval.createProtectionRev4() ); + records.add( retval.createPasswordRev4() ); + records.add( retval.createWindowOne() ); + records.add( retval.createBackup() ); retval.backuppos = records.size() - 1; - records.add(retval.createHideObj()); - records.add(retval.createDateWindow1904()); - records.add(retval.createPrecision()); - records.add(retval.createRefreshAll()); - records.add(retval.createBookBool()); - records.add(retval.createFont()); - records.add(retval.createFont()); - records.add(retval.createFont()); - records.add(retval.createFont()); - retval.fontpos = records.size() - 1; // last font record postion + records.add( retval.createHideObj() ); + records.add( retval.createDateWindow1904() ); + records.add( retval.createPrecision() ); + records.add( retval.createRefreshAll() ); + records.add( retval.createBookBool() ); + records.add( retval.createFont() ); + records.add( retval.createFont() ); + records.add( retval.createFont() ); + records.add( retval.createFont() ); + retval.fontpos = records.size() - 1; // last font record postion retval.numfonts = 4; // set up format records - for (int i = 0; i <= 7; i++) { - Record rec; - rec = retval.createFormat(i); - retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode(); - formats.add(rec); - records.add(rec); - } - retval.formats = formats; + for ( int i = 0; i <= 7; i++ ) + { + Record rec; + rec = retval.createFormat( i ); + retval.maxformatid = retval.maxformatid >= ( (FormatRecord) rec ).getIndexCode() ? retval.maxformatid : ( (FormatRecord) rec ).getIndexCode(); + formats.add( rec ); + records.add( rec ); + } + retval.formats = formats; - for (int k = 0; k < 21; k++) { - records.add(retval.createExtendedFormat(k)); + for ( int k = 0; k < 21; k++ ) + { + records.add( retval.createExtendedFormat( k ) ); retval.numxfs++; } retval.xfpos = records.size() - 1; - for (int k = 0; k < 6; k++) { - records.add(retval.createStyle(k)); + for ( int k = 0; k < 6; k++ ) + { + records.add( retval.createStyle( k ) ); } - records.add(retval.createUseSelFS()); - for (int k = 0; k < 1; k++) { // now just do 1 + records.add( retval.createUseSelFS() ); + for ( int k = 0; k < 1; k++ ) + { // now just do 1 BoundSheetRecord bsr = - ( BoundSheetRecord ) retval.createBoundSheet(k); + (BoundSheetRecord) retval.createBoundSheet( k ); - records.add(bsr); - retval.boundsheets.add(bsr); + records.add( bsr ); + retval.boundsheets.add( bsr ); retval.bspos = records.size() - 1; } - records.add(retval.createCountry()); - retval.sst = ( SSTRecord ) retval.createSST(); - records.add(retval.sst); - records.add(retval.createExtendedSST()); + records.add( retval.createCountry() ); + retval.sst = (SSTRecord) retval.createSST(); + records.add( retval.sst ); + records.add( retval.createExtendedSST() ); - // TODO - records.add(retval.createEOF()); + records.add( retval.createEOF() ); retval.records = records; - log.log(DEBUG, "exit create new workbook from scratch"); + log.log( DEBUG, "exit create new workbook from scratch" ); return retval; } @@ -521,7 +518,6 @@ public class Workbook implements Model { * make the tabid record look like the current situation. * */ - private void fixTabIdRecord() { TabIdRecord tir = ( TabIdRecord ) records.get(tabpos); short[] tia = new short[ boundsheets.size() ]; @@ -1865,29 +1861,29 @@ public class Workbook implements Model { * @see org.apache.poi.hssf.record.FormatRecord * @see org.apache.poi.hssf.record.Record */ - public short createFormat(String format) { - ++xfpos; //These are to ensure that positions are updated properly + public short createFormat( String format ) + { + ++xfpos; //These are to ensure that positions are updated properly ++bspos; - FormatRecord rec = new FormatRecord(); - maxformatid = maxformatid >= (short)0xa4 ? (short)(maxformatid + 1) : (short)0xa4; //Starting value from M$ empiracle study. - rec.setIndexCode(maxformatid); - rec.setFormatStringLength((byte)format.length()); - rec.setFormatString(format); + FormatRecord rec = new FormatRecord(); + maxformatid = maxformatid >= (short) 0xa4 ? (short) ( maxformatid + 1 ) : (short) 0xa4; //Starting value from M$ empiracle study. + rec.setIndexCode( maxformatid ); + rec.setFormatStringLength( (byte) format.length() ); + rec.setFormatString( format ); - int pos = 0; - while (pos < records.size() && ((Record)records.get(pos)).getSid() != FormatRecord.sid) - pos++; - pos += formats.size(); - formats.add(rec); - records.add(pos, rec); - return maxformatid; - } + int pos = 0; + while ( pos < records.size() && ( (Record) records.get( pos ) ).getSid() != FormatRecord.sid ) + pos++; + pos += formats.size(); + formats.add( rec ); + records.add( pos, rec ); + return maxformatid; + } /** * Returns the first occurance of a record matching a particular sid. */ - public Record findFirstRecordBySid(short sid) { for (Iterator iterator = records.iterator(); iterator.hasNext(); ) { Record record = ( Record ) iterator.next(); @@ -1899,13 +1895,34 @@ public class Workbook implements Model { return null; } + /** + * Returns the index of a record matching a particular sid. + * @param sid The sid of the record to match + * @return The index of -1 if no match made. + */ + public int findFirstRecordLocBySid(short sid) { + int index = 0; + for (Iterator iterator = records.iterator(); iterator.hasNext(); ) { + Record record = ( Record ) iterator.next(); + + if (record.getSid() == sid) { + return index; + } + index ++; + } + return -1; + } + /** * Returns the next occurance of a record matching a particular sid. */ public Record findNextRecordBySid(short sid, int pos) { Iterator iterator = records.iterator(); - for (;pos > 0 && iterator.hasNext(); iterator.next(),pos--); - while (iterator.hasNext()) { + for (;pos > 0 && iterator.hasNext(); iterator.next(),pos--) + { + // intentionally empty + } + while (iterator.hasNext()) { Record record = ( Record ) iterator.next(); if (record.getSid() == sid) { @@ -1920,6 +1937,16 @@ public class Workbook implements Model { return records; } +// public void insertChartRecords( List chartRecords ) +// { +// backuppos += chartRecords.size(); +// fontpos += chartRecords.size(); +// bspos += chartRecords.size(); +// xfpos += chartRecords.size(); +// +// records.addAll(protpos, chartRecords); +// } + /** * Whether date windowing is based on 1/2/1904 or 1/1/1900. * Some versions of Excel (Mac) can save workbooks using 1904 date windowing. diff --git a/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java b/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java index c4ab2d69d..664b43c8a 100644 --- a/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java +++ b/src/java/org/apache/poi/hssf/record/LinkedDataFormulaField.java @@ -104,6 +104,13 @@ public class LinkedDataFormulaField } } + public String toString() + { + StringBuffer b = new StringBuffer(); + toString( b ); + return b.toString(); + } + public int serializeField( int offset, byte[] data ) { int size = getSize(); diff --git a/src/java/org/apache/poi/hssf/record/LinkedDataRecord.java b/src/java/org/apache/poi/hssf/record/LinkedDataRecord.java index ddbd24900..3539d0adc 100644 --- a/src/java/org/apache/poi/hssf/record/LinkedDataRecord.java +++ b/src/java/org/apache/poi/hssf/record/LinkedDataRecord.java @@ -74,7 +74,7 @@ public class LinkedDataRecord private byte field_1_linkType; public final static byte LINK_TYPE_TITLE_OR_TEXT = 0; public final static byte LINK_TYPE_VALUES = 1; - public final static byte LINK_TYPE_CATEGORIES = 1; + public final static byte LINK_TYPE_CATEGORIES = 2; private byte field_2_referenceType; public final static byte REFERENCE_TYPE_DEFAULT_CATEGORIES = 0; public final static byte REFERENCE_TYPE_DIRECT = 1; diff --git a/src/java/org/apache/poi/hssf/record/ProtectRecord.java b/src/java/org/apache/poi/hssf/record/ProtectRecord.java index f35239503..1f71b90e3 100644 --- a/src/java/org/apache/poi/hssf/record/ProtectRecord.java +++ b/src/java/org/apache/poi/hssf/record/ProtectRecord.java @@ -149,7 +149,7 @@ public class ProtectRecord StringBuffer buffer = new StringBuffer(); buffer.append("[PROTECT]\n"); - buffer.append(" .rowheight = ") + buffer.append(" .protected = ") .append(Integer.toHexString(getProtect())).append("\n"); buffer.append("[/PROTECT]\n"); return buffer.toString(); diff --git a/src/java/org/apache/poi/hssf/record/UnknownRecord.java b/src/java/org/apache/poi/hssf/record/UnknownRecord.java index e027361b2..76b4aa19c 100644 --- a/src/java/org/apache/poi/hssf/record/UnknownRecord.java +++ b/src/java/org/apache/poi/hssf/record/UnknownRecord.java @@ -149,7 +149,7 @@ public class UnknownRecord { StringBuffer buffer = new StringBuffer(); - buffer.append("[UNKNOWN RECORD]\n"); + buffer.append("[UNKNOWN RECORD:" + Integer.toHexString(sid) + "]\n"); buffer.append(" .id = ").append(Integer.toHexString(sid)) .append("\n"); buffer.append("[/UNKNWON RECORD]\n"); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index a5bb0cede..c6d7e0d91 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -61,18 +61,14 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.record.CellValueRecordInterface; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.hssf.record.VCenterRecord; -import org.apache.poi.hssf.record.WindowTwoRecord; -import org.apache.poi.hssf.record.WSBoolRecord; +import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.util.Region; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import java.util.Iterator; import java.util.TreeMap; +import java.util.List; /** * High level representation of a worksheet. @@ -876,4 +872,10 @@ public class HSSFSheet if (endRow == lastrow || endRow + n > lastrow) lastrow = Math.min(endRow + n, 65535); if (startRow == firstrow || startRow + n < firstrow) firstrow = Math.max(startRow + n, 0); } + + protected void insertChartRecords( List records ) + { + int window2Loc = sheet.findFirstRecordLocBySid(WindowTwoRecord.sid); + sheet.getRecords().addAll(window2Loc, records ); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 1c52c6f51..98cfedae7 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -61,7 +61,6 @@ package org.apache.poi.hssf.usermodel; import org.apache.poi.util.POILogFactory; import org.apache.poi.hssf.eventmodel.EventRecordFactory; -import org.apache.poi.hssf.eventmodel.ModelFactory; import org.apache.poi.hssf.model.Sheet; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.*; @@ -754,7 +753,7 @@ public class HSSFWorkbook private boolean isInList(String entry, List list) { for (int k = 0; k < list.size(); k++) { - if (((String)list.get(k)).equals(entry)) { + if (list.get(k).equals(entry)) { return true; } } @@ -781,4 +780,31 @@ public class HSSFWorkbook } } + public void insertChartRecord() + { + int loc = workbook.findFirstRecordLocBySid(SSTRecord.sid); + byte[] data = { + (byte)0x0F, (byte)0x00, (byte)0x00, (byte)0xF0, (byte)0x52, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x06, (byte)0xF0, (byte)0x18, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x01, (byte)0x08, (byte)0x00, (byte)0x00, + (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00, + (byte)0x33, (byte)0x00, (byte)0x0B, (byte)0xF0, (byte)0x12, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xBF, (byte)0x00, + (byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x81, + (byte)0x01, (byte)0x09, (byte)0x00, (byte)0x00, (byte)0x08, + (byte)0xC0, (byte)0x01, (byte)0x40, (byte)0x00, (byte)0x00, + (byte)0x08, (byte)0x40, (byte)0x00, (byte)0x1E, (byte)0xF1, + (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0D, + (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x0C, (byte)0x00, + (byte)0x00, (byte)0x08, (byte)0x17, (byte)0x00, (byte)0x00, + (byte)0x08, (byte)0xF7, (byte)0x00, (byte)0x00, (byte)0x10, + }; + UnknownRecord r = new UnknownRecord((short)0x00EB,(short)0x005a, data); + workbook.getRecords().add(loc, r); + } + } diff --git a/src/records/definitions/linked_data_record.xml b/src/records/definitions/linked_data_record.xml index 9417eeeca..a6e886307 100644 --- a/src/records/definitions/linked_data_record.xml +++ b/src/records/definitions/linked_data_record.xml @@ -7,7 +7,7 @@ - +