PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/other/src/main/java/org/cran/rexcel/RCellBlock.java

http://rexcel.googlecode.com/
Java | 314 lines | 204 code | 21 blank | 89 comment | 59 complexity | b77afa9b12cf22935a01cba519e92f96 MD5 | raw file
  1. package org.cran.rexcel;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import org.apache.poi.ss.usermodel.Cell;
  5. import org.apache.poi.ss.usermodel.CellStyle;
  6. import org.apache.poi.ss.usermodel.Font;
  7. import org.apache.poi.ss.usermodel.Row;
  8. import org.apache.poi.ss.usermodel.Sheet;
  9. import org.apache.poi.ss.usermodel.Workbook;
  10. import org.apache.poi.xssf.usermodel.XSSFCellStyle;
  11. import org.apache.poi.xssf.usermodel.XSSFColor;
  12. /**
  13. * A rectangular block of Excel sheet cells.
  14. * The object serves as a wrapper of Apache POI
  15. * providing a way to do bulk cell value assignments and cell style modifications.
  16. * It also provide cell block-relative indexing of its cells.
  17. *
  18. * @author Adrian A. Dragulescu
  19. * @author Alexey Stukalov
  20. */
  21. public class RCellBlock {
  22. private Cell[][] cells;
  23. /**
  24. * Constructs continuous cell block.
  25. *
  26. * @param sheet sheet of a cell block
  27. * @param startRowIndex starting row of a block in a sheet.
  28. * @param startColIndex starting column of a block in a sheet.
  29. * @param nRows numbers of rows in a block
  30. * @param nCols number of columns in a block
  31. * @param create if true, rows and cells are created as necessary, otherwise only the existing cells are used
  32. */
  33. public RCellBlock( Sheet sheet, int startRowIndex, int startColIndex, int nRows, int nCols, boolean create )
  34. {
  35. cells = new Cell[nCols][nRows];
  36. for (int i = 0; i < nRows; i++) {
  37. Row r = sheet.getRow(startRowIndex+i);
  38. if (r == null) { // row is already there
  39. if ( create ) r = sheet.createRow(startRowIndex+i);
  40. else throw new RuntimeException( "Row does " + (startRowIndex+i)
  41. + "not exist in the sheet" );
  42. }
  43. for (int j = 0; j < nCols; j++){
  44. cells[j][i] = create ? r.createCell(startColIndex+j)
  45. : r.getCell(startColIndex+j);
  46. }
  47. }
  48. }
  49. /**
  50. * Gets the cell at given position.
  51. * @param rowIndex 0-based row index relative to the block
  52. * @param colIndex 0-based column index relative to the block
  53. * @return Cell object
  54. */
  55. public Cell getCell( int rowIndex, int colIndex )
  56. {
  57. return cells[ colIndex ][ rowIndex ];
  58. }
  59. /**
  60. * Gets the sheet of the cells block.
  61. * @return
  62. */
  63. public Sheet getSheet()
  64. {
  65. return ( cells != null & cells.length > 1
  66. & cells[1] != null & cells[1].length > 1
  67. & cells[1][1] != null
  68. ? cells[1][1].getSheet() : null );
  69. }
  70. /**
  71. * Gets the workbook of the cells block.
  72. * @return
  73. */
  74. public Workbook getWorkbook()
  75. {
  76. final Sheet sheet = getSheet();
  77. return ( sheet != null ? sheet.getWorkbook() : null );
  78. }
  79. /**
  80. * Writes a column of data to the sheet.
  81. * Use for numerics, Dates, DateTimes...
  82. */
  83. public void setColData( int colIndex, int rowOffset, double[] data, boolean showNA, CellStyle style ){
  84. final Cell[] colCells = cells[colIndex];
  85. for (int i=0; i<data.length; i++) {
  86. if ( showNA || !RInterface.isNA(data[i])) {
  87. colCells[rowOffset+i].setCellValue(data[i]);
  88. } else {
  89. colCells[rowOffset+i].setCellType(Cell.CELL_TYPE_BLANK);
  90. }
  91. }
  92. if ( style != null ) setColCellStyle(style, colIndex, rowOffset, data.length);
  93. }
  94. /**
  95. * Writes a column of integer to the sheet.
  96. */
  97. public void setColData( int colIndex, int rowOffset, int[] data, boolean showNA, CellStyle style ){
  98. final Cell[] colCells = cells[colIndex];
  99. for (int i=0; i<data.length; i++) {
  100. if ( showNA || !RInterface.isNA(data[i])) {
  101. colCells[rowOffset+i].setCellValue(data[i]);
  102. } else {
  103. colCells[rowOffset+i].setCellType(Cell.CELL_TYPE_BLANK);
  104. }
  105. }
  106. if ( style != null ) setColCellStyle(style, colIndex, rowOffset, data.length);
  107. }
  108. /**
  109. * Writes a column of strings to the sheet.
  110. */
  111. public void setColData( int colIndex, int rowOffset, String[] data, boolean showNA, CellStyle style ){
  112. final Cell[] colCells = cells[colIndex];
  113. for (int i=0; i<data.length; i++) {
  114. if ( showNA || !RInterface.isNA(data[i])) {
  115. colCells[rowOffset+i].setCellValue(data[i]);
  116. } else {
  117. colCells[rowOffset+i].setCellType(Cell.CELL_TYPE_BLANK);
  118. }
  119. }
  120. if ( style != null ) setColCellStyle(style, colIndex, rowOffset, data.length);
  121. }
  122. /**
  123. * Writes a row of strings to the sheet.
  124. */
  125. public void setRowData( int rowIndex, int colOffset, String[] data, boolean showNA, CellStyle style ){
  126. for (int i=0; i<data.length; i++) {
  127. if ( showNA || !RInterface.isNA(data[i])) {
  128. cells[colOffset+i][rowIndex].setCellValue(data[i]);
  129. } else {
  130. cells[colOffset+i][rowIndex].setCellType(Cell.CELL_TYPE_BLANK);
  131. }
  132. }
  133. if ( style != null ) setRowCellStyle(style, rowIndex, colOffset, data.length);
  134. }
  135. /**
  136. * Set the style of cells in a column.
  137. */
  138. public void setColCellStyle( CellStyle style, int colIndex, int rowOffset, int length )
  139. {
  140. final Cell[] colCells = cells[colIndex];
  141. for (int i=0; i<length; i++) {
  142. colCells[rowOffset+i].setCellStyle( style );
  143. }
  144. }
  145. /**
  146. * Sets the style of cells in a row.
  147. */
  148. public void setRowCellStyle( CellStyle style, int rowIndex, int colOffset, int length )
  149. {
  150. for (int i=0; i<length; i++) {
  151. cells[colOffset+i][rowIndex].setCellStyle( style );
  152. }
  153. }
  154. /**
  155. * Set the style of cells in a sub-block.
  156. */
  157. public void setCellStyle( CellStyle style, int[] rowIndices, int[] colIndices )
  158. {
  159. for ( int colIx : colIndices ) {
  160. final Cell[] colCells = cells[colIx];
  161. for ( int rowIx : rowIndices ) {
  162. colCells[rowIx].setCellStyle( style );
  163. }
  164. }
  165. }
  166. /**
  167. * Sets the style of all cells in a block
  168. */
  169. public void setCellStyle( CellStyle style )
  170. {
  171. for (Cell[] colCells : cells) {
  172. for (Cell cell : colCells) {
  173. cell.setCellStyle(style);
  174. }
  175. }
  176. }
  177. /**
  178. * Interface for modifying cell styles.
  179. * @see modifyCellStyle()
  180. */
  181. protected interface CellStyleModifier {
  182. /**
  183. * Changes the given cell style
  184. * @param style style to modify
  185. */
  186. public void modify( CellStyle style );
  187. }
  188. /**
  189. * Modifies the existing cell styles of a sub-block of cells.
  190. *
  191. * @param rowIndices 0-based block-relative indices of rows of a sub-block
  192. * @param colIndices 0-based block-relative indices of columns of a sub-block
  193. * @param modifier cell styles modifier
  194. */
  195. protected void modifyCellStyle( int[] rowIndices, int[] colIndices, CellStyleModifier modifier )
  196. {
  197. Map<Short, CellStyle> styleMap = new HashMap<Short,CellStyle>();
  198. CellStyle defaultStyle = null;
  199. for ( int colIx : colIndices ) {
  200. final Cell[] colCells = cells[colIx];
  201. for ( int rowIx : rowIndices ) {
  202. Cell cell = colCells[rowIx];
  203. CellStyle style = cell.getCellStyle();
  204. if ( style == null ) {
  205. if ( defaultStyle == null ) {
  206. defaultStyle = getWorkbook().createCellStyle();
  207. modifier.modify( defaultStyle );
  208. }
  209. cell.setCellStyle(defaultStyle);
  210. }
  211. else {
  212. if ( styleMap.containsKey( style.getIndex() ) ) {
  213. cell.setCellStyle( styleMap.get( style.getIndex() ) );
  214. }
  215. else {
  216. CellStyle modStyle = getWorkbook().createCellStyle();
  217. modStyle.cloneStyleFrom( style );
  218. modifier.modify(modStyle);
  219. styleMap.put(style.getIndex(), modStyle);
  220. cell.setCellStyle( modStyle );
  221. }
  222. }
  223. }
  224. }
  225. }
  226. /**
  227. * Sets the fill style of a given sub-block of cells.
  228. * The other properties of cell styles are preserved.
  229. * @see modifyCellStyle()
  230. */
  231. public void setFill( final XSSFColor foreground, final XSSFColor background, final short pattern, int[] rowIndices, int[] colIndices )
  232. {
  233. modifyCellStyle(rowIndices, colIndices, new CellStyleModifier() {
  234. public void modify( CellStyle style ) {
  235. style.setFillPattern( pattern );
  236. if ( style instanceof XSSFCellStyle ) {
  237. XSSFCellStyle xssfStyle = (XSSFCellStyle)style;
  238. xssfStyle.setFillForegroundColor( foreground );
  239. xssfStyle.setFillBackgroundColor( background );
  240. }
  241. }
  242. } );
  243. }
  244. /**
  245. * Sets the font of a given sub-block of cells.
  246. * The other properties of cell styles are preserved.
  247. * @see modifyCellStyle()
  248. */
  249. public void setFont( final Font font, int[] rowIndices, int[] colIndices )
  250. {
  251. modifyCellStyle(rowIndices, colIndices, new CellStyleModifier() {
  252. public void modify( CellStyle style ) {
  253. style.setFont( font );
  254. }
  255. } );
  256. }
  257. /**
  258. * Sets the border style of a given sub-block of cells.
  259. * If provided border type if BORDER_NONE the corresponding border is not modified.
  260. * The other properties of cell styles are preserved.
  261. * @see modifyCellStyle()
  262. */
  263. public void putBorder( final short borderTop, final XSSFColor topBorderColor,
  264. final short borderBottom, final XSSFColor bottomBorderColor,
  265. final short borderLeft, final XSSFColor leftBorderColor,
  266. final short borderRight, final XSSFColor rightBorderColor,
  267. int[] rowIndices, int[] colIndices )
  268. {
  269. modifyCellStyle(rowIndices, colIndices, new CellStyleModifier() {
  270. public void modify( CellStyle style ) {
  271. if ( style instanceof XSSFCellStyle ) {
  272. XSSFCellStyle xssfStyle = (XSSFCellStyle)style;
  273. if ( borderTop != CellStyle.BORDER_NONE ) {
  274. xssfStyle.setBorderTop( borderTop );
  275. xssfStyle.setTopBorderColor( topBorderColor );
  276. }
  277. if ( borderBottom != CellStyle.BORDER_NONE ) {
  278. xssfStyle.setBorderBottom( borderBottom );
  279. xssfStyle.setBottomBorderColor( bottomBorderColor );
  280. }
  281. if ( borderLeft != CellStyle.BORDER_NONE ) {
  282. xssfStyle.setBorderLeft( borderLeft );
  283. xssfStyle.setLeftBorderColor( leftBorderColor );
  284. }
  285. if ( borderRight != CellStyle.BORDER_NONE ) {
  286. xssfStyle.setBorderRight( borderRight );
  287. xssfStyle.setRightBorderColor( rightBorderColor );
  288. }
  289. }
  290. }
  291. } );
  292. }
  293. }