PageRenderTime 81ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/jandcode-excelreport/src/jandcode/excelreport/impl/ReportSheetImpl.java

https://bitbucket.org/gkraser/jandcode-core
Java | 310 lines | 255 code | 35 blank | 20 comment | 58 complexity | bffa29002523454ad6f3fb8b69f7e98a MD5 | raw file
  1. package jandcode.excelreport.impl;
  2. import jandcode.utils.*;
  3. import jandcode.utils.error.*;
  4. import jandcode.excelreport.*;
  5. import jandcode.excelreport.impl.databinder.*;
  6. import org.apache.poi.hssf.usermodel.*;
  7. import org.apache.poi.ss.formula.*;
  8. import org.apache.poi.ss.usermodel.*;
  9. import org.apache.poi.ss.util.*;
  10. import org.joda.time.*;
  11. import java.util.*;
  12. public class ReportSheetImpl extends ReportSheet {
  13. protected HSSFSheet shTemplate;
  14. protected HSSFSheet shResult;
  15. protected int shResultIdx;
  16. protected HSSFWorkbook wbResult;
  17. protected HSSFWorkbook wbTemplate;
  18. // текущие позиции для вывода
  19. protected int curR;
  20. protected int curC;
  21. protected ListNamed<BandInfo> bands;
  22. protected int maxCol;
  23. protected SubstVars substVars = new SubstVars();
  24. // стили в формате [стиль-шаблона]->стиль-результата
  25. protected Map<CellStyle, StyleInfo> cellStyles;
  26. class SubstVars implements ISubstVar {
  27. Object data;
  28. DataBinder dataBinder = new DataBinderDelegate();
  29. void setData(Object data) {
  30. this.data = data;
  31. }
  32. public String onSubstVar(String v) {
  33. try {
  34. if (UtString.empty(v)) {
  35. return "";
  36. }
  37. int a = v.indexOf(':');
  38. if (a == -1) {
  39. return dataBinder.getVarValue(data, v, "");
  40. } else {
  41. return dataBinder.getVarValue(data, v.substring(0, a), v.substring(a + 1));
  42. }
  43. } catch (Exception e) {
  44. return "";
  45. }
  46. }
  47. }
  48. class BandInfo extends Named {
  49. int c1, c2, r1, r2;
  50. boolean wholeCols; // все колонки
  51. List<Cell> cells = new ArrayList<Cell>();
  52. List<Row> rows = new ArrayList<Row>();
  53. public List<CellRangeAddress> merges = new ArrayList<CellRangeAddress>();
  54. }
  55. class StyleInfo {
  56. CellStyle tmlStyle;
  57. CellStyle resStyle;
  58. boolean isDate;
  59. boolean isNumber;
  60. }
  61. public ReportSheetImpl(HSSFSheet shTemplate, HSSFSheet shResult) {
  62. this.shTemplate = shTemplate;
  63. this.shResult = shResult;
  64. this.wbTemplate = this.shTemplate.getWorkbook();
  65. this.wbResult = this.shResult.getWorkbook();
  66. this.shResultIdx = this.wbResult.getSheetIndex(this.shResult);
  67. //
  68. parseSheet();
  69. }
  70. protected void parseSheet() {
  71. shResult.setDefaultColumnWidth(shTemplate.getDefaultColumnWidth());
  72. shResult.setDefaultRowHeight(shTemplate.getDefaultRowHeight());
  73. //
  74. ArrayList<Cell> cells = new ArrayList<Cell>();
  75. // all cells
  76. for (Row row : shTemplate) {
  77. for (Cell cell : row) {
  78. cells.add(cell);
  79. maxCol = Math.max(maxCol, cell.getColumnIndex());
  80. }
  81. }
  82. //
  83. bands = new ListNamed<BandInfo>();
  84. int numNames = shTemplate.getWorkbook().getNumberOfNames();
  85. for (int i = 0; i < numNames; i++) {
  86. HSSFName nm = shTemplate.getWorkbook().getNameAt(i);
  87. AreaReference aref = new AreaReference(nm.getRefersToFormula());
  88. BandInfo band = new BandInfo();
  89. band.setName(nm.getNameName());
  90. band.c1 = aref.getFirstCell().getCol();
  91. band.c2 = aref.getLastCell().getCol();
  92. band.r1 = aref.getFirstCell().getRow();
  93. band.r2 = aref.getLastCell().getRow();
  94. band.wholeCols = aref.isWholeColumnReference();
  95. //
  96. for (int j = band.r1; j <= band.r2; j++) {
  97. band.rows.add(shTemplate.getRow(j));
  98. }
  99. // cells for band
  100. for (Cell cell : cells) {
  101. int ri = cell.getRowIndex();
  102. int ci = cell.getColumnIndex();
  103. if (ri >= band.r1 && ri <= band.r2 && ci >= band.c1 && ci <= band.c2) {
  104. band.cells.add(cell);
  105. }
  106. }
  107. // merges for band
  108. int mergCnt = shTemplate.getNumMergedRegions();
  109. for (int k = 0; k < mergCnt; k++) {
  110. CellRangeAddress mr = shTemplate.getMergedRegion(k);
  111. int ri = mr.getFirstRow();
  112. int ci = mr.getFirstColumn();
  113. if (ri >= band.r1 && ri <= band.r2 && ci >= band.c1 && ci <= band.c2) {
  114. band.merges.add(mr);
  115. }
  116. }
  117. //
  118. bands.add(band);
  119. }
  120. // стили
  121. cellStyles = new HashMap<CellStyle, StyleInfo>();
  122. for (short i = 0; i < wbTemplate.getNumCellStyles(); i++) {
  123. HSSFCellStyle tmlStyle = wbTemplate.getCellStyleAt(i);
  124. HSSFCellStyle resStyle = wbResult.createCellStyle();
  125. resStyle.cloneStyleFrom(tmlStyle);
  126. StyleInfo styleInfo = new StyleInfo();
  127. styleInfo.tmlStyle = tmlStyle;
  128. styleInfo.resStyle = resStyle;
  129. styleInfo.isDate = isStyleDate(resStyle);
  130. styleInfo.isNumber = isStyleNumber(resStyle);
  131. cellStyles.put(tmlStyle, styleInfo);
  132. }
  133. // columns widths & styles
  134. for (int i = 0; i <= maxCol; i++) {
  135. HSSFCellStyle st = shTemplate.getColumnStyle(i);
  136. if (st != null) {
  137. shResult.setDefaultColumnStyle(i, getResultCellStyle(st).resStyle);
  138. }
  139. shResult.setColumnWidth(i, shTemplate.getColumnWidth(i));
  140. if (shTemplate.isColumnHidden(i)) {
  141. shResult.setColumnHidden(i, true);
  142. }
  143. }
  144. }
  145. public void setSheetTitle(String title) {
  146. shResult.getWorkbook().setSheetName(shResultIdx, title);
  147. }
  148. public boolean hasBand(String nameBand) {
  149. return bands.find(nameBand) != null;
  150. }
  151. public void out(String nameBand, Object data) {
  152. substVars.setData(data);
  153. //
  154. BandInfo band = bands.get(nameBand);
  155. int baseRow = curR;
  156. for (Row row : band.rows) {
  157. if (row == null) {
  158. Row emptyRow = shResult.createRow(curR);
  159. Cell emptyCell = emptyRow.createCell(0);
  160. emptyRow.setHeight(shTemplate.getDefaultRowHeight());
  161. curR++; // тут не заполненная строка
  162. continue;
  163. }
  164. Row newRow = shResult.createRow(curR);
  165. newRow.setHeight(row.getHeight());
  166. //
  167. curR++;
  168. for (Cell cell : band.cells) {
  169. if (cell.getRowIndex() == row.getRowNum()) {
  170. Cell newCell = newRow.createCell(cell.getColumnIndex());
  171. copyCell(cell, newCell);
  172. }
  173. }
  174. }
  175. // merges
  176. if (!band.merges.isEmpty()) {
  177. for (CellRangeAddress mr : band.merges) {
  178. CellRangeAddress mrNew = new CellRangeAddress(
  179. mr.getFirstRow() + baseRow,
  180. mr.getLastRow() + baseRow,
  181. mr.getFirstColumn(),
  182. mr.getLastColumn()
  183. );
  184. shResult.addMergedRegion(mrNew);
  185. }
  186. }
  187. }
  188. protected void copyCell(Cell oldCell, Cell newCell) {
  189. // Copy style from old cell and apply to new cell
  190. StyleInfo styleInfo = getResultCellStyle(oldCell.getCellStyle());
  191. newCell.setCellStyle(styleInfo.resStyle);
  192. // If there is a cell comment, copy
  193. if (newCell.getCellComment() != null) {
  194. newCell.setCellComment(oldCell.getCellComment());
  195. }
  196. // If there is a cell hyperlink, copy
  197. if (oldCell.getHyperlink() != null) {
  198. newCell.setHyperlink(oldCell.getHyperlink());
  199. }
  200. String s, s1;
  201. // Set the cell data value
  202. switch (oldCell.getCellType()) {
  203. case Cell.CELL_TYPE_BLANK:
  204. break;
  205. case Cell.CELL_TYPE_BOOLEAN:
  206. newCell.setCellValue(oldCell.getBooleanCellValue());
  207. break;
  208. case Cell.CELL_TYPE_ERROR:
  209. newCell.setCellErrorValue(oldCell.getErrorCellValue());
  210. break;
  211. case Cell.CELL_TYPE_FORMULA:
  212. newCell.setCellFormula(oldCell.getCellFormula());
  213. break;
  214. case Cell.CELL_TYPE_NUMERIC:
  215. newCell.setCellValue(oldCell.getNumericCellValue());
  216. break;
  217. case Cell.CELL_TYPE_STRING:
  218. s = oldCell.getRichStringCellValue().getString();
  219. if (s.startsWith("=")) {
  220. // формула
  221. s = s.substring(1);
  222. s1 = UtString.substVar(s, substVars);
  223. if (!UtString.empty(s1)) {
  224. try {
  225. newCell.setCellType(Cell.CELL_TYPE_FORMULA);
  226. newCell.setCellFormula(s1);
  227. } catch (FormulaParseException e) {
  228. newCell.setCellValue("!ERROR");
  229. }
  230. }
  231. } else {
  232. s1 = UtString.substVar(s, substVars);
  233. if (styleInfo.isDate) {
  234. LocalDateTime dt = UtCnv.toDateTime(s1);
  235. if (!UtDate.isEmpty(dt)) {
  236. newCell.setCellValue(dt.toDate());
  237. } else {
  238. newCell.setCellValue(s1);
  239. }
  240. } else if (styleInfo.isNumber) {
  241. double v = UtCnv.toDouble(s1, Double.MIN_VALUE);
  242. if (v != Double.MIN_VALUE) {
  243. newCell.setCellValue(v);
  244. } else {
  245. newCell.setCellValue(s1);
  246. }
  247. } else {
  248. newCell.setCellValue(s1);
  249. }
  250. }
  251. break;
  252. }
  253. }
  254. protected StyleInfo getResultCellStyle(CellStyle tmlStyle) {
  255. StyleInfo st = cellStyles.get(tmlStyle);
  256. if (st != null) {
  257. return st;
  258. }
  259. throw new XError("Style not found!");
  260. }
  261. protected boolean isStyleNumber(CellStyle style) {
  262. String s = style.getDataFormatString();
  263. if (s == null) {
  264. return false;
  265. }
  266. return s.indexOf('0') != -1 || s.indexOf('#') != -1;
  267. }
  268. protected boolean isStyleDate(CellStyle style) {
  269. String s = style.getDataFormatString();
  270. if (s == null) {
  271. return false;
  272. }
  273. return DateUtil.isADateFormat(style.getFontIndex(), style.getDataFormatString());
  274. }
  275. }