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.

ConditionalFormats.java 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  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.examples.ss;
  20. import java.io.FileOutputStream;
  21. import java.io.IOException;
  22. import java.util.List;
  23. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  24. import org.apache.poi.ss.formula.ConditionalFormattingEvaluator;
  25. import org.apache.poi.ss.formula.EvaluationConditionalFormatRule;
  26. import org.apache.poi.ss.formula.WorkbookEvaluatorProvider;
  27. import org.apache.poi.ss.usermodel.BuiltinFormats;
  28. import org.apache.poi.ss.usermodel.Cell;
  29. import org.apache.poi.ss.usermodel.CellStyle;
  30. import org.apache.poi.ss.usermodel.ColorScaleFormatting;
  31. import org.apache.poi.ss.usermodel.ComparisonOperator;
  32. import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
  33. import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;
  34. import org.apache.poi.ss.usermodel.DataBarFormatting;
  35. import org.apache.poi.ss.usermodel.ExtendedColor;
  36. import org.apache.poi.ss.usermodel.FontFormatting;
  37. import org.apache.poi.ss.usermodel.IconMultiStateFormatting;
  38. import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
  39. import org.apache.poi.ss.usermodel.IndexedColors;
  40. import org.apache.poi.ss.usermodel.PatternFormatting;
  41. import org.apache.poi.ss.usermodel.Row;
  42. import org.apache.poi.ss.usermodel.Sheet;
  43. import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
  44. import org.apache.poi.ss.usermodel.Workbook;
  45. import org.apache.poi.ss.util.CellRangeAddress;
  46. import org.apache.poi.ss.util.CellReference;
  47. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  48. /**
  49. * Excel Conditional Formatting -- Examples
  50. *
  51. * <p>
  52. * Partly based on the code snippets from
  53. * http://www.contextures.com/xlcondformat03.html
  54. * </p>
  55. */
  56. @SuppressWarnings({"java:S106","java:S4823","java:S1192"})
  57. public final class ConditionalFormats {
  58. private ConditionalFormats() {}
  59. /**
  60. * generates a sample workbook with conditional formatting,
  61. * and prints out a summary of applied formats for one sheet
  62. * @param args pass "-xls" to generate an HSSF workbook, default is XSSF
  63. */
  64. public static void main(String[] args) throws IOException {
  65. final boolean isHSSF = args.length > 0 && args[0].equals("-xls");
  66. try (Workbook wb = isHSSF ? new HSSFWorkbook() : new XSSFWorkbook()) {
  67. sameCell(wb.createSheet("Same Cell"));
  68. multiCell(wb.createSheet("MultiCell"));
  69. overlapping(wb.createSheet("Overlapping"));
  70. errors(wb.createSheet("Errors"));
  71. hideDupplicates(wb.createSheet("Hide Dups"));
  72. formatDuplicates(wb.createSheet("Duplicates"));
  73. inList(wb.createSheet("In List"));
  74. expiry(wb.createSheet("Expiry"));
  75. shadeAlt(wb.createSheet("Shade Alt"));
  76. shadeBands(wb.createSheet("Shade Bands"));
  77. iconSets(wb.createSheet("Icon Sets"));
  78. colourScales(wb.createSheet("Colour Scales"));
  79. dataBars(wb.createSheet("Data Bars"));
  80. // print overlapping rule results
  81. evaluateRules(wb, "Overlapping");
  82. // Write the output to a file
  83. String file = "cf-poi.xls";
  84. if (wb instanceof XSSFWorkbook) {
  85. file += "x";
  86. }
  87. try (FileOutputStream out = new FileOutputStream(file)) {
  88. wb.write(out);
  89. }
  90. System.out.println("Generated: " + file);
  91. }
  92. }
  93. /**
  94. * Highlight cells based on their values
  95. */
  96. static void sameCell(Sheet sheet) {
  97. sheet.createRow(0).createCell(0).setCellValue(84);
  98. sheet.createRow(1).createCell(0).setCellValue(74);
  99. sheet.createRow(2).createCell(0).setCellValue(50);
  100. sheet.createRow(3).createCell(0).setCellValue(51);
  101. sheet.createRow(4).createCell(0).setCellValue(49);
  102. sheet.createRow(5).createCell(0).setCellValue(41);
  103. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  104. // Condition 1: Cell Value Is greater than 70 (Blue Fill)
  105. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.GT, "70");
  106. PatternFormatting fill1 = rule1.createPatternFormatting();
  107. fill1.setFillBackgroundColor(IndexedColors.BLUE.index);
  108. fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  109. // Condition 2: Cell Value Is less than 50 (Green Fill)
  110. ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.LT, "50");
  111. PatternFormatting fill2 = rule2.createPatternFormatting();
  112. fill2.setFillBackgroundColor(IndexedColors.GREEN.index);
  113. fill2.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  114. CellRangeAddress[] regions = {
  115. CellRangeAddress.valueOf("A1:A6")
  116. };
  117. sheetCF.addConditionalFormatting(regions, rule1, rule2);
  118. sheet.getRow(0).createCell(2).setCellValue("<== Condition 1: Cell Value Is greater than 70 (Blue Fill)");
  119. sheet.getRow(4).createCell(2).setCellValue("<== Condition 2: Cell Value Is less than 50 (Green Fill)");
  120. }
  121. /**
  122. * Highlight multiple cells based on a formula
  123. */
  124. static void multiCell(Sheet sheet) {
  125. // header row
  126. Row row0 = sheet.createRow(0);
  127. row0.createCell(0).setCellValue("Units");
  128. row0.createCell(1).setCellValue("Cost");
  129. row0.createCell(2).setCellValue("Total");
  130. Row row1 = sheet.createRow(1);
  131. row1.createCell(0).setCellValue(71);
  132. row1.createCell(1).setCellValue(29);
  133. row1.createCell(2).setCellValue(2059);
  134. Row row2 = sheet.createRow(2);
  135. row2.createCell(0).setCellValue(85);
  136. row2.createCell(1).setCellValue(29);
  137. row2.createCell(2).setCellValue(2059);
  138. Row row3 = sheet.createRow(3);
  139. row3.createCell(0).setCellValue(71);
  140. row3.createCell(1).setCellValue(29);
  141. row3.createCell(2).setCellValue(2059);
  142. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  143. // Condition 1: Formula Is =$B2>75 (Blue Fill)
  144. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("$A2>75");
  145. PatternFormatting fill1 = rule1.createPatternFormatting();
  146. fill1.setFillBackgroundColor(IndexedColors.BLUE.index);
  147. fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  148. CellRangeAddress[] regions = {
  149. CellRangeAddress.valueOf("A2:C4")
  150. };
  151. sheetCF.addConditionalFormatting(regions, rule1);
  152. sheet.getRow(2).createCell(4).setCellValue("<== Condition 1: Formula Is =$B2>75 (Blue Fill)");
  153. }
  154. /**
  155. * Multiple conditional formatting rules can apply to
  156. * one cell, some combining, some beating others.
  157. * Done in order of the rules added to the
  158. * SheetConditionalFormatting object
  159. */
  160. static void overlapping(Sheet sheet) {
  161. for (int i=0; i<40; i++) {
  162. int rn = i+1;
  163. Row r = sheet.createRow(i);
  164. r.createCell(0).setCellValue("This is row " + rn + " (" + i + ")");
  165. String str = "";
  166. if (rn%2 == 0) {
  167. str = str + "even ";
  168. }
  169. if (rn%3 == 0) {
  170. str = str + "x3 ";
  171. }
  172. if (rn%5 == 0) {
  173. str = str + "x5 ";
  174. }
  175. if (rn%10 == 0) {
  176. str = str + "x10 ";
  177. }
  178. if (str.length() == 0) {
  179. str = "nothing special...";
  180. }
  181. r.createCell(1).setCellValue("It is " + str);
  182. }
  183. sheet.autoSizeColumn(0);
  184. sheet.autoSizeColumn(1);
  185. sheet.getRow(1).createCell(3).setCellValue("Even rows are blue");
  186. sheet.getRow(2).createCell(3).setCellValue("Multiples of 3 have a grey background");
  187. sheet.getRow(4).createCell(3).setCellValue("Multiples of 5 are bold");
  188. sheet.getRow(9).createCell(3).setCellValue("Multiples of 10 are red (beats even)");
  189. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  190. // Condition 1: Row divides by 10, red (will beat #1)
  191. ConditionalFormattingRule rule1 =
  192. sheetCF.createConditionalFormattingRule("MOD(ROW(),10)=0");
  193. FontFormatting font1 = rule1.createFontFormatting();
  194. font1.setFontColorIndex(IndexedColors.RED.index);
  195. // Condition 2: Row is even, blue
  196. ConditionalFormattingRule rule2 =
  197. sheetCF.createConditionalFormattingRule("MOD(ROW(),2)=0");
  198. FontFormatting font2 = rule2.createFontFormatting();
  199. font2.setFontColorIndex(IndexedColors.BLUE.index);
  200. // Condition 3: Row divides by 5, bold
  201. ConditionalFormattingRule rule3 =
  202. sheetCF.createConditionalFormattingRule("MOD(ROW(),5)=0");
  203. FontFormatting font3 = rule3.createFontFormatting();
  204. font3.setFontStyle(false, true);
  205. // Condition 4: Row divides by 3, grey background
  206. ConditionalFormattingRule rule4 =
  207. sheetCF.createConditionalFormattingRule("MOD(ROW(),3)=0");
  208. PatternFormatting fill4 = rule4.createPatternFormatting();
  209. fill4.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index);
  210. fill4.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  211. // Apply
  212. CellRangeAddress[] regions = {
  213. CellRangeAddress.valueOf("A1:F41")
  214. };
  215. sheetCF.addConditionalFormatting(regions, rule1);
  216. sheetCF.addConditionalFormatting(regions, rule2);
  217. sheetCF.addConditionalFormatting(regions, rule3);
  218. sheetCF.addConditionalFormatting(regions, rule4);
  219. }
  220. /**
  221. * Use Excel conditional formatting to check for errors,
  222. * and change the font colour to match the cell colour.
  223. * In this example, if formula result is #DIV/0! then it will have white font colour.
  224. */
  225. static void errors(Sheet sheet) {
  226. sheet.createRow(0).createCell(0).setCellValue(84);
  227. sheet.createRow(1).createCell(0).setCellValue(0);
  228. sheet.createRow(2).createCell(0).setCellFormula("ROUND(A1/A2,0)");
  229. sheet.createRow(3).createCell(0).setCellValue(0);
  230. sheet.createRow(4).createCell(0).setCellFormula("ROUND(A6/A4,0)");
  231. sheet.createRow(5).createCell(0).setCellValue(41);
  232. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  233. // Condition 1: Formula Is =ISERROR(C2) (White Font)
  234. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("ISERROR(A1)");
  235. FontFormatting font = rule1.createFontFormatting();
  236. font.setFontColorIndex(IndexedColors.WHITE.index);
  237. CellRangeAddress[] regions = {
  238. CellRangeAddress.valueOf("A1:A6")
  239. };
  240. sheetCF.addConditionalFormatting(regions, rule1);
  241. sheet.getRow(2).createCell(1).setCellValue("<== The error in this cell is hidden. Condition: Formula Is =ISERROR(C2) (White Font)");
  242. sheet.getRow(4).createCell(1).setCellValue("<== The error in this cell is hidden. Condition: Formula Is =ISERROR(C2) (White Font)");
  243. }
  244. /**
  245. * Use Excel conditional formatting to hide the duplicate values,
  246. * and make the list easier to read. In this example, when the table is sorted by Region,
  247. * the second (and subsequent) occurences of each region name will have white font colour.
  248. */
  249. static void hideDupplicates(Sheet sheet) {
  250. sheet.createRow(0).createCell(0).setCellValue("City");
  251. sheet.createRow(1).createCell(0).setCellValue("Boston");
  252. sheet.createRow(2).createCell(0).setCellValue("Boston");
  253. sheet.createRow(3).createCell(0).setCellValue("Chicago");
  254. sheet.createRow(4).createCell(0).setCellValue("Chicago");
  255. sheet.createRow(5).createCell(0).setCellValue("New York");
  256. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  257. // Condition 1: Formula Is =A2=A1 (White Font)
  258. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("A2=A1");
  259. FontFormatting font = rule1.createFontFormatting();
  260. font.setFontColorIndex(IndexedColors.WHITE.index);
  261. CellRangeAddress[] regions = {
  262. CellRangeAddress.valueOf("A2:A6")
  263. };
  264. sheetCF.addConditionalFormatting(regions, rule1);
  265. sheet.getRow(1).createCell(1).setCellValue("<== the second (and subsequent) " +
  266. "occurences of each region name will have white font colour. " +
  267. "Condition: Formula Is =A2=A1 (White Font)");
  268. }
  269. /**
  270. * Use Excel conditional formatting to highlight duplicate entries in a column.
  271. */
  272. static void formatDuplicates(Sheet sheet) {
  273. sheet.createRow(0).createCell(0).setCellValue("Code");
  274. sheet.createRow(1).createCell(0).setCellValue(4);
  275. sheet.createRow(2).createCell(0).setCellValue(3);
  276. sheet.createRow(3).createCell(0).setCellValue(6);
  277. sheet.createRow(4).createCell(0).setCellValue(3);
  278. sheet.createRow(5).createCell(0).setCellValue(5);
  279. sheet.createRow(6).createCell(0).setCellValue(8);
  280. sheet.createRow(7).createCell(0).setCellValue(0);
  281. sheet.createRow(8).createCell(0).setCellValue(2);
  282. sheet.createRow(9).createCell(0).setCellValue(8);
  283. sheet.createRow(10).createCell(0).setCellValue(6);
  284. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  285. // Condition 1: Formula Is =A2=A1 (White Font)
  286. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($A$2:$A$11,A2)>1");
  287. FontFormatting font = rule1.createFontFormatting();
  288. font.setFontStyle(false, true);
  289. font.setFontColorIndex(IndexedColors.BLUE.index);
  290. CellRangeAddress[] regions = {
  291. CellRangeAddress.valueOf("A2:A11")
  292. };
  293. sheetCF.addConditionalFormatting(regions, rule1);
  294. sheet.getRow(2).createCell(1).setCellValue("<== Duplicates numbers in the column are highlighted. " +
  295. "Condition: Formula Is =COUNTIF($A$2:$A$11,A2)>1 (Blue Font)");
  296. }
  297. /**
  298. * Use Excel conditional formatting to highlight items that are in a list on the worksheet.
  299. */
  300. static void inList(Sheet sheet) {
  301. sheet.createRow(0).createCell(0).setCellValue("Codes");
  302. sheet.createRow(1).createCell(0).setCellValue("AA");
  303. sheet.createRow(2).createCell(0).setCellValue("BB");
  304. sheet.createRow(3).createCell(0).setCellValue("GG");
  305. sheet.createRow(4).createCell(0).setCellValue("AA");
  306. sheet.createRow(5).createCell(0).setCellValue("FF");
  307. sheet.createRow(6).createCell(0).setCellValue("XX");
  308. sheet.createRow(7).createCell(0).setCellValue("CC");
  309. sheet.getRow(0).createCell(2).setCellValue("Valid");
  310. sheet.getRow(1).createCell(2).setCellValue("AA");
  311. sheet.getRow(2).createCell(2).setCellValue("BB");
  312. sheet.getRow(3).createCell(2).setCellValue("CC");
  313. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  314. // Condition 1: Formula Is =A2=A1 (White Font)
  315. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("COUNTIF($C$2:$C$4,A2)");
  316. PatternFormatting fill1 = rule1.createPatternFormatting();
  317. fill1.setFillBackgroundColor(IndexedColors.LIGHT_BLUE.index);
  318. fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  319. CellRangeAddress[] regions = {
  320. CellRangeAddress.valueOf("A2:A8")
  321. };
  322. sheetCF.addConditionalFormatting(regions, rule1);
  323. sheet.getRow(2).createCell(3).setCellValue("<== Use Excel conditional formatting to highlight items that are in a list on the worksheet");
  324. }
  325. /**
  326. * Use Excel conditional formatting to highlight payments that are due in the next thirty days.
  327. * In this example, Due dates are entered in cells A2:A4.
  328. */
  329. static void expiry(Sheet sheet) {
  330. CellStyle style = sheet.getWorkbook().createCellStyle();
  331. style.setDataFormat((short)BuiltinFormats.getBuiltinFormat("d-mmm"));
  332. sheet.createRow(0).createCell(0).setCellValue("Date");
  333. sheet.createRow(1).createCell(0).setCellFormula("TODAY()+29");
  334. sheet.createRow(2).createCell(0).setCellFormula("A2+1");
  335. sheet.createRow(3).createCell(0).setCellFormula("A3+1");
  336. for(int rownum = 1; rownum <= 3; rownum++) {
  337. sheet.getRow(rownum).getCell(0).setCellStyle(style);
  338. }
  339. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  340. // Condition 1: Formula Is =A2=A1 (White Font)
  341. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("AND(A2-TODAY()>=0,A2-TODAY()<=30)");
  342. FontFormatting font = rule1.createFontFormatting();
  343. font.setFontStyle(false, true);
  344. font.setFontColorIndex(IndexedColors.BLUE.index);
  345. CellRangeAddress[] regions = {
  346. CellRangeAddress.valueOf("A2:A4")
  347. };
  348. sheetCF.addConditionalFormatting(regions, rule1);
  349. sheet.getRow(0).createCell(1).setCellValue("Dates within the next 30 days are highlighted");
  350. }
  351. /**
  352. * Use Excel conditional formatting to shade alternating rows on the worksheet
  353. */
  354. static void shadeAlt(Sheet sheet) {
  355. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  356. // Condition 1: Formula Is =A2=A1 (White Font)
  357. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),2)");
  358. PatternFormatting fill1 = rule1.createPatternFormatting();
  359. fill1.setFillBackgroundColor(IndexedColors.LIGHT_GREEN.index);
  360. fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  361. CellRangeAddress[] regions = {
  362. CellRangeAddress.valueOf("A1:Z100")
  363. };
  364. sheetCF.addConditionalFormatting(regions, rule1);
  365. sheet.createRow(0).createCell(1).setCellValue("Shade Alternating Rows");
  366. sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is =MOD(ROW(),2) (Light Green Fill)");
  367. }
  368. /**
  369. * You can use Excel conditional formatting to shade bands of rows on the worksheet.
  370. * In this example, 3 rows are shaded light grey, and 3 are left with no shading.
  371. * In the MOD function, the total number of rows in the set of banded rows (6) is entered.
  372. */
  373. static void shadeBands(Sheet sheet) {
  374. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  375. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule("MOD(ROW(),6)<3");
  376. PatternFormatting fill1 = rule1.createPatternFormatting();
  377. fill1.setFillBackgroundColor(IndexedColors.GREY_25_PERCENT.index);
  378. fill1.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
  379. CellRangeAddress[] regions = {
  380. CellRangeAddress.valueOf("A1:Z100")
  381. };
  382. sheetCF.addConditionalFormatting(regions, rule1);
  383. sheet.createRow(0).createCell(1).setCellValue("Shade Bands of Rows");
  384. sheet.createRow(1).createCell(1).setCellValue("Condition: Formula Is =MOD(ROW(),6)<2 (Light Grey Fill)");
  385. }
  386. /**
  387. * Icon Sets / Multi-States allow you to have icons shown which vary
  388. * based on the values, eg Red traffic light / Yellow traffic light /
  389. * Green traffic light
  390. */
  391. static void iconSets(Sheet sheet) {
  392. sheet.createRow(0).createCell(0).setCellValue("Icon Sets");
  393. Row r = sheet.createRow(1);
  394. r.createCell(0).setCellValue("Reds");
  395. r.createCell(1).setCellValue(0);
  396. r.createCell(2).setCellValue(0);
  397. r.createCell(3).setCellValue(0);
  398. r = sheet.createRow(2);
  399. r.createCell(0).setCellValue("Yellows");
  400. r.createCell(1).setCellValue(5);
  401. r.createCell(2).setCellValue(5);
  402. r.createCell(3).setCellValue(5);
  403. r = sheet.createRow(3);
  404. r.createCell(0).setCellValue("Greens");
  405. r.createCell(1).setCellValue(10);
  406. r.createCell(2).setCellValue(10);
  407. r.createCell(3).setCellValue(10);
  408. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  409. CellRangeAddress[] regions = { CellRangeAddress.valueOf("B1:B4") };
  410. ConditionalFormattingRule rule1 =
  411. sheetCF.createConditionalFormattingRule(IconSet.GYR_3_TRAFFIC_LIGHTS);
  412. IconMultiStateFormatting im1 = rule1.getMultiStateFormatting();
  413. im1.getThresholds()[0].setRangeType(RangeType.MIN);
  414. im1.getThresholds()[1].setRangeType(RangeType.PERCENT);
  415. im1.getThresholds()[1].setValue(33d);
  416. im1.getThresholds()[2].setRangeType(RangeType.MAX);
  417. sheetCF.addConditionalFormatting(regions, rule1);
  418. regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C1:C4") };
  419. ConditionalFormattingRule rule2 =
  420. sheetCF.createConditionalFormattingRule(IconSet.GYR_3_FLAGS);
  421. IconMultiStateFormatting im2 = rule1.getMultiStateFormatting();
  422. im2.getThresholds()[0].setRangeType(RangeType.PERCENT);
  423. im2.getThresholds()[0].setValue(0d);
  424. im2.getThresholds()[1].setRangeType(RangeType.PERCENT);
  425. im2.getThresholds()[1].setValue(33d);
  426. im2.getThresholds()[2].setRangeType(RangeType.PERCENT);
  427. im2.getThresholds()[2].setValue(67d);
  428. sheetCF.addConditionalFormatting(regions, rule2);
  429. regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D1:D4") };
  430. ConditionalFormattingRule rule3 =
  431. sheetCF.createConditionalFormattingRule(IconSet.GYR_3_SYMBOLS_CIRCLE);
  432. IconMultiStateFormatting im3 = rule1.getMultiStateFormatting();
  433. im3.setIconOnly(true);
  434. im3.getThresholds()[0].setRangeType(RangeType.MIN);
  435. im3.getThresholds()[1].setRangeType(RangeType.NUMBER);
  436. im3.getThresholds()[1].setValue(3d);
  437. im3.getThresholds()[2].setRangeType(RangeType.NUMBER);
  438. im3.getThresholds()[2].setValue(7d);
  439. sheetCF.addConditionalFormatting(regions, rule3);
  440. }
  441. /**
  442. * Color Scales / Colour Scales / Colour Gradients allow you shade the
  443. * background colour of the cell based on the values, eg from Red to
  444. * Yellow to Green.
  445. */
  446. static void colourScales(Sheet sheet) {
  447. sheet.createRow(0).createCell(0).setCellValue("Colour Scales");
  448. Row r = sheet.createRow(1);
  449. r.createCell(0).setCellValue("Red-Yellow-Green");
  450. for (int i=1; i<=7; i++) {
  451. r.createCell(i).setCellValue((i-1)*5.0);
  452. }
  453. r = sheet.createRow(2);
  454. r.createCell(0).setCellValue("Red-White-Blue");
  455. for (int i=1; i<=9; i++) {
  456. r.createCell(i).setCellValue((i-1)*5.0);
  457. }
  458. r = sheet.createRow(3);
  459. r.createCell(0).setCellValue("Blue-Green");
  460. for (int i=1; i<=16; i++) {
  461. r.createCell(i).setCellValue((i-1));
  462. }
  463. sheet.setColumnWidth(0, 5000);
  464. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  465. CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:H2") };
  466. ConditionalFormattingRule rule1 =
  467. sheetCF.createConditionalFormattingColorScaleRule();
  468. ColorScaleFormatting cs1 = rule1.getColorScaleFormatting();
  469. cs1.getThresholds()[0].setRangeType(RangeType.MIN);
  470. cs1.getThresholds()[1].setRangeType(RangeType.PERCENTILE);
  471. cs1.getThresholds()[1].setValue(50d);
  472. cs1.getThresholds()[2].setRangeType(RangeType.MAX);
  473. ((ExtendedColor)cs1.getColors()[0]).setARGBHex("FFF8696B");
  474. ((ExtendedColor)cs1.getColors()[1]).setARGBHex("FFFFEB84");
  475. ((ExtendedColor)cs1.getColors()[2]).setARGBHex("FF63BE7B");
  476. sheetCF.addConditionalFormatting(regions, rule1);
  477. regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B3:J3") };
  478. ConditionalFormattingRule rule2 =
  479. sheetCF.createConditionalFormattingColorScaleRule();
  480. ColorScaleFormatting cs2 = rule2.getColorScaleFormatting();
  481. cs2.getThresholds()[0].setRangeType(RangeType.MIN);
  482. cs2.getThresholds()[1].setRangeType(RangeType.PERCENTILE);
  483. cs2.getThresholds()[1].setValue(50d);
  484. cs2.getThresholds()[2].setRangeType(RangeType.MAX);
  485. ((ExtendedColor)cs2.getColors()[0]).setARGBHex("FFF8696B");
  486. ((ExtendedColor)cs2.getColors()[1]).setARGBHex("FFFCFCFF");
  487. ((ExtendedColor)cs2.getColors()[2]).setARGBHex("FF5A8AC6");
  488. sheetCF.addConditionalFormatting(regions, rule2);
  489. regions = new CellRangeAddress[] { CellRangeAddress.valueOf("B4:Q4") };
  490. ConditionalFormattingRule rule3=
  491. sheetCF.createConditionalFormattingColorScaleRule();
  492. ColorScaleFormatting cs3 = rule3.getColorScaleFormatting();
  493. cs3.setNumControlPoints(2);
  494. cs3.getThresholds()[0].setRangeType(RangeType.MIN);
  495. cs3.getThresholds()[1].setRangeType(RangeType.MAX);
  496. ((ExtendedColor)cs3.getColors()[0]).setARGBHex("FF5A8AC6");
  497. ((ExtendedColor)cs3.getColors()[1]).setARGBHex("FF63BE7B");
  498. sheetCF.addConditionalFormatting(regions, rule3);
  499. }
  500. /**
  501. * DataBars / Data-Bars allow you to have bars shown vary
  502. * based on the values, from full to empty
  503. */
  504. static void dataBars(Sheet sheet) {
  505. sheet.createRow(0).createCell(0).setCellValue("Data Bars");
  506. Row r = sheet.createRow(1);
  507. r.createCell(1).setCellValue("Green Positive");
  508. r.createCell(2).setCellValue("Blue Mix");
  509. r.createCell(3).setCellValue("Red Negative");
  510. r = sheet.createRow(2);
  511. r.createCell(1).setCellValue(0);
  512. r.createCell(2).setCellValue(0);
  513. r.createCell(3).setCellValue(0);
  514. r = sheet.createRow(3);
  515. r.createCell(1).setCellValue(5);
  516. r.createCell(2).setCellValue(-5);
  517. r.createCell(3).setCellValue(-5);
  518. r = sheet.createRow(4);
  519. r.createCell(1).setCellValue(10);
  520. r.createCell(2).setCellValue(10);
  521. r.createCell(3).setCellValue(-10);
  522. r = sheet.createRow(5);
  523. r.createCell(1).setCellValue(5);
  524. r.createCell(2).setCellValue(5);
  525. r.createCell(3).setCellValue(-5);
  526. r = sheet.createRow(6);
  527. r.createCell(1).setCellValue(20);
  528. r.createCell(2).setCellValue(-10);
  529. r.createCell(3).setCellValue(-20);
  530. sheet.setColumnWidth(0, 3000);
  531. sheet.setColumnWidth(1, 5000);
  532. sheet.setColumnWidth(2, 5000);
  533. sheet.setColumnWidth(3, 5000);
  534. SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
  535. ExtendedColor color = sheet.getWorkbook().getCreationHelper().createExtendedColor();
  536. color.setARGBHex("FF63BE7B");
  537. CellRangeAddress[] regions = { CellRangeAddress.valueOf("B2:B7") };
  538. ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(color);
  539. DataBarFormatting db1 = rule1.getDataBarFormatting();
  540. db1.getMinThreshold().setRangeType(RangeType.MIN);
  541. db1.getMaxThreshold().setRangeType(RangeType.MAX);
  542. sheetCF.addConditionalFormatting(regions, rule1);
  543. color = sheet.getWorkbook().getCreationHelper().createExtendedColor();
  544. color.setARGBHex("FF5A8AC6");
  545. regions = new CellRangeAddress[] { CellRangeAddress.valueOf("C2:C7") };
  546. ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(color);
  547. DataBarFormatting db2 = rule2.getDataBarFormatting();
  548. db2.getMinThreshold().setRangeType(RangeType.MIN);
  549. db2.getMaxThreshold().setRangeType(RangeType.MAX);
  550. sheetCF.addConditionalFormatting(regions, rule2);
  551. color = sheet.getWorkbook().getCreationHelper().createExtendedColor();
  552. color.setARGBHex("FFF8696B");
  553. regions = new CellRangeAddress[] { CellRangeAddress.valueOf("D2:D7") };
  554. ConditionalFormattingRule rule3 = sheetCF.createConditionalFormattingRule(color);
  555. DataBarFormatting db3 = rule3.getDataBarFormatting();
  556. db3.getMinThreshold().setRangeType(RangeType.MIN);
  557. db3.getMaxThreshold().setRangeType(RangeType.MAX);
  558. sheetCF.addConditionalFormatting(regions, rule3);
  559. }
  560. /**
  561. * Print out a summary of the conditional formatting rules applied to cells on the given sheet.
  562. * Only cells with a matching rule are printed, and for those, all matching rules are sumarized.
  563. */
  564. static void evaluateRules(Workbook wb, String sheetName) {
  565. final WorkbookEvaluatorProvider wbEvalProv = (WorkbookEvaluatorProvider) wb.getCreationHelper().createFormulaEvaluator();
  566. final ConditionalFormattingEvaluator cfEval = new ConditionalFormattingEvaluator(wb, wbEvalProv);
  567. // if cell values have changed, clear cached format results
  568. cfEval.clearAllCachedValues();
  569. final Sheet sheet = wb.getSheet(sheetName);
  570. for (Row r : sheet) {
  571. for (Cell c : r) {
  572. final List<EvaluationConditionalFormatRule> rules = cfEval.getConditionalFormattingForCell(c);
  573. // check rules list for null, although current implementation will return an empty list, not null, then do what you want with results
  574. if (rules == null || rules.isEmpty()) {
  575. continue;
  576. }
  577. final CellReference ref = ConditionalFormattingEvaluator.getRef(c);
  578. if (rules.isEmpty()) {
  579. continue;
  580. }
  581. System.out.println("\n"
  582. + ref.formatAsString()
  583. + " has conditional formatting.");
  584. for (EvaluationConditionalFormatRule rule : rules) {
  585. ConditionalFormattingRule cf = rule.getRule();
  586. StringBuilder b = new StringBuilder();
  587. b.append("\tRule ")
  588. .append(rule.getFormattingIndex())
  589. .append(": ");
  590. // check for color scale
  591. if (cf.getColorScaleFormatting() != null) {
  592. b.append("\n\t\tcolor scale (caller must calculate bucket)");
  593. }
  594. // check for data bar
  595. if (cf.getDataBarFormatting() != null) {
  596. b.append("\n\t\tdata bar (caller must calculate bucket)");
  597. }
  598. // check for icon set
  599. if (cf.getMultiStateFormatting() != null) {
  600. b.append("\n\t\ticon set (caller must calculate icon bucket)");
  601. }
  602. // check for fill
  603. if (cf.getPatternFormatting() != null) {
  604. final PatternFormatting fill = cf.getPatternFormatting();
  605. b.append("\n\t\tfill pattern ")
  606. .append(fill.getFillPattern())
  607. .append(" color index ")
  608. .append(fill.getFillBackgroundColor());
  609. }
  610. // font stuff
  611. if (cf.getFontFormatting() != null) {
  612. final FontFormatting ff = cf.getFontFormatting();
  613. b.append("\n\t\tfont format ")
  614. .append("color index ")
  615. .append(ff.getFontColorIndex());
  616. if (ff.isBold()) {
  617. b.append(" bold");
  618. }
  619. if (ff.isItalic()) {
  620. b.append(" italic");
  621. }
  622. if (ff.isStruckout()) {
  623. b.append(" strikeout");
  624. }
  625. b.append(" underline index ")
  626. .append(ff.getUnderlineType());
  627. }
  628. System.out.println(b);
  629. }
  630. }
  631. }
  632. }
  633. }