Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

TableStyleType.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.ss.usermodel;
  16. import org.apache.poi.ss.util.CellRangeAddress;
  17. import org.apache.poi.ss.util.CellRangeAddressBase;
  18. import org.apache.poi.ss.util.CellReference;
  19. /**
  20. * Ordered list of table style elements, for both data tables and pivot tables.
  21. * Some elements only apply to pivot tables, but any style definition can omit any number,
  22. * so having them in one list should not be a problem.
  23. * <p>
  24. * The order is the specification order of application, with later elements overriding previous
  25. * ones, if style properties conflict.
  26. * <p>
  27. * Processing could iterate bottom-up if looking for specific properties, and stop when the
  28. * first style is found defining a value for that property.
  29. * <p>
  30. * Enum names match the OOXML spec values exactly, so {@link #valueOf(String)} will work.
  31. *
  32. * @since 3.17 beta 1
  33. */
  34. public enum TableStyleType {
  35. /***/
  36. wholeTable {
  37. @Override
  38. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  39. return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), table.getStartColIndex(), table.getEndColIndex());
  40. }
  41. },
  42. /***/
  43. pageFieldLabels, // pivot only
  44. /***/
  45. pageFieldValues, // pivot only
  46. /***/
  47. firstColumnStripe{
  48. @Override
  49. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  50. TableStyleInfo info = table.getStyle();
  51. if (! info.isShowColumnStripes()) return null;
  52. DifferentialStyleProvider c1Style = info.getStyle().getStyle(firstColumnStripe);
  53. DifferentialStyleProvider c2Style = info.getStyle().getStyle(secondColumnStripe);
  54. int c1Stripe = c1Style == null ? 1 : Math.max(1, c1Style.getStripeSize());
  55. int c2Stripe = c2Style == null ? 1 : Math.max(1, c2Style.getStripeSize());
  56. int firstStart = table.getStartColIndex();
  57. int secondStart = firstStart + c1Stripe;
  58. final int c = cell.getCol();
  59. // look for the stripe containing c, accounting for the style element stripe size
  60. // could do fancy math, but tables can't be that wide, a simple loop is fine
  61. // if not in this type of stripe, return null
  62. while (firstStart <= c) {
  63. if (c <= secondStart -1) {
  64. return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), firstStart, secondStart - 1);
  65. }
  66. firstStart = secondStart + c2Stripe;
  67. secondStart = firstStart + c1Stripe;
  68. }
  69. return null;
  70. }
  71. },
  72. /***/
  73. secondColumnStripe{
  74. @Override
  75. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  76. TableStyleInfo info = table.getStyle();
  77. if (! info.isShowColumnStripes()) return null;
  78. DifferentialStyleProvider c1Style = info.getStyle().getStyle(firstColumnStripe);
  79. DifferentialStyleProvider c2Style = info.getStyle().getStyle(secondColumnStripe);
  80. int c1Stripe = c1Style == null ? 1 : Math.max(1, c1Style.getStripeSize());
  81. int c2Stripe = c2Style == null ? 1 : Math.max(1, c2Style.getStripeSize());
  82. int firstStart = table.getStartColIndex();
  83. int secondStart = firstStart + c1Stripe;
  84. final int c = cell.getCol();
  85. // look for the stripe containing c, accounting for the style element stripe size
  86. // could do fancy math, but tables can't be that wide, a simple loop is fine
  87. // if not in this type of stripe, return null
  88. while (firstStart <= c) {
  89. if (c >= secondStart && c <= secondStart + c2Stripe -1) {
  90. return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), secondStart, secondStart + c2Stripe - 1);
  91. }
  92. firstStart = secondStart + c2Stripe;
  93. secondStart = firstStart + c1Stripe;
  94. }
  95. return null;
  96. }
  97. },
  98. /***/
  99. firstRowStripe {
  100. @Override
  101. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  102. TableStyleInfo info = table.getStyle();
  103. if (! info.isShowRowStripes()) return null;
  104. DifferentialStyleProvider c1Style = info.getStyle().getStyle(firstRowStripe);
  105. DifferentialStyleProvider c2Style = info.getStyle().getStyle(secondRowStripe);
  106. int c1Stripe = c1Style == null ? 1 : Math.max(1, c1Style.getStripeSize());
  107. int c2Stripe = c2Style == null ? 1 : Math.max(1, c2Style.getStripeSize());
  108. int firstStart = table.getStartRowIndex() + table.getHeaderRowCount();
  109. int secondStart = firstStart + c1Stripe;
  110. final int c = cell.getRow();
  111. // look for the stripe containing c, accounting for the style element stripe size
  112. // could do fancy math, but tables can't be that wide, a simple loop is fine
  113. // if not in this type of stripe, return null
  114. while (firstStart <= c) {
  115. if (c <= secondStart -1) {
  116. return new CellRangeAddress(firstStart, secondStart - 1, table.getStartColIndex(), table.getEndColIndex());
  117. }
  118. firstStart = secondStart + c2Stripe;
  119. secondStart = firstStart + c1Stripe;
  120. }
  121. return null;
  122. }
  123. },
  124. /***/
  125. secondRowStripe{
  126. @Override
  127. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  128. TableStyleInfo info = table.getStyle();
  129. if (! info.isShowRowStripes()) return null;
  130. DifferentialStyleProvider c1Style = info.getStyle().getStyle(firstRowStripe);
  131. DifferentialStyleProvider c2Style = info.getStyle().getStyle(secondRowStripe);
  132. int c1Stripe = c1Style == null ? 1 : Math.max(1, c1Style.getStripeSize());
  133. int c2Stripe = c2Style == null ? 1 : Math.max(1, c2Style.getStripeSize());
  134. int firstStart = table.getStartRowIndex() + table.getHeaderRowCount();
  135. int secondStart = firstStart + c1Stripe;
  136. final int c = cell.getRow();
  137. // look for the stripe containing c, accounting for the style element stripe size
  138. // could do fancy math, but tables can't be that wide, a simple loop is fine
  139. // if not in this type of stripe, return null
  140. while (firstStart <= c) {
  141. if (c >= secondStart && c <= secondStart +c2Stripe -1) {
  142. return new CellRangeAddress(secondStart, secondStart + c2Stripe - 1, table.getStartColIndex(), table.getEndColIndex());
  143. }
  144. firstStart = secondStart + c2Stripe;
  145. secondStart = firstStart + c1Stripe;
  146. }
  147. return null;
  148. }
  149. },
  150. /***/
  151. lastColumn {
  152. @Override
  153. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  154. if (! table.getStyle().isShowLastColumn()) return null;
  155. return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), table.getEndColIndex(), table.getEndColIndex());
  156. }
  157. },
  158. /***/
  159. firstColumn {
  160. @Override
  161. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  162. if (! table.getStyle().isShowFirstColumn()) return null;
  163. return new CellRangeAddress(table.getStartRowIndex(), table.getEndRowIndex(), table.getStartColIndex(), table.getStartColIndex());
  164. }
  165. },
  166. /***/
  167. headerRow {
  168. @Override
  169. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  170. if (table.getHeaderRowCount() < 1) return null;
  171. return new CellRangeAddress(table.getStartRowIndex(), table.getStartRowIndex() + table.getHeaderRowCount() -1, table.getStartColIndex(), table.getEndColIndex());
  172. }
  173. },
  174. /***/
  175. totalRow {
  176. @Override
  177. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  178. if (table.getTotalsRowCount() < 1) return null;
  179. return new CellRangeAddress(table.getEndRowIndex() - table.getTotalsRowCount() +1, table.getEndRowIndex(), table.getStartColIndex(), table.getEndColIndex());
  180. }
  181. },
  182. /***/
  183. firstHeaderCell {
  184. @Override
  185. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  186. if (table.getHeaderRowCount() < 1) return null;
  187. return new CellRangeAddress(table.getStartRowIndex(), table.getStartRowIndex(), table.getStartColIndex(), table.getStartColIndex());
  188. }
  189. },
  190. /***/
  191. lastHeaderCell {
  192. @Override
  193. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  194. if (table.getHeaderRowCount() < 1) return null;
  195. return new CellRangeAddress(table.getStartRowIndex(), table.getStartRowIndex(), table.getEndColIndex(), table.getEndColIndex());
  196. }
  197. },
  198. /***/
  199. firstTotalCell {
  200. @Override
  201. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  202. if (table.getTotalsRowCount() < 1) return null;
  203. return new CellRangeAddress(table.getEndRowIndex() - table.getTotalsRowCount() +1, table.getEndRowIndex(), table.getStartColIndex(), table.getStartColIndex());
  204. }
  205. },
  206. /***/
  207. lastTotalCell {
  208. @Override
  209. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  210. if (table.getTotalsRowCount() < 1) return null;
  211. return new CellRangeAddress(table.getEndRowIndex() - table.getTotalsRowCount() +1, table.getEndRowIndex(), table.getEndColIndex(), table.getEndColIndex());
  212. }
  213. },
  214. /* these are for pivot tables only */
  215. /***/
  216. firstSubtotalColumn,
  217. /***/
  218. secondSubtotalColumn,
  219. /***/
  220. thirdSubtotalColumn,
  221. /***/
  222. blankRow,
  223. /***/
  224. firstSubtotalRow,
  225. /***/
  226. secondSubtotalRow,
  227. /***/
  228. thirdSubtotalRow,
  229. /***/
  230. firstColumnSubheading,
  231. /***/
  232. secondColumnSubheading,
  233. /***/
  234. thirdColumnSubheading,
  235. /***/
  236. firstRowSubheading,
  237. /***/
  238. secondRowSubheading,
  239. /***/
  240. thirdRowSubheading,
  241. ;
  242. /**
  243. * A range is returned only for the part of the table matching this enum instance and containing the given cell.
  244. * Null is returned for all other cases, such as:
  245. * <ul>
  246. * <li>Cell on a different sheet than the table
  247. * <li>Cell outside the table
  248. * <li>this Enum part is not included in the table (i.e. no header/totals row)
  249. * <li>this Enum is for a table part not yet implemented in POI, such as pivot table elements
  250. * </ul>
  251. * The returned range can be used to determine how style options may or may not apply to this cell.
  252. * For example, {@link #wholeTable} borders only apply to the outer boundary of a table, while the
  253. * rest of the styling, such as font and color, could apply to all the interior cells as well.
  254. *
  255. * @param table table to evaluate
  256. * @param cell to evaluate
  257. * @return range in the table representing this class of cells, if it contains the given cell, or null if not applicable.
  258. * Stripe style types return only the stripe range containing the given cell, or null.
  259. */
  260. public CellRangeAddressBase appliesTo(Table table, Cell cell) {
  261. if (cell == null) return null;
  262. return appliesTo(table, new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(), true, true));
  263. }
  264. /**
  265. * A range is returned only for the part of the table matching this enum instance and containing the given cell reference.
  266. * Null is returned for all other cases, such as:
  267. * <ul>
  268. * <li>Cell on a different sheet than the table
  269. * <li>Cell outside the table
  270. * <li>this Enum part is not included in the table (i.e. no header/totals row)
  271. * <li>this Enum is for a table part not yet implemented in POI, such as pivot table elements
  272. * </ul>
  273. * The returned range can be used to determine how style options may or may not apply to this cell.
  274. * For example, {@link #wholeTable} borders only apply to the outer boundary of a table, while the
  275. * rest of the styling, such as font and color, could apply to all the interior cells as well.
  276. *
  277. * @param table table to evaluate
  278. * @param cell CellReference to evaluate
  279. * @return range in the table representing this class of cells, if it contains the given cell, or null if not applicable.
  280. * Stripe style types return only the stripe range containing the given cell, or null.
  281. */
  282. public CellRangeAddressBase appliesTo(Table table, CellReference cell) {
  283. if (table == null || cell == null) return null;
  284. if ( ! cell.getSheetName().equals(table.getSheetName())) return null;
  285. if ( ! table.contains(cell)) return null;
  286. final CellRangeAddressBase range = getRange(table, cell);
  287. if (range != null && range.isInRange(cell.getRow(), cell.getCol())) return range;
  288. // else
  289. return null;
  290. }
  291. /**
  292. * Calls {@link #getRange(Table, CellReference)}. Use that instead for performance.
  293. * @return default is unimplemented/null
  294. * @see #getRange(Table, CellReference)
  295. */
  296. public final CellRangeAddressBase getRange(Table table, Cell cell) {
  297. if (cell == null) return null;
  298. return getRange(table, new CellReference(cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex(), true, true));
  299. }
  300. /**
  301. * @return default is unimplemented/null
  302. */
  303. public CellRangeAddressBase getRange(Table table, CellReference cell) {
  304. return null;
  305. }
  306. }