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.

InCellLists.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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.examples.hssf.usermodel;
  16. import java.io.File;
  17. import java.io.FileOutputStream;
  18. import java.io.IOException;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. import org.apache.poi.hssf.usermodel.HSSFCell;
  22. import org.apache.poi.hssf.usermodel.HSSFCellStyle;
  23. import org.apache.poi.hssf.usermodel.HSSFDataFormat;
  24. import org.apache.poi.hssf.usermodel.HSSFRichTextString;
  25. import org.apache.poi.hssf.usermodel.HSSFRow;
  26. import org.apache.poi.hssf.usermodel.HSSFSheet;
  27. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  28. /**
  29. * This class contains code that demonstrates how to insert plain, numbered
  30. * and bulleted lists into an Excel spreadsheet cell.
  31. *
  32. * Look at the code contained in the demonstrateMethodCalls() method. It calls
  33. * other methods that create plain, numbered and bulleted single and
  34. * multi-level lists. The demonstrateMethodCalls() method appears at the top
  35. * of the class definition.
  36. *
  37. * Though different methods are provided to construct single and multi-level
  38. * plain, numbered and bulleted lists, close examination will reveal that they
  39. * are not strictly necessary. If the inputs to the listInCell() and
  40. * multilLevelListInCell() methods are constructed to include the bullet
  41. * character or the item numbers then these methods alone may be sufficient.
  42. *
  43. * @author Mark Beardsley [msb at apache.org]
  44. */
  45. @SuppressWarnings({"java:S106","java:S4823"})
  46. public class InCellLists {
  47. // This character looks like a solid, black, loser case letter 'o'
  48. // positioned up from the base line of the text.
  49. private static final char BULLET_CHARACTER = '\u2022';
  50. // The tab character - \t - cannot be used to create a tab space
  51. // within a cell as it is rendered as a square. Therefore, four
  52. // spaces are used to simulate that character.
  53. private static final String TAB = " ";
  54. /**
  55. * Call each of the list creation methods.
  56. *
  57. * @param outputFilename A String that encapsulates the name of and path to
  58. * the Excel spreadsheet file this code will create.
  59. */
  60. public void demonstrateMethodCalls(String outputFilename) throws IOException {
  61. try (HSSFWorkbook workbook = new HSSFWorkbook()) {
  62. HSSFSheet sheet = workbook.createSheet("In Cell Lists");
  63. HSSFRow row = sheet.createRow(0);
  64. // Create a cell at A1 and insert a single, bulleted, item into
  65. // that cell.
  66. HSSFCell cell = row.createCell(0);
  67. this.bulletedItemInCell(workbook, "List Item", cell);
  68. // Create a cell at A2 and insert a plain list - that is one
  69. // whose items are neither bulleted or numbered - into that cell.
  70. row = sheet.createRow(1);
  71. cell = row.createCell(0);
  72. List<String> listItems = new ArrayList<>();
  73. listItems.add("List Item One.");
  74. listItems.add("List Item Two.");
  75. listItems.add("List Item Three.");
  76. listItems.add("List Item Four.");
  77. this.listInCell(workbook, listItems, cell);
  78. // The row height and cell width are set here to ensure that the
  79. // list may be seen.
  80. row.setHeight((short) 1100);
  81. sheet.setColumnWidth(0, 9500);
  82. // Create a cell at A3 and insert a numbered list into that cell.
  83. // Note that a couple of items have been added to the listItems
  84. // ArrayList
  85. row = sheet.createRow(2);
  86. cell = row.createCell(0);
  87. listItems.add("List Item Five.");
  88. listItems.add("List Item Six.");
  89. this.numberedListInCell(workbook, listItems, cell, 1, 2);
  90. row.setHeight((short) 1550);
  91. // Create a cell at A4 and insert a numbered list into that cell.
  92. // Note that a couple of items have been added to the listItems
  93. // ArrayList
  94. row = sheet.createRow(3);
  95. cell = row.createCell(0);
  96. listItems.add("List Item Seven.");
  97. listItems.add("List Item Eight.");
  98. listItems.add("List Item Nine.");
  99. listItems.add("List Item Ten.");
  100. this.bulletedListInCell(workbook, listItems, cell);
  101. row.setHeight((short) 2550);
  102. // Insert a plain, multi-level list into cell A5. Note that
  103. // the major difference here is that the list items are passed as
  104. // an ArrayList of MultiLevelListItems. Note that an ArrayList
  105. // of instances of an inner class was used here in preference to
  106. // a Hashtable or HashMap as the ArrayList will preserve the
  107. // ordering of the items added to it; the first item added will
  108. // be the first item recovered and the last item added, the last
  109. // item recovered. Alternatively, a LinkedHashMap could be used
  110. // to preserve order.
  111. row = sheet.createRow(4);
  112. cell = row.createCell(0);
  113. List<MultiLevelListItem> multiLevelListItems = new ArrayList<>();
  114. listItems = new ArrayList<>();
  115. listItems.add("ML List Item One - Sub Item One.");
  116. listItems.add("ML List Item One - Sub Item Two.");
  117. listItems.add("ML List Item One - Sub Item Three.");
  118. listItems.add("ML List Item One - Sub Item Four.");
  119. multiLevelListItems.add(new MultiLevelListItem("List Item One.", listItems));
  120. // Passing either null or an empty ArrayList will signal that
  121. // there are no lower level items associated with the top level
  122. // item
  123. multiLevelListItems.add(new MultiLevelListItem("List Item Two.", null));
  124. multiLevelListItems.add(new MultiLevelListItem("List Item Three.", null));
  125. listItems = new ArrayList<>();
  126. listItems.add("ML List Item Four - Sub Item One.");
  127. listItems.add("ML List Item Four - Sub Item Two.");
  128. listItems.add("ML List Item Four - Sub Item Three.");
  129. multiLevelListItems.add(new MultiLevelListItem("List Item Four.", listItems));
  130. this.multiLevelListInCell(workbook, multiLevelListItems, cell);
  131. row.setHeight((short) 2800);
  132. // Insert a numbered multi-level list into cell A6. Note that the
  133. // same ArrayList as constructed for the above plain multi-level
  134. // list example will be re-used
  135. row = sheet.createRow(5);
  136. cell = row.createCell(0);
  137. this.multiLevelNumberedListInCell(workbook, multiLevelListItems,
  138. cell, 1, 1, 1, 2);
  139. row.setHeight((short) 2800);
  140. // Insert a numbered multi-level list into cell A7. Note that the
  141. // same ArrayList as constructed for the plain multi-level list
  142. // example will be re-used
  143. row = sheet.createRow(6);
  144. cell = row.createCell(0);
  145. this.multiLevelBulletedListInCell(workbook, multiLevelListItems, cell);
  146. row.setHeight((short) 2800);
  147. // Save the completed workbook
  148. try (FileOutputStream fos = new FileOutputStream(new File(outputFilename))) {
  149. workbook.write(fos);
  150. }
  151. } catch (IOException ioEx) {
  152. System.out.println("Caught a: " + ioEx.getClass().getName());
  153. System.out.println("Message: " + ioEx.getMessage());
  154. System.out.println("Stacktrace follows...........");
  155. ioEx.printStackTrace(System.out);
  156. }
  157. }
  158. /**
  159. * Inserts a single bulleted item into a cell.
  160. *
  161. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  162. * cell.
  163. * @param listItem An instance of the String class encapsulating the
  164. * items text.
  165. * @param cell An instance of the HSSFCell class that encapsulates a
  166. * reference to the spreadsheet cell into which the list item
  167. * will be written.
  168. */
  169. public void bulletedItemInCell(HSSFWorkbook workbook, String listItem, HSSFCell cell) {
  170. // A format String must be built to ensure that the contents of the
  171. // cell appear as a bulleted item.
  172. HSSFDataFormat format = workbook.createDataFormat();
  173. String formatString = InCellLists.BULLET_CHARACTER + " @";
  174. int formatIndex = format.getFormat(formatString);
  175. // Construct an HSSFCellStyle and set it's data formt to use the
  176. // object created above.
  177. HSSFCellStyle bulletStyle = workbook.createCellStyle();
  178. bulletStyle.setDataFormat((short)formatIndex);
  179. // Set the cells contents and style.
  180. cell.setCellValue(new HSSFRichTextString(listItem));
  181. cell.setCellStyle(bulletStyle);
  182. }
  183. /**
  184. * Inserts a list of plain items - that is items that are neither
  185. * numbered or bulleted - into a single cell.
  186. *
  187. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  188. * cell.
  189. * @param listItems An ArrayList whose elements encapsulate the text for
  190. * the list's items.
  191. * @param cell An instance of the HSSFCell class that encapsulates a
  192. * reference to the spreadsheet cell into which the list
  193. * will be written.
  194. */
  195. public void listInCell(HSSFWorkbook workbook, List<String> listItems, HSSFCell cell) {
  196. StringBuilder buffer = new StringBuilder();
  197. HSSFCellStyle wrapStyle = workbook.createCellStyle();
  198. wrapStyle.setWrapText(true);
  199. for(String listItem : listItems) {
  200. buffer.append(listItem);
  201. buffer.append("\n");
  202. }
  203. // The StringBuilder's contents are the source for the contents
  204. // of the cell.
  205. cell.setCellValue(new HSSFRichTextString(buffer.toString().trim()));
  206. cell.setCellStyle(wrapStyle);
  207. }
  208. /**
  209. * Inserts a numbered list into a single cell.
  210. *
  211. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  212. * cell.
  213. * @param listItems An ArrayList whose elements encapsulate the text for
  214. * the lists items.
  215. * @param cell An instance of the HSSFCell class that encapsulates a
  216. * reference to the spreadsheet cell into which the list
  217. * will be written.
  218. * @param startingValue A primitive int containing the number for the first
  219. * item in the list.
  220. * @param increment A primitive int containing the value that should be used
  221. * to calculate subsequent item numbers.
  222. */
  223. public void numberedListInCell(HSSFWorkbook workbook,
  224. List<String> listItems,
  225. HSSFCell cell,
  226. int startingValue,
  227. int increment) {
  228. StringBuilder buffer = new StringBuilder();
  229. int itemNumber = startingValue;
  230. // Note that again, an HSSFCellStye object is required and that
  231. // it's wrap text property should be set to 'true'
  232. HSSFCellStyle wrapStyle = workbook.createCellStyle();
  233. wrapStyle.setWrapText(true);
  234. // Note that the basic method is identical to the listInCell() method
  235. // with one difference; a number prefixed to the items text.
  236. for(String listItem : listItems) {
  237. buffer.append(itemNumber).append(". ");
  238. buffer.append(listItem);
  239. buffer.append("\n");
  240. itemNumber += increment;
  241. }
  242. // The StringBuilder's contents are the source for the contents
  243. // of the cell.
  244. cell.setCellValue(new HSSFRichTextString(buffer.toString().trim()));
  245. cell.setCellStyle(wrapStyle);
  246. }
  247. /**
  248. * Insert a bulleted list into a cell.
  249. *
  250. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  251. * cell.
  252. * @param listItems An ArrayList whose elements encapsulate the text for
  253. * the lists items.
  254. * @param cell An instance of the HSSFCell class that encapsulates a
  255. * reference to the spreadsheet cell into which the list
  256. * will be written.
  257. */
  258. public void bulletedListInCell(HSSFWorkbook workbook,
  259. List<String> listItems,
  260. HSSFCell cell) {
  261. StringBuilder buffer = new StringBuilder();
  262. // Note that again, an HSSFCellStye object is required and that
  263. // it's wrap text property should be set to 'true'
  264. HSSFCellStyle wrapStyle = workbook.createCellStyle();
  265. wrapStyle.setWrapText(true);
  266. // Note that the basic method is identical to the listInCell() method
  267. // with one difference; the bullet character prefixed to the items text.
  268. for(String listItem : listItems) {
  269. buffer.append(InCellLists.BULLET_CHARACTER + " ");
  270. buffer.append(listItem);
  271. buffer.append("\n");
  272. }
  273. // The StringBuilder's contents are the source for the contents
  274. // of the cell.
  275. cell.setCellValue(new HSSFRichTextString(buffer.toString().trim()));
  276. cell.setCellStyle(wrapStyle);
  277. }
  278. /**
  279. * Insert a multi-level list into a cell.
  280. *
  281. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  282. * cell.
  283. * @param multiLevelListItems An ArrayList whose elements contain instances
  284. * of the MultiLevelListItem class. Each element
  285. * encapsulates the text for the high level item
  286. * along with an ArrayList. Each element of this
  287. * ArrayList encapsulates the text for a lower
  288. * level item.
  289. * @param cell An instance of the HSSFCell class that encapsulates a
  290. * reference to the spreadsheet cell into which the list
  291. * will be written.
  292. */
  293. public void multiLevelListInCell(HSSFWorkbook workbook,
  294. List<MultiLevelListItem> multiLevelListItems,
  295. HSSFCell cell) {
  296. StringBuilder buffer = new StringBuilder();
  297. // Note that again, an HSSFCellStye object is required and that
  298. // it's wrap text property should be set to 'true'
  299. HSSFCellStyle wrapStyle = workbook.createCellStyle();
  300. wrapStyle.setWrapText(true);
  301. // Step through the ArrayList of MultilLevelListItem instances.
  302. for(MultiLevelListItem multiLevelListItem : multiLevelListItems) {
  303. // For each element in the ArrayList, get the text for the high
  304. // level list item......
  305. buffer.append(multiLevelListItem.getItemText());
  306. buffer.append("\n");
  307. // and then an ArrayList whose elements encapsulate the text
  308. // for the lower level list items.
  309. List<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems();
  310. if (lowerLevelItems == null || lowerLevelItems.isEmpty()) {
  311. continue;
  312. }
  313. for(String item : lowerLevelItems) {
  314. buffer.append(InCellLists.TAB);
  315. buffer.append(item);
  316. buffer.append("\n");
  317. }
  318. }
  319. // The StringBuilder's contents are the source for the contents
  320. // of the cell.
  321. cell.setCellValue(new HSSFRichTextString(buffer.toString().trim()));
  322. cell.setCellStyle(wrapStyle);
  323. }
  324. /**
  325. * Insert a multi-level list into a cell.
  326. *
  327. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  328. * cell.
  329. * @param multiLevelListItems An ArrayList whose elements contain instances
  330. * of the MultiLevelListItem class. Each element
  331. * encapsulates the text for the high level item
  332. * along with an ArrayList. Each element of this
  333. * ArrayList encapsulates the text for a lower
  334. * level item.
  335. * @param cell An instance of the HSSFCell class that encapsulates a
  336. * reference to the spreadsheet cell into which the list
  337. * will be written.
  338. * @param highLevelStartingValue A primitive int containing the number
  339. * for the first high level item in the list.
  340. * @param highLevelIncrement A primitive int containing the value that
  341. * should be used to calculate the number of
  342. * subsequent high level item.
  343. * @param lowLevelStartingValue A primitive int will containing the number
  344. * for the first low level item associated
  345. * with a high level item.
  346. * @param lowLevelIncrement A primitive int containing the value that
  347. * should be used to calculate the number of
  348. * subsequent low level item.
  349. */
  350. public void multiLevelNumberedListInCell(HSSFWorkbook workbook,
  351. List<MultiLevelListItem> multiLevelListItems,
  352. HSSFCell cell,
  353. int highLevelStartingValue,
  354. int highLevelIncrement,
  355. int lowLevelStartingValue,
  356. int lowLevelIncrement) {
  357. StringBuilder buffer = new StringBuilder();
  358. int highLevelItemNumber = highLevelStartingValue;
  359. // Note that again, an HSSFCellStye object is required and that
  360. // it's wrap text property should be set to 'true'
  361. HSSFCellStyle wrapStyle = workbook.createCellStyle();
  362. wrapStyle.setWrapText(true);
  363. // Step through the ArrayList of MultilLevelListItem instances.
  364. for(MultiLevelListItem multiLevelListItem : multiLevelListItems) {
  365. // For each element in the ArrayList, get the text for the high
  366. // level list item......
  367. buffer.append(highLevelItemNumber);
  368. buffer.append(". ");
  369. buffer.append(multiLevelListItem.getItemText());
  370. buffer.append("\n");
  371. // and then an ArrayList whose elements encapsulate the text
  372. // for the lower level list items.
  373. List<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems();
  374. if(lowerLevelItems != null && !lowerLevelItems.isEmpty()) {
  375. int lowLevelItemNumber = lowLevelStartingValue;
  376. for(String item : lowerLevelItems) {
  377. buffer.append(InCellLists.TAB);
  378. buffer.append(highLevelItemNumber);
  379. buffer.append(".");
  380. buffer.append(lowLevelItemNumber);
  381. buffer.append(" ");
  382. buffer.append(item);
  383. buffer.append("\n");
  384. lowLevelItemNumber += lowLevelIncrement;
  385. }
  386. }
  387. highLevelItemNumber += highLevelIncrement;
  388. }
  389. // The StringBuilder's contents are the source for the contents
  390. // of the cell.
  391. cell.setCellValue(new HSSFRichTextString(buffer.toString().trim()));
  392. cell.setCellStyle(wrapStyle);
  393. }
  394. /**
  395. * Insert a bulleted multi-level list into a cell.
  396. *
  397. * @param workbook A reference to the HSSFWorkbook that 'contains' the
  398. * cell.
  399. * @param multiLevelListItems An ArrayList whose elements contain instances
  400. * of the MultiLevelListItem class. Each element
  401. * encapsulates the text for the high level item
  402. * along with an ArrayList. Each element of this
  403. * ArrayList encapsulates the text for a lower
  404. * level item.
  405. * @param cell An instance of the HSSFCell class that encapsulates a
  406. * reference to the spreadsheet cell into which the list
  407. * will be written.
  408. */
  409. public void multiLevelBulletedListInCell(HSSFWorkbook workbook,
  410. List<MultiLevelListItem> multiLevelListItems,
  411. HSSFCell cell) {
  412. StringBuilder buffer = new StringBuilder();
  413. // Note that again, an HSSFCellStye object is required and that
  414. // it's wrap text property should be set to 'true'
  415. HSSFCellStyle wrapStyle = workbook.createCellStyle();
  416. wrapStyle.setWrapText(true);
  417. // Step through the ArrayList of MultilLevelListItem instances.
  418. for(MultiLevelListItem multiLevelListItem : multiLevelListItems) {
  419. // For each element in the ArrayList, get the text for the high
  420. // level list item......
  421. buffer.append(InCellLists.BULLET_CHARACTER);
  422. buffer.append(" ");
  423. buffer.append(multiLevelListItem.getItemText());
  424. buffer.append("\n");
  425. // and then an ArrayList whose elements encapsulate the text
  426. // for the lower level list items.
  427. List<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems();
  428. if(lowerLevelItems != null && !lowerLevelItems.isEmpty()) {
  429. for(String item : lowerLevelItems) {
  430. buffer.append(InCellLists.TAB);
  431. buffer.append(InCellLists.BULLET_CHARACTER);
  432. buffer.append(" ");
  433. buffer.append(item);
  434. buffer.append("\n");
  435. }
  436. }
  437. }
  438. // The StringBuilder's contents are the source for the contents
  439. // of the cell.
  440. cell.setCellValue(new HSSFRichTextString(buffer.toString().trim()));
  441. cell.setCellStyle(wrapStyle);
  442. }
  443. /**
  444. * The main entry point to the program. Demonstrates how to call the method
  445. * that will create an Excel workbook containing many different sorts of
  446. * lists.
  447. *
  448. * @param args the command line arguments.
  449. */
  450. public static void main(String[] args) throws IOException {
  451. new InCellLists().demonstrateMethodCalls("Latest In Cell List.xls");
  452. }
  453. /**
  454. * An instance of this inner class models an item or element in a
  455. * multi-level list. Each multi-level list item consists of the text for the
  456. * high level items and an ArrayList containing the text for each of the
  457. * associated lower level items. When written into a cell, each multi-level
  458. * list item will have this general appearance.
  459. *
  460. * Item One
  461. * Sub Item One.
  462. * Sub Item Two.
  463. * Item Two
  464. * Sub Item One.
  465. * Sub Item Two.
  466. * etc.
  467. *
  468. * It would be quite possible to modify this class to model much more
  469. * complex list structures descending through two, three or even more
  470. * levels.
  471. */
  472. public final class MultiLevelListItem {
  473. private String itemText;
  474. private List<String> lowerLevelItems;
  475. /**
  476. * Create a new instance of the MultiLevelListItem class using the
  477. * following parameters.
  478. *
  479. * @param itemText A String that encapsulates the text for the high
  480. * level list item.
  481. * @param lowerLevelItems An ArrayList whose elements encapsulate the
  482. * text for the associated lower level list
  483. * items.
  484. */
  485. public MultiLevelListItem(String itemText, List<String> lowerLevelItems) {
  486. this.itemText = itemText;
  487. this.lowerLevelItems = lowerLevelItems;
  488. }
  489. /**
  490. * Get the text for the high level list item.
  491. *
  492. * @return A String that encapsulates the text for the high level list
  493. * item.
  494. */
  495. public String getItemText() {
  496. return(this.itemText);
  497. }
  498. /**
  499. * Get the text for the associated lower level list items.
  500. *
  501. * @return An ArrayList whose elements each encapsulate the text for a
  502. * single associated lower level list item.
  503. */
  504. public List<String> getLowerLevelItems() {
  505. return lowerLevelItems;
  506. }
  507. }
  508. }