mirror of https://github.com/apache/poi.git
more progress with xssf chart api, see Bug 51196
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1167579 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
57c369a541
commit
e4b2a66d09
|
@ -20,63 +20,61 @@
|
||||||
package org.apache.poi.xssf.usermodel.examples;
|
package org.apache.poi.xssf.usermodel.examples;
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.ss.util.*;
|
import org.apache.poi.ss.util.*;
|
||||||
import org.apache.poi.ss.usermodel.charts.*;
|
import org.apache.poi.ss.usermodel.charts.*;
|
||||||
import org.apache.poi.xssf.usermodel.*;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.apache.poi.xssf.usermodel.charts.*;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Illustrates how to create a simple scatter chart.
|
* Illustrates how to create a simple scatter chart.
|
||||||
|
*
|
||||||
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
public class ScatterChart {
|
public class ScatterChart {
|
||||||
|
|
||||||
public static void main(String[]args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Workbook wb = new XSSFWorkbook();
|
Workbook wb = new XSSFWorkbook();
|
||||||
CreationHelper creationHelper = wb.getCreationHelper();
|
Sheet sheet = wb.createSheet("Sheet 1");
|
||||||
Sheet sheet = wb.createSheet("Sheet 1");
|
final int NUM_OF_ROWS = 3;
|
||||||
final int NUM_OF_ROWS = 3;
|
final int NUM_OF_COLUMNS = 10;
|
||||||
final int NUM_OF_COLUMNS = 10;
|
|
||||||
|
|
||||||
// Create a row and put some cells in it. Rows are 0 based.
|
// Create a row and put some cells in it. Rows are 0 based.
|
||||||
Row row;
|
Row row;
|
||||||
Cell cell;
|
Cell cell;
|
||||||
for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
|
for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
|
||||||
row = sheet.createRow((short)rowIndex);
|
row = sheet.createRow((short) rowIndex);
|
||||||
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
|
||||||
cell = row.createCell((short)colIndex);
|
cell = row.createCell((short) colIndex);
|
||||||
cell.setCellValue(colIndex * (rowIndex + 1));
|
cell.setCellValue(colIndex * (rowIndex + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawing drawing = sheet.createDrawingPatriarch();
|
Drawing drawing = sheet.createDrawingPatriarch();
|
||||||
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
|
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 10, 15);
|
||||||
|
|
||||||
Chart chart = drawing.createChart(anchor);
|
Chart chart = drawing.createChart(anchor);
|
||||||
ChartLegend legend = chart.getOrCreateLegend();
|
ChartLegend legend = chart.getOrCreateLegend();
|
||||||
legend.setPosition(LegendPosition.TOP_RIGHT);
|
legend.setPosition(LegendPosition.TOP_RIGHT);
|
||||||
|
|
||||||
ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
|
ScatterChartData data = chart.getChartDataFactory().createScatterChartData();
|
||||||
|
|
||||||
ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
|
ValueAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
|
||||||
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
|
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
|
||||||
|
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
|
||||||
|
|
||||||
DataMarker xMarker = new DataMarker(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
|
||||||
DataMarker y1Marker = new DataMarker(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
|
ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, NUM_OF_COLUMNS - 1));
|
||||||
DataMarker y2Marker = new DataMarker(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
ChartDataSource<Number> ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, NUM_OF_COLUMNS - 1));
|
||||||
|
|
||||||
|
|
||||||
data.addSerie(xMarker, y1Marker);
|
|
||||||
data.addSerie(xMarker, y2Marker);
|
|
||||||
|
|
||||||
chart.plot(data, bottomAxis, leftAxis);
|
data.addSerie(xs, ys1);
|
||||||
|
data.addSerie(xs, ys2);
|
||||||
|
|
||||||
// Write the output to a file
|
chart.plot(data, bottomAxis, leftAxis);
|
||||||
FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx");
|
|
||||||
wb.write(fileOut);
|
// Write the output to a file
|
||||||
fileOut.close();
|
FileOutputStream fileOut = new FileOutputStream("ooxml-scatter-chart.xlsx");
|
||||||
}
|
wb.write(fileOut);
|
||||||
|
fileOut.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,14 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High level representation of chart axis.
|
* High level representation of chart axis.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ChartAxis {
|
public interface ChartAxis {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Chart;
|
import org.apache.poi.ss.usermodel.Chart;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for different chart axis.
|
* A factory for different chart axis.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ChartAxisFactory {
|
public interface ChartAxisFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,19 +18,21 @@
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Chart;
|
import org.apache.poi.ss.usermodel.Chart;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base for all chart data types.
|
* A base for all charts data types.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ChartData {
|
public interface ChartData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills a chart with data specified by implementation.
|
* Fills a charts with data specified by implementation.
|
||||||
*
|
*
|
||||||
* @param chart a chart to fill in
|
* @param chart a charts to fill in
|
||||||
* @param axis chart axis to use
|
* @param axis charts axis to use
|
||||||
*/
|
*/
|
||||||
void fillChart(Chart chart, ChartAxis... axis);
|
void fillChart(Chart chart, ChartAxis... axis);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,14 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for different chart data types.
|
* A factory for different charts data types.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ChartDataFactory {
|
public interface ChartDataFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents data model of the charts.
|
||||||
|
*
|
||||||
|
* @param <T> type of points the data source contents
|
||||||
|
* @author Roman Kashitsyn
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public interface ChartDataSource<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return number of points contained by data source.
|
||||||
|
*
|
||||||
|
* @return number of points contained by data source
|
||||||
|
*/
|
||||||
|
int getPointCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns point value at specified index.
|
||||||
|
*
|
||||||
|
* @param index index to value from
|
||||||
|
* @return point value at specified index.
|
||||||
|
* @throws {@code IndexOutOfBoundsException} if index
|
||||||
|
* parameter not in range {@code 0 <= index <= pointCount}
|
||||||
|
*/
|
||||||
|
T getPointAt(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if charts data source is valid cell range.
|
||||||
|
*
|
||||||
|
* @return {@code true} if charts data source is valid cell range
|
||||||
|
*/
|
||||||
|
boolean isReference();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if data source points should be treated as numbers.
|
||||||
|
*
|
||||||
|
* @return {@code true} if data source points should be treated as numbers
|
||||||
|
*/
|
||||||
|
boolean isNumeric();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns formula representation of the data source. It is only applicable
|
||||||
|
* for data source that is valid cell range.
|
||||||
|
*
|
||||||
|
* @return formula representation of the data source
|
||||||
|
* @throws {@code UnsupportedOperationException} if the data source is not a
|
||||||
|
* reference.
|
||||||
|
*/
|
||||||
|
String getFormulaString();
|
||||||
|
}
|
|
@ -17,11 +17,14 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High level representation of chart legend.
|
* High level representation of chart legend.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ChartLegend extends ManuallyPositionable {
|
public interface ChartLegend extends ManuallyPositionable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class {@code DataSources} is a factory for {@link ChartDataSource} instances.
|
||||||
|
*
|
||||||
|
* @author Roman Kashitsyn
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class DataSources {
|
||||||
|
|
||||||
|
private DataSources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ChartDataSource<T> fromArray(T[] elements) {
|
||||||
|
return new ArrayDataSource<T>(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChartDataSource<Number> fromNumericCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
|
||||||
|
return new AbstractCellRangeDataSource<Number>(sheet, cellRangeAddress) {
|
||||||
|
public Number getPointAt(int index) {
|
||||||
|
CellValue cellValue = getCellValueAt(index);
|
||||||
|
if (cellValue != null && cellValue.getCellType() == Cell.CELL_TYPE_NUMERIC) {
|
||||||
|
return Double.valueOf(cellValue.getNumberValue());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNumeric() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChartDataSource<String> fromStringCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
|
||||||
|
return new AbstractCellRangeDataSource<String>(sheet, cellRangeAddress) {
|
||||||
|
public String getPointAt(int index) {
|
||||||
|
CellValue cellValue = getCellValueAt(index);
|
||||||
|
if (cellValue != null && cellValue.getCellType() == Cell.CELL_TYPE_STRING) {
|
||||||
|
return cellValue.getStringValue();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNumeric() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ArrayDataSource<T> implements ChartDataSource<T> {
|
||||||
|
|
||||||
|
private final T[] elements;
|
||||||
|
|
||||||
|
public ArrayDataSource(T[] elements) {
|
||||||
|
this.elements = elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPointCount() {
|
||||||
|
return elements.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getPointAt(int index) {
|
||||||
|
return elements[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReference() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNumeric() {
|
||||||
|
Class<?> arrayComponentType = elements.getClass().getComponentType();
|
||||||
|
return (Number.class.isAssignableFrom(arrayComponentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormulaString() {
|
||||||
|
throw new UnsupportedOperationException("Literal data source can not be expressed by reference.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract static class AbstractCellRangeDataSource<T> implements ChartDataSource<T> {
|
||||||
|
private final Sheet sheet;
|
||||||
|
private final CellRangeAddress cellRangeAddress;
|
||||||
|
private final int numOfCells;
|
||||||
|
private FormulaEvaluator evaluator;
|
||||||
|
|
||||||
|
protected AbstractCellRangeDataSource(Sheet sheet, CellRangeAddress cellRangeAddress) {
|
||||||
|
this.sheet = sheet;
|
||||||
|
// Make copy since CellRangeAddress is mutable.
|
||||||
|
this.cellRangeAddress = cellRangeAddress.copy();
|
||||||
|
this.numOfCells = this.cellRangeAddress.getNumberOfCells();
|
||||||
|
this.evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPointCount() {
|
||||||
|
return numOfCells;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReference() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormulaString() {
|
||||||
|
return cellRangeAddress.formatAsString(sheet.getSheetName(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CellValue getCellValueAt(int index) {
|
||||||
|
if (index < 0 || index >= numOfCells) {
|
||||||
|
throw new IndexOutOfBoundsException("Index must be between 0 and " +
|
||||||
|
(numOfCells - 1) + " (inclusive), given: " + index);
|
||||||
|
}
|
||||||
|
int firstRow = cellRangeAddress.getFirstRow();
|
||||||
|
int firstCol = cellRangeAddress.getFirstColumn();
|
||||||
|
int lastCol = cellRangeAddress.getLastColumn();
|
||||||
|
int width = lastCol - firstCol + 1;
|
||||||
|
int rowIndex = firstRow + index / width;
|
||||||
|
int cellIndex = firstCol + index % width;
|
||||||
|
Row row = sheet.getRow(rowIndex);
|
||||||
|
return (row == null) ? null : evaluator.evaluate(row.getCell(cellIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,11 +17,14 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High level representation of chart element manual layout.
|
* High level representation of chart element manual layout.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ManualLayout {
|
public interface ManualLayout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction of chart element that can be positioned with manual
|
* Abstraction of chart element that can be positioned with manual
|
||||||
* layout.
|
* layout.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ManuallyPositionable {
|
public interface ManuallyPositionable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,20 +18,17 @@
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
public interface ScatterChartData extends ChartData {
|
public interface ScatterChartData extends ChartData {
|
||||||
/**
|
/**
|
||||||
* @param xMarker data marker to be used for X value range
|
* @param xs data source to be used for X axis values
|
||||||
* @param yMarker data marker to be used for Y value range
|
* @param ys data source to be used for Y axis values
|
||||||
* @return a new scatter chart serie
|
* @return a new scatter charts serie
|
||||||
*/
|
*/
|
||||||
ScatterChartSerie addSerie(DataMarker xMarker, DataMarker yMarker);
|
ScatterChartSerie addSerie(ChartDataSource<?> xs, ChartDataSource<? extends Number> ys);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of all series
|
* @return list of all series
|
||||||
|
|
|
@ -17,23 +17,24 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
|
||||||
import org.apache.poi.ss.usermodel.charts.ChartDataFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Represents scatter charts serie.
|
||||||
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ScatterChartSerie {
|
public interface ScatterChartSerie {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param xMarker data marker to use for X values.
|
* @return data source used for X axis values
|
||||||
*/
|
*/
|
||||||
void setXValues(DataMarker xMarker);
|
ChartDataSource<?> getXValues();
|
||||||
|
|
||||||
/**'
|
/**
|
||||||
* @param yMarker data marker to use for Y values.
|
* @return data source used for Y axis values
|
||||||
*/
|
*/
|
||||||
void setYValues(DataMarker yMarker);
|
ChartDataSource<? extends Number> getYValues();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,12 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.usermodel.charts;
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public interface ValueAxis extends ChartAxis {
|
public interface ValueAxis extends ChartAxis {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
/*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.apache.poi.ss.util;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents data marker used in charts.
|
|
||||||
* @author Roman Kashitsyn
|
|
||||||
*/
|
|
||||||
public class DataMarker {
|
|
||||||
|
|
||||||
private Sheet sheet;
|
|
||||||
private CellRangeAddress range;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param sheet the sheet where data located.
|
|
||||||
* @param range the range within that sheet.
|
|
||||||
*/
|
|
||||||
public DataMarker(Sheet sheet, CellRangeAddress range) {
|
|
||||||
this.sheet = sheet;
|
|
||||||
this.range = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the sheet marker points to.
|
|
||||||
* @return sheet marker points to.
|
|
||||||
*/
|
|
||||||
public Sheet getSheet() {
|
|
||||||
return sheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets sheet marker points to.
|
|
||||||
* @param sheet new sheet for the marker.
|
|
||||||
*/
|
|
||||||
public void setSheet(Sheet sheet) {
|
|
||||||
this.sheet = sheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns range of the marker.
|
|
||||||
* @return range of cells marker points to.
|
|
||||||
*/
|
|
||||||
public CellRangeAddress getRange() {
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets range of the marker.
|
|
||||||
* @param range new range for the marker.
|
|
||||||
*/
|
|
||||||
public void setRange(CellRangeAddress range) {
|
|
||||||
this.range = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats data marker using canonical format, for example
|
|
||||||
* `SheetName!$A$1:$A$5'.
|
|
||||||
* @return formatted data marker.
|
|
||||||
*/
|
|
||||||
public String formatAsString() {
|
|
||||||
String sheetName = (sheet == null) ? (null) : (sheet.getSheetName());
|
|
||||||
if (range == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return range.formatAsString(sheetName, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,115 +25,134 @@ import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that provides useful sheet build capabilities. It can be used
|
* Class {@code SheetBuilder} provides an easy way of building workbook sheets
|
||||||
* in test cases to improve readability or in Swing applications with
|
* from 2D array of Objects. It can be used in test cases to improve code
|
||||||
* tables.
|
* readability or in Swing applications with tables.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
public class SheetBuilder {
|
public class SheetBuilder {
|
||||||
|
|
||||||
private Workbook workbook;
|
private final Workbook workbook;
|
||||||
private Object[][] cells;
|
private final Object[][] cells;
|
||||||
private boolean shouldCreateEmptyCells = false;
|
private boolean shouldCreateEmptyCells = false;
|
||||||
|
private String sheetName = null;
|
||||||
|
|
||||||
public SheetBuilder(Workbook workbook, Object[][] cells) {
|
public SheetBuilder(Workbook workbook, Object[][] cells) {
|
||||||
this.workbook = workbook;
|
this.workbook = workbook;
|
||||||
this.cells = cells;
|
this.cells = cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if null objects should be trated as empty cells
|
* Returns {@code true} if null array elements should be treated as empty
|
||||||
* false otherwise
|
* cells.
|
||||||
|
*
|
||||||
|
* @return {@code true} if null objects should be treated as empty cells
|
||||||
|
* and {@code false} otherwise
|
||||||
*/
|
*/
|
||||||
public boolean getCreateEmptyCells() {
|
public boolean getCreateEmptyCells() {
|
||||||
return shouldCreateEmptyCells;
|
return shouldCreateEmptyCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param shouldCreateEmptyCells true if null array elements should be
|
* Specifies if null array elements should be treated as empty cells.
|
||||||
* trated as empty cells
|
*
|
||||||
* @return this
|
* @param shouldCreateEmptyCells {@code true} if null array elements should be
|
||||||
|
* treated as empty cells
|
||||||
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public SheetBuilder setCreateEmptyCells(boolean shouldCreateEmptyCells) {
|
public SheetBuilder setCreateEmptyCells(boolean shouldCreateEmptyCells) {
|
||||||
this.shouldCreateEmptyCells = shouldCreateEmptyCells;
|
this.shouldCreateEmptyCells = shouldCreateEmptyCells;
|
||||||
return this;
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies name of the sheet to build. If not specified, default name (provided by
|
||||||
|
* workbook) will be used instead.
|
||||||
|
* @param sheetName sheet name to use
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public SheetBuilder setSheetName(String sheetName) {
|
||||||
|
this.sheetName = sheetName;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds sheet from parent workbook and 2D array with cell
|
* Builds sheet from parent workbook and 2D array with cell
|
||||||
* values. Creates rows anyway (even if row contains only null
|
* values. Creates rows anyway (even if row contains only null
|
||||||
* cells), creates cells only if corresponding property is true.
|
* cells), creates cells if either corresponding array value is not
|
||||||
|
* null or createEmptyCells property is true.
|
||||||
* The conversion is performed in the following way:
|
* The conversion is performed in the following way:
|
||||||
*
|
* <p/>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Numbers become numeric cells.</li>
|
* <li>Numbers become numeric cells.</li>
|
||||||
* <li><code>java.util.Date</code> or <code>java.util.Calendar</code>
|
* <li><code>java.util.Date</code> or <code>java.util.Calendar</code>
|
||||||
* instances become date cells.</li>
|
* instances become date cells.</li>
|
||||||
* <li>String with leading '=' char become formulas (leading '='
|
* <li>String with leading '=' char become formulas (leading '='
|
||||||
* trancated).</li>
|
* will be truncated).</li>
|
||||||
* <li>Other objects become strings via <code>Object.toString()</code>
|
* <li>Other objects become strings via <code>Object.toString()</code>
|
||||||
* method.</li>
|
* method call.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @return newly created sheet
|
* @return newly created sheet
|
||||||
*/
|
*/
|
||||||
public Sheet build() {
|
public Sheet build() {
|
||||||
Sheet sheet = workbook.createSheet();
|
Sheet sheet = (sheetName == null) ? workbook.createSheet() : workbook.createSheet(sheetName);
|
||||||
Row currentRow = null;
|
Row currentRow = null;
|
||||||
Cell currentCell = null;
|
Cell currentCell = null;
|
||||||
|
|
||||||
for (int rowIndex = 0; rowIndex < cells.length; ++rowIndex) {
|
for (int rowIndex = 0; rowIndex < cells.length; ++rowIndex) {
|
||||||
Object[] rowArray = cells[rowIndex];
|
Object[] rowArray = cells[rowIndex];
|
||||||
currentRow = sheet.createRow(rowIndex);
|
currentRow = sheet.createRow(rowIndex);
|
||||||
|
|
||||||
for (int cellIndex = 0; cellIndex < rowArray.length; ++cellIndex) {
|
for (int cellIndex = 0; cellIndex < rowArray.length; ++cellIndex) {
|
||||||
Object cellValue = rowArray[cellIndex];
|
Object cellValue = rowArray[cellIndex];
|
||||||
if (cellValue != null || shouldCreateEmptyCells) {
|
if (cellValue != null || shouldCreateEmptyCells) {
|
||||||
currentCell = currentRow.createCell(cellIndex);
|
currentCell = currentRow.createCell(cellIndex);
|
||||||
setCellValue(currentCell, cellValue);
|
setCellValue(currentCell, cellValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cell value using object type information.
|
* Sets the cell value using object type information.
|
||||||
* @param cell cell to change
|
*
|
||||||
|
* @param cell cell to change
|
||||||
* @param value value to set
|
* @param value value to set
|
||||||
*/
|
*/
|
||||||
public void setCellValue(Cell cell, Object value) {
|
private void setCellValue(Cell cell, Object value) {
|
||||||
if (value == null || cell == null) {
|
if (value == null || cell == null) {
|
||||||
return;
|
return;
|
||||||
} else if (value instanceof Number) {
|
} else if (value instanceof Number) {
|
||||||
double doubleValue = ((Number) value).doubleValue();
|
double doubleValue = ((Number) value).doubleValue();
|
||||||
cell.setCellValue(doubleValue);
|
cell.setCellValue(doubleValue);
|
||||||
} else if (value instanceof Date) {
|
} else if (value instanceof Date) {
|
||||||
cell.setCellValue((Date) value);
|
cell.setCellValue((Date) value);
|
||||||
} else if (value instanceof Calendar) {
|
} else if (value instanceof Calendar) {
|
||||||
cell.setCellValue((Calendar) value);
|
cell.setCellValue((Calendar) value);
|
||||||
} else if (isFormulaDefinition(value)) {
|
} else if (isFormulaDefinition(value)) {
|
||||||
cell.setCellFormula(getFormula(value));
|
cell.setCellFormula(getFormula(value));
|
||||||
} else {
|
} else {
|
||||||
cell.setCellValue(value.toString());
|
cell.setCellValue(value.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFormulaDefinition(Object obj) {
|
private boolean isFormulaDefinition(Object obj) {
|
||||||
if (obj instanceof String) {
|
if (obj instanceof String) {
|
||||||
String str = (String) obj;
|
String str = (String) obj;
|
||||||
if (str.length() < 2) {
|
if (str.length() < 2) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return ((String) obj).charAt(0) == '=';
|
return ((String) obj).charAt(0) == '=';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFormula(Object obj) {
|
private String getFormula(Object obj) {
|
||||||
return ((String) obj).substring(1);
|
return ((String) obj).substring(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,12 +17,10 @@
|
||||||
|
|
||||||
package org.apache.poi.ss.util.cellwalk;
|
package org.apache.poi.ss.util.cellwalk;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverse cell range.
|
* Traverse cell range.
|
||||||
|
@ -35,95 +33,96 @@ public class CellWalk {
|
||||||
private CellRangeAddress range;
|
private CellRangeAddress range;
|
||||||
private boolean traverseEmptyCells;
|
private boolean traverseEmptyCells;
|
||||||
|
|
||||||
public CellWalk(DataMarker dm) {
|
|
||||||
this(dm.getSheet(), dm.getRange());
|
|
||||||
}
|
|
||||||
|
|
||||||
public CellWalk(Sheet sheet, CellRangeAddress range) {
|
public CellWalk(Sheet sheet, CellRangeAddress range) {
|
||||||
this.sheet = sheet;
|
this.sheet = sheet;
|
||||||
this.range = range;
|
this.range = range;
|
||||||
this.traverseEmptyCells = false;
|
this.traverseEmptyCells = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should we call handler on empty (blank) cells. Default is
|
* Should we call handler on empty (blank) cells. Default is
|
||||||
* false.
|
* false.
|
||||||
|
*
|
||||||
* @return true if handler should be called on empty (blank)
|
* @return true if handler should be called on empty (blank)
|
||||||
* cells, false otherwise.
|
* cells, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isTraverseEmptyCells() {
|
public boolean isTraverseEmptyCells() {
|
||||||
return traverseEmptyCells;
|
return traverseEmptyCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the traverseEmptyCells property.
|
* Sets the traverseEmptyCells property.
|
||||||
|
*
|
||||||
* @param traverseEmptyCells new property value
|
* @param traverseEmptyCells new property value
|
||||||
*/
|
*/
|
||||||
public void setTraverseEmptyCells(boolean traverseEmptyCells) {
|
public void setTraverseEmptyCells(boolean traverseEmptyCells) {
|
||||||
this.traverseEmptyCells = traverseEmptyCells;
|
this.traverseEmptyCells = traverseEmptyCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverse cell range from top left to bottom right cell.
|
* Traverse cell range from top left to bottom right cell.
|
||||||
|
*
|
||||||
* @param handler handler to call on each appropriate cell
|
* @param handler handler to call on each appropriate cell
|
||||||
*/
|
*/
|
||||||
public void traverse(CellHandler handler) {
|
public void traverse(CellHandler handler) {
|
||||||
int firstRow = range.getFirstRow();
|
int firstRow = range.getFirstRow();
|
||||||
int lastRow = range.getLastRow();
|
int lastRow = range.getLastRow();
|
||||||
int firstColumn = range.getFirstColumn();
|
int firstColumn = range.getFirstColumn();
|
||||||
int lastColumn = range.getLastColumn();
|
int lastColumn = range.getLastColumn();
|
||||||
final int width = lastColumn - firstColumn + 1;
|
final int width = lastColumn - firstColumn + 1;
|
||||||
SimpleCellWalkContext ctx = new SimpleCellWalkContext();
|
SimpleCellWalkContext ctx = new SimpleCellWalkContext();
|
||||||
Row currentRow = null;
|
Row currentRow = null;
|
||||||
Cell currentCell = null;
|
Cell currentCell = null;
|
||||||
|
|
||||||
for (ctx.rowNumber = firstRow; ctx.rowNumber <= lastRow; ++ctx.rowNumber) {
|
for (ctx.rowNumber = firstRow; ctx.rowNumber <= lastRow; ++ctx.rowNumber) {
|
||||||
currentRow = sheet.getRow(ctx.rowNumber);
|
currentRow = sheet.getRow(ctx.rowNumber);
|
||||||
if (currentRow == null) {
|
if (currentRow == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (ctx.colNumber = firstColumn; ctx.colNumber <= lastColumn; ++ctx.colNumber) {
|
for (ctx.colNumber = firstColumn; ctx.colNumber <= lastColumn; ++ctx.colNumber) {
|
||||||
currentCell = currentRow.getCell(ctx.colNumber);
|
currentCell = currentRow.getCell(ctx.colNumber);
|
||||||
|
|
||||||
if (currentCell == null) {
|
if (currentCell == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isEmpty(currentCell) && !traverseEmptyCells) {
|
if (isEmpty(currentCell) && !traverseEmptyCells) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.ordinalNumber =
|
ctx.ordinalNumber =
|
||||||
(ctx.rowNumber - firstRow) * width +
|
(ctx.rowNumber - firstRow) * width +
|
||||||
(ctx.colNumber - firstColumn + 1);
|
(ctx.colNumber - firstColumn + 1);
|
||||||
|
|
||||||
handler.onCell(currentCell, ctx);
|
handler.onCell(currentCell, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEmpty(Cell cell) {
|
private boolean isEmpty(Cell cell) {
|
||||||
return (cell.getCellType() == Cell.CELL_TYPE_BLANK);
|
return (cell.getCellType() == Cell.CELL_TYPE_BLANK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner class to hold walk context.
|
* Inner class to hold walk context.
|
||||||
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
private class SimpleCellWalkContext implements CellWalkContext {
|
private class SimpleCellWalkContext implements CellWalkContext {
|
||||||
public long ordinalNumber = 0;
|
public long ordinalNumber = 0;
|
||||||
public int rowNumber = 0;
|
public int rowNumber = 0;
|
||||||
public int colNumber = 0;
|
public int colNumber = 0;
|
||||||
|
|
||||||
public long getOrdinalNumber() {
|
public long getOrdinalNumber() {
|
||||||
return ordinalNumber;
|
return ordinalNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRowNumber() {
|
public int getRowNumber() {
|
||||||
return rowNumber;
|
return rowNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColumnNumber() {
|
public int getColumnNumber() {
|
||||||
return colNumber;
|
return colNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.apache.poi.ss.usermodel.charts.ChartAxis;
|
||||||
import org.apache.poi.ss.usermodel.charts.AxisPosition;
|
import org.apache.poi.ss.usermodel.charts.AxisPosition;
|
||||||
import org.apache.poi.ss.usermodel.charts.AxisOrientation;
|
import org.apache.poi.ss.usermodel.charts.AxisOrientation;
|
||||||
import org.apache.poi.ss.usermodel.charts.AxisCrosses;
|
import org.apache.poi.ss.usermodel.charts.AxisCrosses;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
|
||||||
|
@ -38,6 +39,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses;
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public abstract class XSSFChartAxis implements ChartAxis {
|
public abstract class XSSFChartAxis implements ChartAxis {
|
||||||
|
|
||||||
protected XSSFChart chart;
|
protected XSSFChart chart;
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
package org.apache.poi.xssf.usermodel.charts;
|
package org.apache.poi.xssf.usermodel.charts;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.charts.*;
|
import org.apache.poi.ss.usermodel.charts.*;
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public class XSSFChartDataFactory implements ChartDataFactory {
|
public class XSSFChartDataFactory implements ChartDataFactory {
|
||||||
|
|
||||||
private static XSSFChartDataFactory instance;
|
private static XSSFChartDataFactory instance;
|
||||||
|
@ -31,7 +33,7 @@ public class XSSFChartDataFactory implements ChartDataFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return new scatter chart data instance
|
* @return new scatter charts data instance
|
||||||
*/
|
*/
|
||||||
public XSSFScatterChartData createScatterChartData() {
|
public XSSFScatterChartData createScatterChartData() {
|
||||||
return new XSSFScatterChartData();
|
return new XSSFScatterChartData();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.apache.poi.xssf.usermodel.charts;
|
package org.apache.poi.xssf.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.ss.usermodel.charts.ChartLegend;
|
import org.apache.poi.ss.usermodel.charts.ChartLegend;
|
||||||
import org.apache.poi.ss.usermodel.charts.LegendPosition;
|
import org.apache.poi.ss.usermodel.charts.LegendPosition;
|
||||||
|
@ -30,6 +31,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos;
|
||||||
* Represents a SpreadsheetML chart legend
|
* Represents a SpreadsheetML chart legend
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public final class XSSFChartLegend implements ChartLegend {
|
public final class XSSFChartLegend implements ChartLegend {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.poi.xssf.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.charts.ChartDataSource;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package private class with utility methods.
|
||||||
|
*
|
||||||
|
* @author Roman Kashitsyn
|
||||||
|
*/
|
||||||
|
class XSSFChartUtil {
|
||||||
|
|
||||||
|
private XSSFChartUtil() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds CTAxDataSource object content from POI ChartDataSource.
|
||||||
|
* @param ctAxDataSource OOXML data source to build
|
||||||
|
* @param dataSource POI data source to use
|
||||||
|
*/
|
||||||
|
public static void buildAxDataSource(CTAxDataSource ctAxDataSource, ChartDataSource<?> dataSource) {
|
||||||
|
if (dataSource.isNumeric()) {
|
||||||
|
if (dataSource.isReference()) {
|
||||||
|
buildNumRef(ctAxDataSource.addNewNumRef(), dataSource);
|
||||||
|
} else {
|
||||||
|
buildNumLit(ctAxDataSource.addNewNumLit(), dataSource);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dataSource.isReference()) {
|
||||||
|
buildStrRef(ctAxDataSource.addNewStrRef(), dataSource);
|
||||||
|
} else {
|
||||||
|
buildStrLit(ctAxDataSource.addNewStrLit(), dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds CTNumDataSource object content from POI ChartDataSource
|
||||||
|
* @param ctNumDataSource OOXML data source to build
|
||||||
|
* @param dataSource POI data source to use
|
||||||
|
*/
|
||||||
|
public static void buildNumDataSource(CTNumDataSource ctNumDataSource,
|
||||||
|
ChartDataSource<? extends Number> dataSource) {
|
||||||
|
if (dataSource.isReference()) {
|
||||||
|
buildNumRef(ctNumDataSource.addNewNumRef(), dataSource);
|
||||||
|
} else {
|
||||||
|
buildNumLit(ctNumDataSource.addNewNumLit(), dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildNumRef(CTNumRef ctNumRef, ChartDataSource<?> dataSource) {
|
||||||
|
ctNumRef.setF(dataSource.getFormulaString());
|
||||||
|
CTNumData cache = ctNumRef.addNewNumCache();
|
||||||
|
fillNumCache(cache, dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildNumLit(CTNumData ctNumData, ChartDataSource<?> dataSource) {
|
||||||
|
fillNumCache(ctNumData, dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildStrRef(CTStrRef ctStrRef, ChartDataSource<?> dataSource) {
|
||||||
|
ctStrRef.setF(dataSource.getFormulaString());
|
||||||
|
CTStrData cache = ctStrRef.addNewStrCache();
|
||||||
|
fillStringCache(cache, dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildStrLit(CTStrData ctStrData, ChartDataSource<?> dataSource) {
|
||||||
|
fillStringCache(ctStrData, dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillStringCache(CTStrData cache, ChartDataSource<?> dataSource) {
|
||||||
|
int numOfPoints = dataSource.getPointCount();
|
||||||
|
cache.addNewPtCount().setVal(numOfPoints);
|
||||||
|
for (int i = 0; i < numOfPoints; ++i) {
|
||||||
|
Object value = dataSource.getPointAt(i);
|
||||||
|
if (value != null) {
|
||||||
|
CTStrVal ctStrVal = cache.addNewPt();
|
||||||
|
ctStrVal.setIdx(i);
|
||||||
|
ctStrVal.setV(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillNumCache(CTNumData cache, ChartDataSource<?> dataSource) {
|
||||||
|
int numOfPoints = dataSource.getPointCount();
|
||||||
|
cache.addNewPtCount().setVal(numOfPoints);
|
||||||
|
for (int i = 0; i < numOfPoints; ++i) {
|
||||||
|
Number value = (Number) dataSource.getPointAt(i);
|
||||||
|
if (value != null) {
|
||||||
|
CTNumVal ctNumVal = cache.addNewPt();
|
||||||
|
ctNumVal.setIdx(i);
|
||||||
|
ctNumVal.setV(value.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.apache.poi.xssf.usermodel.charts;
|
package org.apache.poi.xssf.usermodel.charts;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.ss.usermodel.charts.ManualLayout;
|
import org.apache.poi.ss.usermodel.charts.ManualLayout;
|
||||||
import org.apache.poi.ss.usermodel.charts.LayoutMode;
|
import org.apache.poi.ss.usermodel.charts.LayoutMode;
|
||||||
|
@ -35,6 +36,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget;
|
||||||
* Represents a SpreadsheetML manual layout.
|
* Represents a SpreadsheetML manual layout.
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public final class XSSFManualLayout implements ManualLayout {
|
public final class XSSFManualLayout implements ManualLayout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
/* ====================================================================
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
|
||||||
this work for additional information regarding copyright ownership.
|
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
(the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
==================================================================== */
|
|
||||||
|
|
||||||
package org.apache.poi.xssf.usermodel.charts;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
|
||||||
import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
|
||||||
import org.apache.poi.ss.usermodel.CellValue;
|
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
|
||||||
import org.apache.poi.ss.util.NumberToTextConverter;
|
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
|
||||||
import org.apache.poi.ss.util.cellwalk.CellWalk;
|
|
||||||
import org.apache.poi.ss.util.cellwalk.CellHandler;
|
|
||||||
import org.apache.poi.ss.util.cellwalk.CellWalkContext;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package private class to fill chart's number reference with cached
|
|
||||||
* numeric values. If a formula-typed cell referenced by data marker,
|
|
||||||
* cell's value will be calculated and placed to cache. Numeric cells
|
|
||||||
* will be placed to cache as is. Non-numeric cells will be ignored.
|
|
||||||
*
|
|
||||||
* @author Roman Kashitsyn
|
|
||||||
*/
|
|
||||||
class XSSFNumberCache {
|
|
||||||
|
|
||||||
private CTNumData ctNumData;
|
|
||||||
|
|
||||||
XSSFNumberCache(CTNumData ctNumData) {
|
|
||||||
this.ctNumData = ctNumData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds new numeric cache container.
|
|
||||||
* @param marker data marker to use for cache evaluation
|
|
||||||
* @param ctNumRef parent number reference
|
|
||||||
* @return numeric cache instance
|
|
||||||
*/
|
|
||||||
static XSSFNumberCache buildCache(DataMarker marker, CTNumRef ctNumRef) {
|
|
||||||
CellRangeAddress range = marker.getRange();
|
|
||||||
int numOfPoints = range.getNumberOfCells();
|
|
||||||
|
|
||||||
if (numOfPoints == 0) {
|
|
||||||
// Nothing to do.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
XSSFNumberCache cache = new XSSFNumberCache(ctNumRef.addNewNumCache());
|
|
||||||
cache.setPointCount(numOfPoints);
|
|
||||||
|
|
||||||
Workbook wb = marker.getSheet().getWorkbook();
|
|
||||||
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
|
|
||||||
|
|
||||||
CellWalk cellWalk = new CellWalk(marker);
|
|
||||||
NumCacheCellHandler numCacheHandler = cache.new NumCacheCellHandler(evaluator);
|
|
||||||
cellWalk.traverse(numCacheHandler);
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns total count of points in cache. Some (or even all) of
|
|
||||||
* them might be empty.
|
|
||||||
* @return total count of points in cache
|
|
||||||
*/
|
|
||||||
long getPointCount() {
|
|
||||||
CTUnsignedInt pointCount = ctNumData.getPtCount();
|
|
||||||
if (pointCount != null) {
|
|
||||||
return pointCount.getVal();
|
|
||||||
} else {
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns cache value at specified index.
|
|
||||||
* @param index index of the point in cache
|
|
||||||
* @return point value
|
|
||||||
*/
|
|
||||||
double getValueAt(int index) {
|
|
||||||
/* TODO: consider more effective algorithm. Left as is since
|
|
||||||
* this method should be invoked mostly in tests. */
|
|
||||||
for (CTNumVal pt : ctNumData.getPtList()) {
|
|
||||||
if (pt.getIdx() == index) {
|
|
||||||
return Double.valueOf(pt.getV()).doubleValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setPointCount(int numOfPoints) {
|
|
||||||
ctNumData.addNewPtCount().setVal(numOfPoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NumCacheCellHandler implements CellHandler {
|
|
||||||
|
|
||||||
private FormulaEvaluator evaluator;
|
|
||||||
|
|
||||||
public NumCacheCellHandler(FormulaEvaluator evaluator) {
|
|
||||||
this.evaluator = evaluator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onCell(Cell cell, CellWalkContext ctx) {
|
|
||||||
double pointValue = getOrEvalCellValue(cell);
|
|
||||||
/* Silently ignore non-numeric values.
|
|
||||||
* This is Office default behaviour. */
|
|
||||||
if (Double.isNaN(pointValue)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTNumVal point = ctNumData.addNewPt();
|
|
||||||
point.setIdx(ctx.getOrdinalNumber());
|
|
||||||
point.setV(NumberToTextConverter.toText(pointValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private double getOrEvalCellValue(Cell cell) {
|
|
||||||
int cellType = cell.getCellType();
|
|
||||||
|
|
||||||
if (cellType == Cell.CELL_TYPE_NUMERIC) {
|
|
||||||
return cell.getNumericCellValue();
|
|
||||||
} else if (cellType == Cell.CELL_TYPE_FORMULA) {
|
|
||||||
CellValue value = evaluator.evaluate(cell);
|
|
||||||
if (value.getCellType() == Cell.CELL_TYPE_NUMERIC) {
|
|
||||||
return value.getNumberValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Double.NaN;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,40 +17,25 @@
|
||||||
|
|
||||||
package org.apache.poi.xssf.usermodel.charts;
|
package org.apache.poi.xssf.usermodel.charts;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Chart;
|
import org.apache.poi.ss.usermodel.Chart;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.charts.ChartAxis;
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
import org.apache.poi.ss.usermodel.charts.ChartDataSource;
|
||||||
import org.apache.poi.ss.usermodel.charts.ScatterChartData;
|
import org.apache.poi.ss.usermodel.charts.ScatterChartData;
|
||||||
import org.apache.poi.ss.usermodel.charts.ScatterChartSerie;
|
import org.apache.poi.ss.usermodel.charts.ScatterChartSerie;
|
||||||
import org.apache.poi.ss.usermodel.charts.ChartDataFactory;
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.ss.usermodel.charts.ChartAxis;
|
|
||||||
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterChart;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterStyle;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScatterSer;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumFmt;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STScatterStyle;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STCrosses;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STCrossBetween;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
|
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
|
|
||||||
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents DrawingML scatter chart.
|
* Represents DrawingML scatter charts.
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public class XSSFScatterChartData implements ScatterChartData {
|
public class XSSFScatterChartData implements ScatterChartData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,118 +44,93 @@ public class XSSFScatterChartData implements ScatterChartData {
|
||||||
private List<Serie> series;
|
private List<Serie> series;
|
||||||
|
|
||||||
public XSSFScatterChartData() {
|
public XSSFScatterChartData() {
|
||||||
series = new ArrayList<Serie>();
|
series = new ArrayList<Serie>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package private ScatterChartSerie implementation.
|
* Package private ScatterChartSerie implementation.
|
||||||
*/
|
*/
|
||||||
static class Serie implements ScatterChartSerie {
|
static class Serie implements ScatterChartSerie {
|
||||||
private int id;
|
private int id;
|
||||||
private int order;
|
private int order;
|
||||||
private boolean useCache;
|
private ChartDataSource<?> xs;
|
||||||
private DataMarker xMarker;
|
private ChartDataSource<? extends Number> ys;
|
||||||
private DataMarker yMarker;
|
|
||||||
private XSSFNumberCache lastCaclulatedXCache;
|
|
||||||
private XSSFNumberCache lastCalculatedYCache;
|
|
||||||
|
|
||||||
protected Serie(int id, int order) {
|
protected Serie(int id, int order,
|
||||||
super();
|
ChartDataSource<?> xs,
|
||||||
this.id = id;
|
ChartDataSource<? extends Number> ys) {
|
||||||
this.order = order;
|
super();
|
||||||
this.useCache = true;
|
this.id = id;
|
||||||
}
|
this.order = order;
|
||||||
|
this.xs = xs;
|
||||||
|
this.ys = ys;
|
||||||
|
}
|
||||||
|
|
||||||
public void setXValues(DataMarker marker) {
|
/**
|
||||||
xMarker = marker;
|
* Returns data source used for X axis values.
|
||||||
}
|
* @return data source used for X axis values
|
||||||
|
*/
|
||||||
|
public ChartDataSource<?> getXValues() {
|
||||||
|
return xs;
|
||||||
|
}
|
||||||
|
|
||||||
public void setYValues(DataMarker marker) {
|
/**
|
||||||
yMarker = marker;
|
* Returns data source used for Y axis values.
|
||||||
}
|
* @return data source used for Y axis values
|
||||||
|
*/
|
||||||
|
public ChartDataSource<? extends Number> getYValues() {
|
||||||
|
return ys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
protected void addToChart(CTScatterChart ctScatterChart) {
|
||||||
* @param useCache if true, cached results will be added on plot
|
CTScatterSer scatterSer = ctScatterChart.addNewSer();
|
||||||
*/
|
scatterSer.addNewIdx().setVal(this.id);
|
||||||
public void setUseCache(boolean useCache) {
|
scatterSer.addNewOrder().setVal(this.order);
|
||||||
this.useCache = useCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
CTAxDataSource xVal = scatterSer.addNewXVal();
|
||||||
* Returns last calculated number cache for X axis.
|
XSSFChartUtil.buildAxDataSource(xVal, xs);
|
||||||
* @return last calculated number cache for X axis.
|
|
||||||
*/
|
|
||||||
XSSFNumberCache getLastCaculatedXCache() {
|
|
||||||
return lastCaclulatedXCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
CTNumDataSource yVal = scatterSer.addNewYVal();
|
||||||
* Returns last calculated number cache for Y axis.
|
XSSFChartUtil.buildNumDataSource(yVal, ys);
|
||||||
* @return last calculated number cache for Y axis.
|
}
|
||||||
*/
|
|
||||||
XSSFNumberCache getLastCalculatedYCache() {
|
|
||||||
return lastCalculatedYCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addToChart(CTScatterChart ctScatterChart) {
|
|
||||||
CTScatterSer scatterSer = ctScatterChart.addNewSer();
|
|
||||||
scatterSer.addNewIdx().setVal(this.id);
|
|
||||||
scatterSer.addNewOrder().setVal(this.order);
|
|
||||||
|
|
||||||
/* TODO: add some logic to automatically recognize cell
|
|
||||||
* types and choose appropriate data representation for
|
|
||||||
* X axis.
|
|
||||||
*/
|
|
||||||
CTAxDataSource xVal = scatterSer.addNewXVal();
|
|
||||||
CTNumRef xNumRef = xVal.addNewNumRef();
|
|
||||||
xNumRef.setF(xMarker.formatAsString());
|
|
||||||
|
|
||||||
CTNumDataSource yVal = scatterSer.addNewYVal();
|
|
||||||
CTNumRef yNumRef = yVal.addNewNumRef();
|
|
||||||
yNumRef.setF(yMarker.formatAsString());
|
|
||||||
|
|
||||||
if (useCache) {
|
|
||||||
/* We can not store cache since markers are not immutable */
|
|
||||||
XSSFNumberCache.buildCache(xMarker, xNumRef);
|
|
||||||
lastCalculatedYCache = XSSFNumberCache.buildCache(yMarker, yNumRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScatterChartSerie addSerie(DataMarker xMarker, DataMarker yMarker) {
|
public ScatterChartSerie addSerie(ChartDataSource<?> xs,
|
||||||
int numOfSeries = series.size();
|
ChartDataSource<? extends Number> ys) {
|
||||||
Serie newSerie = new Serie(numOfSeries, numOfSeries);
|
if (!ys.isNumeric()) {
|
||||||
newSerie.setXValues(xMarker);
|
throw new IllegalArgumentException("Y axis data source must be numeric.");
|
||||||
newSerie.setYValues(yMarker);
|
}
|
||||||
series.add(newSerie);
|
int numOfSeries = series.size();
|
||||||
return newSerie;
|
Serie newSerie = new Serie(numOfSeries, numOfSeries, xs, ys);
|
||||||
|
series.add(newSerie);
|
||||||
|
return newSerie;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fillChart(Chart chart, ChartAxis... axis) {
|
public void fillChart(Chart chart, ChartAxis... axis) {
|
||||||
if (!(chart instanceof XSSFChart)) {
|
if (!(chart instanceof XSSFChart)) {
|
||||||
throw new IllegalArgumentException("Chart must be instance of XSSFChart");
|
throw new IllegalArgumentException("Chart must be instance of XSSFChart");
|
||||||
}
|
}
|
||||||
|
|
||||||
XSSFChart xssfChart = (XSSFChart) chart;
|
XSSFChart xssfChart = (XSSFChart) chart;
|
||||||
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
|
CTPlotArea plotArea = xssfChart.getCTChart().getPlotArea();
|
||||||
CTScatterChart scatterChart = plotArea.addNewScatterChart();
|
CTScatterChart scatterChart = plotArea.addNewScatterChart();
|
||||||
addStyle(scatterChart);
|
addStyle(scatterChart);
|
||||||
|
|
||||||
for (Serie s : series) {
|
for (Serie s : series) {
|
||||||
s.addToChart(scatterChart);
|
s.addToChart(scatterChart);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ChartAxis ax : axis) {
|
for (ChartAxis ax : axis) {
|
||||||
scatterChart.addNewAxId().setVal(ax.getId());
|
scatterChart.addNewAxId().setVal(ax.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<? extends Serie> getSeries() {
|
public List<? extends Serie> getSeries() {
|
||||||
return series;
|
return series;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addStyle(CTScatterChart ctScatterChart) {
|
private void addStyle(CTScatterChart ctScatterChart) {
|
||||||
CTScatterStyle scatterStyle = ctScatterChart.addNewScatterStyle();
|
CTScatterStyle scatterStyle = ctScatterChart.addNewScatterStyle();
|
||||||
scatterStyle.setVal(STScatterStyle.LINE_MARKER);
|
scatterStyle.setVal(STScatterStyle.LINE_MARKER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.poi.ss.usermodel.charts.AxisOrientation;
|
||||||
import org.apache.poi.ss.usermodel.charts.AxisCrossBetween;
|
import org.apache.poi.ss.usermodel.charts.AxisCrossBetween;
|
||||||
import org.apache.poi.ss.usermodel.charts.AxisCrosses;
|
import org.apache.poi.ss.usermodel.charts.AxisCrosses;
|
||||||
|
|
||||||
|
import org.apache.poi.util.Beta;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
|
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxPos;
|
||||||
|
@ -39,6 +40,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;
|
||||||
*
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
|
@Beta
|
||||||
public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis {
|
public class XSSFValueAxis extends XSSFChartAxis implements ValueAxis {
|
||||||
|
|
||||||
private CTValAx ctValAx;
|
private CTValAx ctValAx;
|
||||||
|
|
|
@ -40,7 +40,7 @@ public final class TestXSSFChartSheet extends TestCase {
|
||||||
XSSFChartSheet sheet = (XSSFChartSheet)wb.getSheetAt(2);
|
XSSFChartSheet sheet = (XSSFChartSheet)wb.getSheetAt(2);
|
||||||
|
|
||||||
for(Row row : sheet) {
|
for(Row row : sheet) {
|
||||||
fail("Row iterator for chart sheets should return zero rows");
|
fail("Row iterator for charts sheets should return zero rows");
|
||||||
}
|
}
|
||||||
//access to a arbitrary row
|
//access to a arbitrary row
|
||||||
assertEquals(null, sheet.getRow(1));
|
assertEquals(null, sheet.getRow(1));
|
||||||
|
|
|
@ -332,7 +332,7 @@ public final class TestXSSFWorkbook extends BaseTestWorkbook {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Problems with XSSFWorkbook.removeSheetAt when workbook contains chart
|
* Problems with XSSFWorkbook.removeSheetAt when workbook contains charts
|
||||||
*/
|
*/
|
||||||
public void testBug47813() {
|
public void testBug47813() {
|
||||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx");
|
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("47813.xlsx");
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
/* ====================================================================
|
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
|
||||||
this work for additional information regarding copyright ownership.
|
|
||||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
(the "License"); you may not use this file except in compliance with
|
|
||||||
the License. You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
==================================================================== */
|
|
||||||
package org.apache.poi.xssf.usermodel.charts;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.*;
|
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
|
||||||
import org.apache.poi.ss.util.SheetBuilder;
|
|
||||||
import org.apache.poi.ss.usermodel.charts.*;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
||||||
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class TestXSSFNumberCache extends TestCase {
|
|
||||||
private static Object[][] plotData = {
|
|
||||||
{0, 1, 2, 3, 4},
|
|
||||||
{0, "=B1*2", "=C1*2", "=D1*2", "=E1*4"}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void testFormulaCache() {
|
|
||||||
Workbook wb = new XSSFWorkbook();
|
|
||||||
Sheet sheet = new SheetBuilder(wb, plotData).build();
|
|
||||||
Drawing drawing = sheet.createDrawingPatriarch();
|
|
||||||
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
|
|
||||||
Chart chart = drawing.createChart(anchor);
|
|
||||||
|
|
||||||
ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
|
|
||||||
ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
|
|
||||||
|
|
||||||
ScatterChartData scatterChartData =
|
|
||||||
chart.getChartDataFactory().createScatterChartData();
|
|
||||||
|
|
||||||
DataMarker xMarker = new DataMarker(sheet, CellRangeAddress.valueOf("A1:E1"));
|
|
||||||
DataMarker yMarker = new DataMarker(sheet, CellRangeAddress.valueOf("A2:E2"));
|
|
||||||
ScatterChartSerie serie = scatterChartData.addSerie(xMarker, yMarker);
|
|
||||||
|
|
||||||
chart.plot(scatterChartData, bottomAxis, leftAxis);
|
|
||||||
|
|
||||||
XSSFScatterChartData.Serie xssfScatterSerie =
|
|
||||||
(XSSFScatterChartData.Serie) serie;
|
|
||||||
XSSFNumberCache yCache = xssfScatterSerie.getLastCalculatedYCache();
|
|
||||||
|
|
||||||
assertEquals(5, yCache.getPointCount());
|
|
||||||
assertEquals(4.0, yCache.getValueAt(3), 0.00001);
|
|
||||||
assertEquals(16.0, yCache.getValueAt(5), 0.00001);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -21,42 +21,43 @@ import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
import org.apache.poi.ss.util.DataMarker;
|
|
||||||
import org.apache.poi.ss.util.SheetBuilder;
|
import org.apache.poi.ss.util.SheetBuilder;
|
||||||
import org.apache.poi.ss.usermodel.charts.*;
|
import org.apache.poi.ss.usermodel.charts.*;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for XSSFScatterChartData.
|
* Tests for XSSFScatterChartData.
|
||||||
|
*
|
||||||
* @author Roman Kashitsyn
|
* @author Roman Kashitsyn
|
||||||
*/
|
*/
|
||||||
public final class TestXSSFScatterChartData extends TestCase {
|
public final class TestXSSFScatterChartData extends TestCase {
|
||||||
|
|
||||||
private static Object[][] plotData = new Object[][] {
|
private static final Object[][] plotData = {
|
||||||
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"},
|
||||||
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void testOneSeriePlot() throws Exception {
|
public void testOneSeriePlot() throws Exception {
|
||||||
Workbook wb = new XSSFWorkbook();
|
Workbook wb = new XSSFWorkbook();
|
||||||
Sheet sheet = new SheetBuilder(wb, plotData).build();
|
Sheet sheet = new SheetBuilder(wb, plotData).build();
|
||||||
Drawing drawing = sheet.createDrawingPatriarch();
|
Drawing drawing = sheet.createDrawingPatriarch();
|
||||||
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
|
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 10, 30);
|
||||||
Chart chart = drawing.createChart(anchor);
|
Chart chart = drawing.createChart(anchor);
|
||||||
|
|
||||||
ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
|
ChartAxis bottomAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.BOTTOM);
|
||||||
ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
|
ChartAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
|
||||||
|
|
||||||
ScatterChartData scatterChartData =
|
ScatterChartData scatterChartData =
|
||||||
chart.getChartDataFactory().createScatterChartData();
|
chart.getChartDataFactory().createScatterChartData();
|
||||||
|
|
||||||
DataMarker xMarker = new DataMarker(sheet, CellRangeAddress.valueOf("A1:A10"));
|
ChartDataSource<String> xs = DataSources.fromStringCellRange(sheet, CellRangeAddress.valueOf("A1:J1"));
|
||||||
DataMarker yMarker = new DataMarker(sheet, CellRangeAddress.valueOf("B1:B10"));
|
ChartDataSource<Number> ys = DataSources.fromNumericCellRange(sheet, CellRangeAddress.valueOf("A2:J2"));
|
||||||
ScatterChartSerie serie = scatterChartData.addSerie(xMarker, yMarker);
|
ScatterChartSerie serie = scatterChartData.addSerie(xs, ys);
|
||||||
|
|
||||||
assertEquals(1, scatterChartData.getSeries().size());
|
assertNotNull(serie);
|
||||||
|
assertEquals(1, scatterChartData.getSeries().size());
|
||||||
|
assertTrue(scatterChartData.getSeries().contains(serie));
|
||||||
|
|
||||||
chart.plot(scatterChartData, bottomAxis, leftAxis);
|
chart.plot(scatterChartData, bottomAxis, leftAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.ss.usermodel.charts;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.ss.util.SheetBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link org.apache.poi.ss.usermodel.charts.DataSources}.
|
||||||
|
*
|
||||||
|
* @author Roman Kashitsyn
|
||||||
|
*/
|
||||||
|
public class TestDataSources extends TestCase {
|
||||||
|
|
||||||
|
private static final Object[][] numericCells = {
|
||||||
|
{0.0, 1.0, 2.0, 3.0, 4.0},
|
||||||
|
{0.0, "=B1*2", "=C1*2", "=D1*2", "=E1*2"}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Object[][] stringCells = {
|
||||||
|
{ 1, 2, 3, 4, 5},
|
||||||
|
{"A", "B", "C", "D", "E"}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Object[][] mixedCells = {
|
||||||
|
{1.0, "2.0", 3.0, "4.0", 5.0, "6.0"}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void testNumericArrayDataSource() {
|
||||||
|
Double[] doubles = new Double[]{1.0, 2.0, 3.0, 4.0, 5.0};
|
||||||
|
ChartDataSource<Double> doubleDataSource = DataSources.fromArray(doubles);
|
||||||
|
assertTrue(doubleDataSource.isNumeric());
|
||||||
|
assertFalse(doubleDataSource.isReference());
|
||||||
|
assertDataSourceIsEqualToArray(doubleDataSource, doubles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStringArrayDataSource() {
|
||||||
|
String[] strings = new String[]{"one", "two", "three", "four", "five"};
|
||||||
|
ChartDataSource<String> stringDataSource = DataSources.fromArray(strings);
|
||||||
|
assertFalse(stringDataSource.isNumeric());
|
||||||
|
assertFalse(stringDataSource.isReference());
|
||||||
|
assertDataSourceIsEqualToArray(stringDataSource, strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNumericCellDataSource() {
|
||||||
|
Workbook wb = new HSSFWorkbook();
|
||||||
|
Sheet sheet = new SheetBuilder(wb, numericCells).build();
|
||||||
|
CellRangeAddress numCellRange = CellRangeAddress.valueOf("A2:E2");
|
||||||
|
ChartDataSource<Number> numDataSource = DataSources.fromNumericCellRange(sheet, numCellRange);
|
||||||
|
assertTrue(numDataSource.isReference());
|
||||||
|
assertTrue(numDataSource.isNumeric());
|
||||||
|
assertEquals(numericCells[0].length, numDataSource.getPointCount());
|
||||||
|
for (int i = 0; i < numericCells[0].length; ++i) {
|
||||||
|
assertEquals(((Number) numericCells[0][i]).doubleValue() * 2,
|
||||||
|
numDataSource.getPointAt(i).doubleValue(), 0.00001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStringCellDataSource() {
|
||||||
|
Workbook wb = new HSSFWorkbook();
|
||||||
|
Sheet sheet = new SheetBuilder(wb, stringCells).build();
|
||||||
|
CellRangeAddress numCellRange = CellRangeAddress.valueOf("A2:E2");
|
||||||
|
ChartDataSource<String> numDataSource = DataSources.fromStringCellRange(sheet, numCellRange);
|
||||||
|
assertTrue(numDataSource.isReference());
|
||||||
|
assertFalse(numDataSource.isNumeric());
|
||||||
|
assertEquals(numericCells[0].length, numDataSource.getPointCount());
|
||||||
|
for (int i = 0; i < stringCells[1].length; ++i) {
|
||||||
|
assertEquals(stringCells[1][i], numDataSource.getPointAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMixedCellDataSource() {
|
||||||
|
Workbook wb = new HSSFWorkbook();
|
||||||
|
Sheet sheet = new SheetBuilder(wb, mixedCells).build();
|
||||||
|
CellRangeAddress mixedCellRange = CellRangeAddress.valueOf("A1:F1");
|
||||||
|
ChartDataSource<String> strDataSource = DataSources.fromStringCellRange(sheet, mixedCellRange);
|
||||||
|
ChartDataSource<Number> numDataSource = DataSources.fromNumericCellRange(sheet, mixedCellRange);
|
||||||
|
for (int i = 0; i < mixedCells[0].length; ++i) {
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
assertNull(strDataSource.getPointAt(i));
|
||||||
|
assertEquals(((Number) mixedCells[0][i]).doubleValue(),
|
||||||
|
numDataSource.getPointAt(i).doubleValue(), 0.00001);
|
||||||
|
} else {
|
||||||
|
assertNull(numDataSource.getPointAt(i));
|
||||||
|
assertEquals(mixedCells[0][i], strDataSource.getPointAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIOBExceptionOnInvalidIndex() {
|
||||||
|
Workbook wb = new HSSFWorkbook();
|
||||||
|
Sheet sheet = new SheetBuilder(wb, numericCells).build();
|
||||||
|
CellRangeAddress rangeAddress = CellRangeAddress.valueOf("A2:E2");
|
||||||
|
ChartDataSource<Number> numDataSource = DataSources.fromNumericCellRange(sheet, rangeAddress);
|
||||||
|
IndexOutOfBoundsException exception = null;
|
||||||
|
try {
|
||||||
|
numDataSource.getPointAt(-1);
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
assertNotNull(exception);
|
||||||
|
|
||||||
|
exception = null;
|
||||||
|
try {
|
||||||
|
numDataSource.getPointAt(numDataSource.getPointCount());
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
assertNotNull(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void assertDataSourceIsEqualToArray(ChartDataSource<T> ds, T[] array) {
|
||||||
|
assertEquals(ds.getPointCount(), array.length);
|
||||||
|
for (int i = 0; i < array.length; ++i) {
|
||||||
|
assertEquals(ds.getPointAt(i), array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,49 +29,56 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests SheetBuilder.
|
* Tests SheetBuilder.
|
||||||
|
*
|
||||||
* @see org.apache.poi.ss.util.SheetBuilder
|
* @see org.apache.poi.ss.util.SheetBuilder
|
||||||
*/
|
*/
|
||||||
public final class TestSheetBuilder extends TestCase {
|
public final class TestSheetBuilder extends TestCase {
|
||||||
|
|
||||||
private static Object[][] testData = new Object[][] {
|
private static Object[][] testData = new Object[][]{
|
||||||
{ 1, 2, 3},
|
{1, 2, 3},
|
||||||
{new Date(), null, null},
|
{new Date(), null, null},
|
||||||
{ "one", "two", "=A1+B2"}
|
{"one", "two", "=A1+B2"}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void testNotCreateEmptyCells() {
|
public void testNotCreateEmptyCells() {
|
||||||
Workbook wb = new HSSFWorkbook();
|
Workbook wb = new HSSFWorkbook();
|
||||||
Sheet sheet = new SheetBuilder(wb, testData).build();
|
Sheet sheet = new SheetBuilder(wb, testData).build();
|
||||||
|
|
||||||
assertEquals(sheet.getPhysicalNumberOfRows(), 3);
|
|
||||||
|
|
||||||
Row firstRow = sheet.getRow(0);
|
assertEquals(sheet.getPhysicalNumberOfRows(), 3);
|
||||||
Cell firstCell = firstRow.getCell(0);
|
|
||||||
|
|
||||||
assertEquals(firstCell.getCellType(), Cell.CELL_TYPE_NUMERIC);
|
Row firstRow = sheet.getRow(0);
|
||||||
assertEquals(1.0, firstCell.getNumericCellValue(), 0.00001);
|
Cell firstCell = firstRow.getCell(0);
|
||||||
|
|
||||||
|
|
||||||
Row secondRow = sheet.getRow(1);
|
assertEquals(firstCell.getCellType(), Cell.CELL_TYPE_NUMERIC);
|
||||||
assertNotNull(secondRow.getCell(0));
|
assertEquals(1.0, firstCell.getNumericCellValue(), 0.00001);
|
||||||
assertNull(secondRow.getCell(2));
|
|
||||||
|
|
||||||
Row thirdRow = sheet.getRow(2);
|
|
||||||
assertEquals(Cell.CELL_TYPE_STRING, thirdRow.getCell(0).getCellType());
|
Row secondRow = sheet.getRow(1);
|
||||||
String cellValue = thirdRow.getCell(0).getStringCellValue();
|
assertNotNull(secondRow.getCell(0));
|
||||||
assertEquals(testData[2][0].toString(), cellValue);
|
assertNull(secondRow.getCell(2));
|
||||||
|
|
||||||
assertEquals(Cell.CELL_TYPE_FORMULA, thirdRow.getCell(2).getCellType());
|
Row thirdRow = sheet.getRow(2);
|
||||||
assertEquals("A1+B2", thirdRow.getCell(2).getCellFormula());
|
assertEquals(Cell.CELL_TYPE_STRING, thirdRow.getCell(0).getCellType());
|
||||||
|
String cellValue = thirdRow.getCell(0).getStringCellValue();
|
||||||
|
assertEquals(testData[2][0].toString(), cellValue);
|
||||||
|
|
||||||
|
assertEquals(Cell.CELL_TYPE_FORMULA, thirdRow.getCell(2).getCellType());
|
||||||
|
assertEquals("A1+B2", thirdRow.getCell(2).getCellFormula());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEmptyCells() {
|
public void testEmptyCells() {
|
||||||
Workbook wb = new HSSFWorkbook();
|
Workbook wb = new HSSFWorkbook();
|
||||||
Sheet sheet = new SheetBuilder(wb, testData).setCreateEmptyCells(true).build();
|
Sheet sheet = new SheetBuilder(wb, testData).setCreateEmptyCells(true).build();
|
||||||
|
|
||||||
Cell emptyCell = sheet.getRow(1).getCell(1);
|
Cell emptyCell = sheet.getRow(1).getCell(1);
|
||||||
assertNotNull(emptyCell);
|
assertNotNull(emptyCell);
|
||||||
assertEquals(Cell.CELL_TYPE_BLANK, emptyCell.getCellType());
|
assertEquals(Cell.CELL_TYPE_BLANK, emptyCell.getCellType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testSheetName() {
|
||||||
|
final String sheetName = "TEST SHEET NAME";
|
||||||
|
Workbook wb = new HSSFWorkbook();
|
||||||
|
Sheet sheet = new SheetBuilder(wb, testData).setSheetName(sheetName).build();
|
||||||
|
assertEquals(sheetName, sheet.getSheetName());
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue