You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DataSources.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.ss.usermodel.charts;
  20. import org.apache.poi.ss.usermodel.*;
  21. import org.apache.poi.ss.util.CellRangeAddress;
  22. import org.apache.poi.util.Beta;
  23. /**
  24. * Class {@code DataSources} is a factory for {@link ChartDataSource} instances.
  25. *
  26. * @author Roman Kashitsyn
  27. */
  28. @Beta
  29. public class DataSources {
  30. private DataSources() {
  31. }
  32. public static <T> ChartDataSource<T> fromArray(T[] elements) {
  33. return new ArrayDataSource<T>(elements);
  34. }
  35. public static ChartDataSource<Number> fromNumericCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
  36. return new AbstractCellRangeDataSource<Number>(sheet, cellRangeAddress) {
  37. public Number getPointAt(int index) {
  38. CellValue cellValue = getCellValueAt(index);
  39. if (cellValue != null && cellValue.getCellTypeEnum() == CellType.NUMERIC) {
  40. return Double.valueOf(cellValue.getNumberValue());
  41. } else {
  42. return null;
  43. }
  44. }
  45. public boolean isNumeric() {
  46. return true;
  47. }
  48. };
  49. }
  50. public static ChartDataSource<String> fromStringCellRange(Sheet sheet, CellRangeAddress cellRangeAddress) {
  51. return new AbstractCellRangeDataSource<String>(sheet, cellRangeAddress) {
  52. public String getPointAt(int index) {
  53. CellValue cellValue = getCellValueAt(index);
  54. if (cellValue != null && cellValue.getCellTypeEnum() == CellType.STRING) {
  55. return cellValue.getStringValue();
  56. } else {
  57. return null;
  58. }
  59. }
  60. public boolean isNumeric() {
  61. return false;
  62. }
  63. };
  64. }
  65. private static class ArrayDataSource<T> implements ChartDataSource<T> {
  66. private final T[] elements;
  67. public ArrayDataSource(T[] elements) {
  68. this.elements = elements.clone();
  69. }
  70. public int getPointCount() {
  71. return elements.length;
  72. }
  73. public T getPointAt(int index) {
  74. return elements[index];
  75. }
  76. public boolean isReference() {
  77. return false;
  78. }
  79. public boolean isNumeric() {
  80. Class<?> arrayComponentType = elements.getClass().getComponentType();
  81. return (Number.class.isAssignableFrom(arrayComponentType));
  82. }
  83. public String getFormulaString() {
  84. throw new UnsupportedOperationException("Literal data source can not be expressed by reference.");
  85. }
  86. }
  87. private abstract static class AbstractCellRangeDataSource<T> implements ChartDataSource<T> {
  88. private final Sheet sheet;
  89. private final CellRangeAddress cellRangeAddress;
  90. private final int numOfCells;
  91. private FormulaEvaluator evaluator;
  92. protected AbstractCellRangeDataSource(Sheet sheet, CellRangeAddress cellRangeAddress) {
  93. this.sheet = sheet;
  94. // Make copy since CellRangeAddress is mutable.
  95. this.cellRangeAddress = cellRangeAddress.copy();
  96. this.numOfCells = this.cellRangeAddress.getNumberOfCells();
  97. this.evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator();
  98. }
  99. public int getPointCount() {
  100. return numOfCells;
  101. }
  102. public boolean isReference() {
  103. return true;
  104. }
  105. public String getFormulaString() {
  106. return cellRangeAddress.formatAsString(sheet.getSheetName(), true);
  107. }
  108. protected CellValue getCellValueAt(int index) {
  109. if (index < 0 || index >= numOfCells) {
  110. throw new IndexOutOfBoundsException("Index must be between 0 and " +
  111. (numOfCells - 1) + " (inclusive), given: " + index);
  112. }
  113. int firstRow = cellRangeAddress.getFirstRow();
  114. int firstCol = cellRangeAddress.getFirstColumn();
  115. int lastCol = cellRangeAddress.getLastColumn();
  116. int width = lastCol - firstCol + 1;
  117. int rowIndex = firstRow + index / width;
  118. int cellIndex = firstCol + index % width;
  119. Row row = sheet.getRow(rowIndex);
  120. return (row == null) ? null : evaluator.evaluate(row.getCell(cellIndex));
  121. }
  122. }
  123. }