1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.primefaces.extensions.component.exporter;
17
18 import java.awt.Color;
19 import java.io.IOException;
20 import java.io.OutputStream;
21 import java.lang.reflect.Array;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.StringTokenizer;
28
29 import javax.el.MethodExpression;
30 import javax.faces.FacesException;
31 import javax.faces.component.UIComponent;
32 import javax.faces.component.UIPanel;
33 import javax.faces.component.html.HtmlCommandButton;
34 import javax.faces.component.html.HtmlCommandLink;
35 import javax.faces.component.html.HtmlOutputText;
36 import javax.faces.context.ExternalContext;
37 import javax.faces.context.FacesContext;
38 import javax.faces.event.ActionEvent;
39
40 import org.apache.commons.lang3.StringUtils;
41 import org.apache.poi.ss.usermodel.Cell;
42 import org.apache.poi.ss.usermodel.CellStyle;
43 import org.apache.poi.ss.usermodel.FillPatternType;
44 import org.apache.poi.ss.usermodel.Font;
45 import org.apache.poi.ss.usermodel.HorizontalAlignment;
46 import org.apache.poi.ss.usermodel.PrintSetup;
47 import org.apache.poi.ss.usermodel.Row;
48 import org.apache.poi.ss.usermodel.Sheet;
49 import org.apache.poi.ss.usermodel.VerticalAlignment;
50 import org.apache.poi.ss.util.CellRangeAddress;
51 import org.apache.poi.ss.util.WorkbookUtil;
52 import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
53 import org.apache.poi.xssf.usermodel.XSSFCellStyle;
54 import org.apache.poi.xssf.usermodel.XSSFColor;
55 import org.apache.poi.xssf.usermodel.XSSFFont;
56 import org.apache.poi.xssf.usermodel.XSSFRichTextString;
57 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
58 import org.primefaces.component.api.DynamicColumn;
59 import org.primefaces.component.api.UIColumn;
60 import org.primefaces.component.column.Column;
61 import org.primefaces.component.columngroup.ColumnGroup;
62 import org.primefaces.component.datalist.DataList;
63 import org.primefaces.component.datatable.DataTable;
64 import org.primefaces.component.rowexpansion.RowExpansion;
65 import org.primefaces.component.subtable.SubTable;
66 import org.primefaces.expression.SearchExpressionFacade;
67 import org.primefaces.util.Constants;
68
69
70
71
72
73
74
75 public class ExcelExporter extends Exporter {
76
77 private XSSFWorkbook wb;
78
79 private CellStyle cellStyle;
80 private CellStyle facetStyle;
81 private CellStyle titleStyle;
82 private Color facetBackground;
83 private Short facetFontSize;
84 private Color facetFontColor;
85 private String facetFontStyle;
86 private String fontName;
87 private Short cellFontSize;
88 private Color cellFontColor;
89 private String cellFontStyle;
90 private String datasetPadding;
91
92 private CellStyle facetStyleLeftAlign;
93 private CellStyle facetStyleCenterAlign;
94 private CellStyle facetStyleRightAlign;
95 private CellStyle cellStyleLeftAlign;
96 private CellStyle cellStyleCenterAlign;
97 private CellStyle cellStyleRightAlign;
98
99 @Override
100 public void export(final ActionEvent event, final String tableId, final FacesContext context, final String filename, final String tableTitle,
101 final boolean pageOnly, final boolean selectionOnly,
102 final String encodingType, final MethodExpression preProcessor, final MethodExpression postProcessor, final boolean subTable)
103 throws IOException {
104
105 wb = new XSSFWorkbook();
106 final String safeName = WorkbookUtil.createSafeSheetName(filename);
107 final Sheet sheet = wb.createSheet(safeName);
108
109 cellStyle = wb.createCellStyle();
110 facetStyle = wb.createCellStyle();
111 titleStyle = wb.createCellStyle();
112
113 facetStyleLeftAlign = wb.createCellStyle();
114 facetStyleCenterAlign = wb.createCellStyle();
115 facetStyleRightAlign = wb.createCellStyle();
116 cellStyleLeftAlign = wb.createCellStyle();
117 cellStyleCenterAlign = wb.createCellStyle();
118 cellStyleRightAlign = wb.createCellStyle();
119
120 createCustomFonts();
121
122 if (preProcessor != null) {
123 preProcessor.invoke(context.getELContext(), new Object[] {wb});
124 }
125
126 int maxColumns = 0;
127 final String tokenString = StringUtils.normalizeSpace(tableId.replaceAll(",", StringUtils.SPACE));
128 final StringTokenizer st = new StringTokenizer(tokenString, StringUtils.SPACE);
129 while (st.hasMoreElements()) {
130 final String tableName = (String) st.nextElement();
131 final UIComponent component = SearchExpressionFacade.resolveComponent(context, event.getComponent(), tableName);
132 if (component == null) {
133 throw new FacesException("Cannot find component \"" + tableName + "\" in view.");
134 }
135 if (!(component instanceof DataTable || component instanceof DataList)) {
136 throw new FacesException(
137 "Unsupported datasource target:\"" + component.getClass().getName() + "\", exporter must target a PrimeFaces DataTable/DataList.");
138 }
139 if (!component.isRendered()) {
140 continue;
141 }
142
143 DataList list;
144 DataTable table;
145
146 if (tableTitle != null && !tableTitle.isEmpty() && !tableId.contains(",")) {
147 final Row titleRow = sheet.createRow(sheet.getLastRowNum());
148 final int cellIndex = titleRow.getLastCellNum() == -1 ? 0 : titleRow.getLastCellNum();
149 final Cell cell = titleRow.createCell(cellIndex);
150 cell.setCellValue(new XSSFRichTextString(tableTitle));
151 final Font titleFont = wb.createFont();
152 titleFont.setBold(true);
153 titleStyle.setFont(titleFont);
154 cell.setCellStyle(titleStyle);
155 sheet.createRow(sheet.getLastRowNum() + 3);
156
157 }
158 if (component instanceof DataList) {
159 list = (DataList) component;
160
161 if (list.getHeader() != null) {
162 tableFacet(context, sheet, list, "header");
163 }
164 if (pageOnly) {
165 exportPageOnly(context, list, sheet);
166 }
167 else {
168 exportAll(context, list, sheet);
169 }
170 }
171 else {
172
173 table = (DataTable) component;
174 final int columnsCount = getColumnsCount(table);
175
176 if (table.getHeader() != null && !subTable) {
177 tableFacet(context, sheet, table, columnsCount, "header");
178
179 }
180 if (!subTable) {
181 tableColumnGroup(sheet, table, "header");
182 }
183
184 addColumnFacets(table, sheet, ColumnType.HEADER);
185
186 if (pageOnly) {
187 exportPageOnly(context, table, sheet);
188 }
189 else if (selectionOnly) {
190 exportSelectionOnly(context, table, sheet);
191 }
192 else {
193 exportAll(context, table, sheet, subTable);
194 }
195
196 if (table.hasFooterColumn() && !subTable) {
197 addColumnFacets(table, sheet, ColumnType.FOOTER);
198 }
199 if (!subTable) {
200 tableColumnGroup(sheet, table, "footer");
201 }
202 table.setRowIndex(-1);
203
204 final int cols = table.getColumnsCount();
205
206 if (maxColumns < cols) {
207 maxColumns = cols;
208 }
209 }
210 sheet.createRow(sheet.getLastRowNum() + Integer.parseInt(datasetPadding));
211 }
212
213 if (postProcessor != null) {
214 postProcessor.invoke(context.getELContext(), new Object[] {wb});
215 }
216
217 if (!subTable) {
218 for (int i = 0; i < maxColumns; i++) {
219 sheet.autoSizeColumn((short) i);
220 }
221 }
222
223 final PrintSetup printSetup = sheet.getPrintSetup();
224 printSetup.setLandscape(true);
225 printSetup.setPaperSize(PrintSetup.A4_PAPERSIZE);
226 sheet.setPrintGridlines(true);
227
228 writeExcelToResponse(context.getExternalContext(), wb, filename);
229
230 }
231
232 protected void exportAll(final FacesContext context, final DataTable table, final Sheet sheet, final Boolean subTable) {
233
234 final int first = table.getFirst();
235 final int rowCount = table.getRowCount();
236 final boolean lazy = table.isLazy();
237 int i = 0;
238 if (subTable) {
239 int subTableCount = table.getRowCount();
240 SubTable subtable = table.getSubTable();
241 final int subTableColumnsCount = getColumnsCount(subtable);
242
243 if (table.getHeader() != null) {
244 tableFacet(context, sheet, table, subTableColumnsCount, "header");
245 }
246
247 tableColumnGroup(sheet, table, "header");
248
249 while (subTableCount > 0) {
250
251 subTableCount--;
252 table.setRowIndex(i);
253 i++;
254 if (subtable.getHeader() != null) {
255 tableFacet(context, sheet, subtable, subTableColumnsCount, "header");
256 }
257
258 if (hasHeaderColumn(subtable)) {
259 addColumnFacets(subtable, sheet, ColumnType.HEADER);
260 }
261
262 exportAll(context, subtable, sheet);
263
264 if (hasFooterColumn(subtable)) {
265
266 addColumnFacets(subtable, sheet, ColumnType.FOOTER);
267 }
268
269 if (subtable.getFooter() != null) {
270 tableFacet(context, sheet, subtable, subTableColumnsCount, "footer");
271 }
272
273 subtable.setRowIndex(-1);
274 subtable = table.getSubTable();
275 }
276
277 tableColumnGroup(sheet, table, "footer");
278
279 if (table.hasFooterColumn()) {
280 tableFacet(context, sheet, table, subTableColumnsCount, "footer");
281 }
282 }
283 else {
284 if (lazy) {
285 if (rowCount > 0) {
286 table.setFirst(0);
287 table.setRows(rowCount);
288 table.clearLazyCache();
289 table.loadLazyData();
290 }
291 for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
292 exportRow(table, sheet, rowIndex);
293 }
294
295
296 table.setFirst(first);
297 table.setRowIndex(-1);
298 table.clearLazyCache();
299 table.loadLazyData();
300 }
301 else {
302 for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
303 exportRow(table, sheet, rowIndex);
304 }
305
306 table.setFirst(first);
307 }
308 }
309 }
310
311 protected void exportAll(final FacesContext context, final SubTable table, final Sheet sheet) {
312 final int rowCount = table.getRowCount();
313
314 tableColumnGroup(sheet, table, "header");
315 if (hasHeaderColumn(table)) {
316 addColumnFacets(table, sheet, ColumnType.HEADER);
317 }
318 for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
319 exportRow(table, sheet, rowIndex);
320 }
321 if (hasFooterColumn(table)) {
322 addColumnFacets(table, sheet, ColumnType.FOOTER);
323 }
324 tableColumnGroup(sheet, table, "footer");
325
326 }
327
328 protected void exportAll(final FacesContext context, final DataList list, final Sheet sheet) {
329 final int first = list.getFirst();
330 final int rowCount = list.getRowCount();
331 final int rows = list.getRows();
332 final boolean lazy = list.isLazy();
333
334 if (lazy) {
335 for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
336 if (rowIndex % rows == 0) {
337 list.setFirst(rowIndex);
338 list.loadLazyData();
339 }
340
341 exportRow(list, sheet, rowIndex);
342 }
343
344
345 list.setFirst(first);
346 list.loadLazyData();
347 }
348 else {
349
350 for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
351 exportRow(list, sheet, rowIndex);
352 }
353
354 list.setFirst(first);
355 }
356
357 }
358
359 protected void exportPageOnly(final FacesContext context, final DataTable table, final Sheet sheet) {
360 final int first = table.getFirst();
361 final int rowsToExport = first + table.getRows();
362
363 for (int rowIndex = first; rowIndex < rowsToExport; rowIndex++) {
364 exportRow(table, sheet, rowIndex);
365 }
366 }
367
368 protected void exportPageOnly(final FacesContext context, final DataList list, final Sheet sheet) {
369 final int first = list.getFirst();
370 final int rowsToExport = first + list.getRows();
371
372 for (int rowIndex = first; rowIndex < rowsToExport; rowIndex++) {
373 exportRow(list, sheet, rowIndex);
374 }
375 }
376
377 protected void exportSelectionOnly(final FacesContext context, final DataTable table, final Sheet sheet) {
378 final Object selection = table.getSelection();
379 final String var = table.getVar();
380
381 if (selection != null) {
382 final Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
383
384 if (selection.getClass().isArray()) {
385 final int size = Array.getLength(selection);
386
387 for (int i = 0; i < size; i++) {
388 requestMap.put(var, Array.get(selection, i));
389 exportCells(table, sheet);
390 }
391 }
392 else if (Collection.class.isAssignableFrom(selection.getClass())) {
393 final Collection<?> collection = (Collection<?>) selection;
394 for (final Iterator<? extends Object> it = collection.iterator(); it.hasNext();) {
395 requestMap.put(var, it.next());
396 exportCells(table, sheet);
397 }
398 }
399 else {
400 requestMap.put(var, selection);
401 exportCells(table, sheet);
402 }
403 }
404 }
405
406 protected void tableFacet(final FacesContext context, final Sheet sheet, final DataTable table, final int columnCount, final String facetType) {
407 final Map<String, UIComponent> map = table.getFacets();
408 final UIComponent component = map.get(facetType);
409 if (component != null) {
410 String headerValue;
411 if (component instanceof HtmlCommandButton) {
412 headerValue = exportValue(context, component);
413 }
414 else if (component instanceof HtmlCommandLink) {
415 headerValue = exportValue(context, component);
416 }
417 else if (component instanceof UIPanel) {
418 final StringBuilder header = new StringBuilder(Constants.EMPTY_STRING);
419 for (final UIComponent child : component.getChildren()) {
420 headerValue = exportValue(context, child);
421 header.append(headerValue);
422 }
423 headerValue = header.toString();
424 }
425 else {
426 headerValue = exportFacetValue(context, component);
427 }
428
429 final int sheetRowIndex = sheet.getLastRowNum() + 1;
430 final Row row = sheet.createRow(sheetRowIndex);
431 final Cell cell = row.createCell((short) 0);
432 cell.setCellValue(headerValue);
433 cell.setCellStyle(facetStyle);
434
435 sheet.addMergedRegion(new CellRangeAddress(
436 sheetRowIndex,
437 sheetRowIndex,
438 0,
439 columnCount - 1
440 ));
441
442 }
443 }
444
445 protected void tableFacet(final FacesContext context, final Sheet sheet, final SubTable table, final int columnCount, final String facetType) {
446 final Map<String, UIComponent> map = table.getFacets();
447 final UIComponent component = map.get(facetType);
448 if (component != null) {
449 String headerValue;
450 if (component instanceof HtmlCommandButton) {
451 headerValue = exportValue(context, component);
452 }
453 else if (component instanceof HtmlCommandLink) {
454 headerValue = exportValue(context, component);
455 }
456 else if (component instanceof UIPanel) {
457 final StringBuilder header = new StringBuilder(Constants.EMPTY_STRING);
458 for (final UIComponent child : component.getChildren()) {
459 headerValue = exportValue(context, child);
460 header.append(headerValue);
461 }
462 headerValue = header.toString();
463 }
464 else {
465 headerValue = exportFacetValue(context, component);
466 }
467
468 final int sheetRowIndex = sheet.getLastRowNum() + 1;
469 final Row row = sheet.createRow(sheetRowIndex);
470 final Cell cell = row.createCell((short) 0);
471 cell.setCellValue(headerValue);
472 cell.setCellStyle(facetStyle);
473
474 sheet.addMergedRegion(new CellRangeAddress(
475 sheetRowIndex,
476 sheetRowIndex,
477 0,
478 columnCount - 1
479 ));
480
481 }
482 }
483
484 protected void tableFacet(final FacesContext context, final Sheet sheet, final DataList list, final String facetType) {
485 final Map<String, UIComponent> map = list.getFacets();
486 final UIComponent component = map.get(facetType);
487 if (component != null) {
488 String headerValue;
489 if (component instanceof HtmlCommandButton) {
490 headerValue = exportValue(context, component);
491 }
492 else if (component instanceof HtmlCommandLink) {
493 headerValue = exportValue(context, component);
494 }
495 else {
496 headerValue = exportFacetValue(context, component);
497 }
498
499 final int sheetRowIndex = sheet.getLastRowNum() + 1;
500 final Row row = sheet.createRow(sheetRowIndex);
501 final Cell cell = row.createCell((short) 0);
502 cell.setCellValue(headerValue);
503 cell.setCellStyle(facetStyle);
504
505 sheet.addMergedRegion(new CellRangeAddress(
506 sheetRowIndex,
507 sheetRowIndex,
508 0,
509 1
510 ));
511
512 }
513 }
514
515 private int calculateColumnOffset(final Sheet sheet, final int row, int col) {
516 for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
517 final CellRangeAddress merged = sheet.getMergedRegion(j);
518 if (merged.isInRange(row, col)) {
519 col = merged.getLastColumn() + 1;
520 }
521 }
522 return col;
523 }
524
525 private void putText(final Row xlRow, final short col, final String text) {
526 final Cell cell = xlRow.createCell(col);
527 cell.setCellValue(text);
528 cell.setCellStyle(facetStyleCenterAlign);
529 }
530
531 protected void tableColumnGroup(final Sheet sheet, final DataTable table, final String facetType) {
532 facetStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
533 facetStyleCenterAlign.setVerticalAlignment(VerticalAlignment.CENTER);
534 facetStyleCenterAlign.setWrapText(true);
535
536 final ColumnGroup cg = table.getColumnGroup(facetType);
537 List<UIComponent> headerComponentList = null;
538 if (cg != null) {
539 headerComponentList = cg.getChildren();
540 }
541 if (headerComponentList != null) {
542 for (final UIComponent component : headerComponentList) {
543 if (component instanceof org.primefaces.component.row.Row) {
544 final org.primefaces.component.row.Row row = (org.primefaces.component.row.Row) component;
545 final int rowIndex = sheet.getLastRowNum() + 1;
546 final Row xlRow = sheet.createRow(rowIndex);
547 int colIndex = 0;
548 for (final UIComponent rowComponent : row.getChildren()) {
549 final UIColumn column = (UIColumn) rowComponent;
550 if (!column.isRendered() || !column.isExportable()) {
551 continue;
552 }
553
554 final String text = facetType.equalsIgnoreCase("header") ? column.getHeaderText() : column.getFooterText();
555
556 final int rowSpan = column.getRowspan() - 1;
557 final int colSpan = column.getColspan() - 1;
558
559 if (rowSpan > 0 && colSpan > 0) {
560 colIndex = calculateColumnOffset(sheet, rowIndex, colIndex);
561 sheet.addMergedRegion(new CellRangeAddress(
562 rowIndex,
563 rowIndex + rowSpan,
564 colIndex,
565 colIndex + colSpan
566 ));
567 putText(xlRow, (short) colIndex, text);
568 colIndex = colIndex + colSpan;
569 }
570 else if (rowSpan > 0) {
571 sheet.addMergedRegion(new CellRangeAddress(
572 rowIndex,
573 rowIndex + rowSpan,
574 colIndex,
575 colIndex
576 ));
577 putText(xlRow, (short) colIndex, text);
578 }
579 else if (colSpan > 0) {
580 colIndex = calculateColumnOffset(sheet, rowIndex, colIndex);
581 sheet.addMergedRegion(new CellRangeAddress(
582 rowIndex,
583 rowIndex,
584 colIndex,
585 colIndex + colSpan
586 ));
587 putText(xlRow, (short) colIndex, text);
588 colIndex = colIndex + colSpan;
589 }
590 else {
591 colIndex = calculateColumnOffset(sheet, rowIndex, colIndex);
592 putText(xlRow, (short) colIndex, text);
593 }
594 colIndex++;
595 }
596 }
597 }
598 }
599 }
600
601 protected void tableColumnGroup(final Sheet sheet, final SubTable table, final String facetType) {
602 final ColumnGroup cg = table.getColumnGroup(facetType);
603 List<UIComponent> headerComponentList = null;
604 if (cg != null) {
605 headerComponentList = cg.getChildren();
606 }
607 if (headerComponentList != null) {
608 for (final UIComponent component : headerComponentList) {
609 if (component instanceof org.primefaces.component.row.Row) {
610 final org.primefaces.component.row.Row row = (org.primefaces.component.row.Row) component;
611 final int sheetRowIndex = sheet.getPhysicalNumberOfRows() > 0 ? sheet.getLastRowNum() + 1 : 0;
612 final Row xlRow = sheet.createRow(sheetRowIndex);
613 int i = 0;
614 for (final UIComponent rowComponent : row.getChildren()) {
615 final UIColumn column = (UIColumn) rowComponent;
616 String value;
617 if (facetType.equalsIgnoreCase("header")) {
618 value = column.getHeaderText();
619 }
620 else {
621 value = column.getFooterText();
622 }
623 final int rowSpan = column.getRowspan();
624 final int colSpan = column.getColspan();
625
626 Cell cell;
627
628 if (rowSpan > 1 || colSpan > 1) {
629
630 if (rowSpan > 1) {
631 cell = xlRow.createCell((short) i);
632 Boolean rowSpanFlag = false;
633 for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
634 final CellRangeAddress merged = sheet.getMergedRegion(j);
635 if (merged.isInRange(sheetRowIndex, i)) {
636 rowSpanFlag = true;
637 }
638
639 }
640 if (!rowSpanFlag) {
641 cell.setCellStyle(cellStyle);
642 cell.setCellValue(value);
643 sheet.addMergedRegion(new CellRangeAddress(
644 sheetRowIndex,
645 sheetRowIndex + rowSpan - 1,
646 i,
647 i
648 ));
649 }
650 }
651 if (colSpan > 1) {
652 cell = xlRow.createCell((short) i);
653 for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
654 final CellRangeAddress merged = sheet.getMergedRegion(j);
655 if (merged.isInRange(sheetRowIndex, i)) {
656 cell = xlRow.createCell((short) ++i);
657 }
658 }
659 cell.setCellStyle(cellStyle);
660 cell.setCellValue(value);
661 sheet.addMergedRegion(new CellRangeAddress(
662 sheetRowIndex,
663 sheetRowIndex,
664 i,
665 i + colSpan - 1
666 ));
667 i = i + colSpan - 1;
668 }
669 }
670 else {
671 cell = xlRow.createCell((short) i);
672 for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
673 final CellRangeAddress merged = sheet.getMergedRegion(j);
674 if (merged.isInRange(sheetRowIndex, i)) {
675 cell = xlRow.createCell((short) ++i);
676 }
677 }
678 cell.setCellValue(value);
679 cell.setCellStyle(facetStyle);
680
681 }
682 i++;
683 }
684 }
685
686 }
687 }
688
689 }
690
691 protected void exportRow(final DataTable table, final Sheet sheet, final int rowIndex) {
692 table.setRowIndex(rowIndex);
693 if (!table.isRowAvailable()) {
694 return;
695 }
696
697 exportCells(table, sheet);
698 }
699
700 protected void exportRow(final SubTable table, final Sheet sheet, final int rowIndex) {
701 table.setRowIndex(rowIndex);
702
703 if (!table.isRowAvailable()) {
704 return;
705 }
706
707 exportCells(table, sheet);
708 }
709
710 protected void exportRow(final DataList list, final Sheet sheet, final int rowIndex) {
711 list.setRowIndex(rowIndex);
712
713 if (!list.isRowAvailable()) {
714 return;
715 }
716
717 exportCells(list, sheet);
718 }
719
720 protected void exportCells(final DataTable table, final Sheet sheet) {
721 final int sheetRowIndex = sheet.getLastRowNum() + 1;
722 final Row row = sheet.createRow(sheetRowIndex);
723
724 facetStyleLeftAlign.setAlignment(HorizontalAlignment.LEFT);
725 facetStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
726 facetStyleCenterAlign.setVerticalAlignment(VerticalAlignment.CENTER);
727 facetStyleCenterAlign.setWrapText(true);
728 facetStyleRightAlign.setAlignment(HorizontalAlignment.RIGHT);
729 cellStyleLeftAlign.setAlignment(HorizontalAlignment.LEFT);
730 cellStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
731 cellStyleRightAlign.setAlignment(HorizontalAlignment.RIGHT);
732
733 for (final UIColumn col : table.getColumns()) {
734
735 if (col instanceof DynamicColumn) {
736 ((DynamicColumn) col).applyStatelessModel();
737 }
738
739 if (col.isRendered() && col.isExportable()) {
740 addColumnValue(row, col.getChildren(), "content", col);
741 }
742 }
743 final FacesContext context = null;
744 if (table.getRowIndex() == 0) {
745 for (final UIComponent component : table.getChildren()) {
746 if (component instanceof RowExpansion) {
747 final RowExpansion rowExpansion = (RowExpansion) component;
748 if (rowExpansion.getChildren() != null) {
749 if (rowExpansion.getChildren().get(0) instanceof DataTable) {
750 final DataTable childTable = (DataTable) rowExpansion.getChildren().get(0);
751 childTable.setRowIndex(-1);
752 }
753 if (rowExpansion.getChildren().get(0) instanceof DataList) {
754 final DataList childList = (DataList) rowExpansion.getChildren().get(0);
755 childList.setRowIndex(-1);
756 }
757 }
758
759 }
760 }
761 }
762 for (final UIComponent component : table.getChildren()) {
763 if (component instanceof RowExpansion) {
764 final RowExpansion rowExpansion = (RowExpansion) component;
765 if (rowExpansion.getChildren() != null) {
766 for (int i = 0; i < rowExpansion.getChildren().size(); i++) {
767 final UIComponent child = rowExpansion.getChildren().get(i);
768 if (child instanceof DataList) {
769 final DataList list = (DataList) child;
770 if (list.getHeader() != null) {
771 tableFacet(context, sheet, list, "header");
772 }
773 exportAll(context, list, sheet);
774 }
775 }
776 for (int i = 0; i < rowExpansion.getChildren().size(); i++) {
777 if (rowExpansion.getChildren().get(i) instanceof DataTable) {
778 final DataTable childTable = (DataTable) rowExpansion.getChildren().get(i);
779 final int columnsCount = getColumnsCount(childTable);
780 if (columnsCount > 0) {
781 if (childTable.getHeader() != null) {
782 tableFacet(context, sheet, childTable, columnsCount, "header");
783
784 }
785 tableColumnGroup(sheet, childTable, "header");
786
787 addColumnFacets(childTable, sheet, ColumnType.HEADER);
788
789 exportAll(context, childTable, sheet, false);
790
791 if (childTable.hasFooterColumn()) {
792 addColumnFacets(childTable, sheet, ColumnType.FOOTER);
793 }
794 tableColumnGroup(sheet, childTable, "footer");
795 childTable.setRowIndex(-1);
796 }
797 }
798 }
799
800 }
801 }
802 }
803 }
804
805 protected void exportCells(final SubTable table, final Sheet sheet) {
806 final int sheetRowIndex = sheet.getLastRowNum() + 1;
807 final Row row = sheet.createRow(sheetRowIndex);
808
809 facetStyleLeftAlign.setAlignment(HorizontalAlignment.LEFT);
810 facetStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
811 facetStyleCenterAlign.setVerticalAlignment(VerticalAlignment.CENTER);
812 facetStyleCenterAlign.setWrapText(true);
813 facetStyleRightAlign.setAlignment(HorizontalAlignment.RIGHT);
814 cellStyleLeftAlign.setAlignment(HorizontalAlignment.LEFT);
815 cellStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
816 cellStyleRightAlign.setAlignment(HorizontalAlignment.RIGHT);
817
818 for (final UIColumn col : table.getColumns()) {
819
820 if (col instanceof DynamicColumn) {
821 ((DynamicColumn) col).applyStatelessModel();
822 }
823
824 if (col.isRendered() && col.isExportable()) {
825 addColumnValue(row, col.getChildren(), "content", col);
826 }
827 }
828 }
829
830 protected void exportCells(final DataList list, final Sheet sheet) {
831 final int sheetRowIndex = sheet.getLastRowNum() + 1;
832 final Row row = sheet.createRow(sheetRowIndex);
833
834 facetStyleLeftAlign.setAlignment(HorizontalAlignment.LEFT);
835 facetStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
836 facetStyleCenterAlign.setVerticalAlignment(VerticalAlignment.CENTER);
837 facetStyleCenterAlign.setWrapText(true);
838 facetStyleRightAlign.setAlignment(HorizontalAlignment.RIGHT);
839 cellStyleLeftAlign.setAlignment(HorizontalAlignment.LEFT);
840 cellStyleCenterAlign.setAlignment(HorizontalAlignment.CENTER);
841 cellStyleRightAlign.setAlignment(HorizontalAlignment.RIGHT);
842
843 for (final UIComponent component : list.getChildren()) {
844 if (component instanceof Column) {
845 final UIColumn column = (UIColumn) component;
846 for (final UIComponent childComponent : column.getChildren()) {
847 final int cellIndex = row.getLastCellNum() == -1 ? 0 : row.getLastCellNum();
848 final Cell cell = row.createCell(cellIndex);
849 if (component.isRendered()) {
850 final String value = exportValue(FacesContext.getCurrentInstance(), childComponent);
851 cell.setCellValue(new XSSFRichTextString(value));
852 cell.setCellStyle(cellStyle);
853 }
854 }
855
856 }
857 else {
858 final int cellIndex = row.getLastCellNum() == -1 ? 0 : row.getLastCellNum();
859 final Cell cell = row.createCell(cellIndex);
860 if (component.isRendered()) {
861 final String value = exportValue(FacesContext.getCurrentInstance(), component);
862 cell.setCellValue(new XSSFRichTextString(value));
863 cell.setCellStyle(cellStyle);
864 }
865 }
866 }
867
868 }
869
870 protected void addColumnFacets(final DataTable table, final Sheet sheet, final ColumnType columnType) {
871
872 final int sheetRowIndex = sheet.getLastRowNum() + 1;
873 Row rowHeader = null;
874
875 for (final UIColumn col : table.getColumns()) {
876
877 if (col instanceof DynamicColumn) {
878 ((DynamicColumn) col).applyStatelessModel();
879 }
880
881 if (col.isRendered() && col.isExportable() && col.getFacet(columnType.facet()) != null) {
882 if (rowHeader == null) {
883 rowHeader = sheet.createRow(sheetRowIndex);
884 }
885 addColumnValue(rowHeader, col.getFacet(columnType.facet()), "facet");
886 }
887 }
888
889 }
890
891 protected void addColumnFacets(final SubTable table, final Sheet sheet, final ColumnType columnType) {
892
893 final int sheetRowIndex = sheet.getPhysicalNumberOfRows() > 0 ? sheet.getLastRowNum() + 1 : 0;
894 final Row rowHeader = sheet.createRow(sheetRowIndex);
895
896 for (final UIColumn col : table.getColumns()) {
897
898 if (col instanceof DynamicColumn) {
899 ((DynamicColumn) col).applyStatelessModel();
900 }
901
902 if (col.isRendered() && col.isExportable()) {
903 addColumnValue(rowHeader, col.getFacet(columnType.facet()), "facet");
904 }
905 }
906 }
907
908 protected void addColumnValue(final Row row, final UIComponent component, final String type) {
909 final int cellIndex = row.getLastCellNum() == -1 ? 0 : row.getLastCellNum();
910 final Cell cell = row.createCell(cellIndex);
911 final String value = component == null ? Constants.EMPTY_STRING : exportValue(FacesContext.getCurrentInstance(), component);
912 cell.setCellValue(new XSSFRichTextString(value));
913 if (type.equalsIgnoreCase("facet")) {
914 addFacetAlignments(component, cell);
915 }
916 else {
917 addColumnAlignments(component, cell);
918 }
919
920 }
921
922 protected void addColumnValue(final Row row, final List<UIComponent> components, final String columnType, final UIColumn column) {
923 final int cellIndex = row.getLastCellNum() == -1 ? 0 : row.getLastCellNum();
924 final Cell cell = row.createCell(cellIndex);
925 final FacesContext context = FacesContext.getCurrentInstance();
926
927 if (column.getExportFunction() != null) {
928 cell.setCellValue(new XSSFRichTextString(exportColumnByFunction(context, column)));
929 }
930 else {
931 final StringBuilder builder = new StringBuilder();
932 for (final UIComponent component : components) {
933 if (component.isRendered()) {
934 final String value = exportValue(context, component);
935
936 if (value != null) {
937 builder.append(value);
938 }
939 }
940 }
941
942 cell.setCellValue(new XSSFRichTextString(builder.toString()));
943
944 if (columnType.equalsIgnoreCase("facet")) {
945 for (final UIComponent component : components) {
946 addFacetAlignments(component, cell);
947 }
948 }
949 else {
950 for (final UIComponent component : components) {
951 addColumnAlignments(component, cell);
952 }
953 }
954 }
955 }
956
957 protected void addColumnAlignments(final UIComponent component, final Cell cell) {
958 if (component instanceof HtmlOutputText) {
959 final HtmlOutputText output = (HtmlOutputText) component;
960 if (output.getStyle() != null && output.getStyle().contains("left")) {
961 cell.setCellStyle(cellStyleLeftAlign);
962 }
963 if (output.getStyle() != null && output.getStyle().contains("right")) {
964 cell.setCellStyle(cellStyleRightAlign);
965 }
966 if (output.getStyle() != null && output.getStyle().contains("center")) {
967 cell.setCellStyle(cellStyleCenterAlign);
968 }
969 }
970 }
971
972 protected void addFacetAlignments(final UIComponent component, final Cell cell) {
973 if (component instanceof HtmlOutputText) {
974 final HtmlOutputText output = (HtmlOutputText) component;
975 if (output.getStyle() != null && output.getStyle().contains("left")) {
976 cell.setCellStyle(facetStyleLeftAlign);
977 }
978 else if (output.getStyle() != null && output.getStyle().contains("right")) {
979 cell.setCellStyle(facetStyleRightAlign);
980 }
981 else {
982 cell.setCellStyle(facetStyleCenterAlign);
983 }
984 }
985 }
986
987 @Override
988 public void customFormat(final String facetBackground, final String facetFontSize, final String facetFontColor, final String facetFontStyle,
989 final String fontName, final String cellFontSize,
990 final String cellFontColor, final String cellFontStyle, final String datasetPadding, final String orientation) {
991 if (facetBackground != null) {
992 this.facetBackground = Color.decode(facetBackground);
993 }
994 if (facetFontColor != null) {
995 this.facetFontColor = Color.decode(facetFontColor);
996 }
997 if (fontName != null) {
998 this.fontName = fontName;
999 }
1000 if (cellFontColor != null) {
1001 this.cellFontColor = Color.decode(cellFontColor);
1002 }
1003
1004 this.facetFontSize = Short.valueOf(facetFontSize);
1005 this.facetFontStyle = facetFontStyle;
1006 this.cellFontSize = Short.valueOf(cellFontSize);
1007 this.cellFontStyle = cellFontStyle;
1008 this.datasetPadding = datasetPadding;
1009
1010 }
1011
1012 protected void createCustomFonts() {
1013
1014 final Font facetFont = wb.createFont();
1015 final Font cellFont = wb.createFont();
1016 final DefaultIndexedColorMap colorMap = new DefaultIndexedColorMap();
1017
1018 if (cellFontColor != null) {
1019 final XSSFColor cellColor = new XSSFColor(cellFontColor, colorMap);
1020 ((XSSFFont) cellFont).setColor(cellColor);
1021 }
1022 if (cellFontSize != null) {
1023 cellFont.setFontHeightInPoints(cellFontSize);
1024 }
1025
1026 if (cellFontStyle.equalsIgnoreCase("BOLD")) {
1027 cellFont.setBold(true);
1028 }
1029 if (cellFontStyle.equalsIgnoreCase("ITALIC")) {
1030 cellFont.setItalic(true);
1031 }
1032
1033 if (facetFontStyle.equalsIgnoreCase("BOLD")) {
1034 facetFont.setBold(true);
1035 }
1036 if (facetFontStyle.equalsIgnoreCase("ITALIC")) {
1037 facetFont.setItalic(true);
1038 }
1039
1040 if (fontName != null) {
1041 cellFont.setFontName(fontName);
1042 facetFont.setFontName(fontName);
1043 }
1044
1045 if (facetBackground != null) {
1046 final XSSFColor backgroundColor = new XSSFColor(facetBackground, colorMap);
1047 ((XSSFCellStyle) facetStyle).setFillForegroundColor(backgroundColor);
1048 ((XSSFCellStyle) facetStyleLeftAlign).setFillForegroundColor(backgroundColor);
1049 ((XSSFCellStyle) facetStyleCenterAlign).setFillForegroundColor(backgroundColor);
1050 ((XSSFCellStyle) facetStyleRightAlign).setFillForegroundColor(backgroundColor);
1051 facetStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1052 facetStyleLeftAlign.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1053 facetStyleCenterAlign.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1054 facetStyleRightAlign.setFillPattern(FillPatternType.SOLID_FOREGROUND);
1055 }
1056
1057 if (facetFontColor != null) {
1058 final XSSFColor facetColor = new XSSFColor(facetFontColor, colorMap);
1059 ((XSSFFont) facetFont).setColor(facetColor);
1060
1061 }
1062 if (facetFontSize != null) {
1063 facetFont.setFontHeightInPoints(facetFontSize);
1064 }
1065
1066 cellStyle.setFont(cellFont);
1067 cellStyleLeftAlign.setFont(cellFont);
1068 cellStyleCenterAlign.setFont(cellFont);
1069 cellStyleRightAlign.setFont(cellFont);
1070
1071 facetStyle.setFont(facetFont);
1072 facetStyleLeftAlign.setFont(facetFont);
1073 facetStyleCenterAlign.setFont(facetFont);
1074 facetStyleRightAlign.setFont(facetFont);
1075
1076
1077 }
1078
1079 protected void writeExcelToResponse(final ExternalContext externalContext, final org.apache.poi.ss.usermodel.Workbook generatedExcel, final String filename)
1080 throws IOException {
1081
1082 externalContext.setResponseContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
1083 externalContext.setResponseHeader("Expires", "0");
1084 externalContext.setResponseHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
1085 externalContext.setResponseHeader("Pragma", "public");
1086 externalContext.setResponseHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx");
1087 externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", Collections.<String, Object> emptyMap());
1088
1089 final OutputStream out = externalContext.getResponseOutputStream();
1090 generatedExcel.write(out);
1091 externalContext.responseFlushBuffer();
1092 }
1093 }