From e0da1968b140dd05ce85f7e58b236e791c61ad17 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Sat, 6 Jul 2019 17:03:12 +0800 Subject: [PATCH] IDEMPIERE-4001 Improve excel export for form type report --- .../impexp/AbstractExcelExporter.java | 129 ++++++++++-- .../print/export/PrintDataExcelExporter.java | 185 ++++++++++++++++++ .../print/layout/PrintDataEvaluatee.java | 4 +- 3 files changed, 305 insertions(+), 13 deletions(-) diff --git a/org.adempiere.base/src/org/adempiere/impexp/AbstractExcelExporter.java b/org.adempiere.base/src/org/adempiere/impexp/AbstractExcelExporter.java index 216af59df6..d212cd0c0f 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/AbstractExcelExporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/AbstractExcelExporter.java @@ -295,7 +295,7 @@ public abstract class AbstractExcelExporter return; // fixColumnWidth(prevSheet, colCount); - if (m_colSplit >= 0 || m_rowSplit >= 0) + if ((m_colSplit >= 0 || m_rowSplit >= 0) && !isForm()) prevSheet.createFreezePane(m_colSplit >= 0 ? m_colSplit : 0, m_rowSplit >= 0 ? m_rowSplit : 0); if (!Util.isEmpty(prevSheetName, true) && m_sheetCount > 0) { int prevSheetIndex = m_sheetCount - 1; @@ -313,7 +313,10 @@ public abstract class AbstractExcelExporter formatPage(sheet); createHeaderFooter(sheet); createParameter(sheet); - createTableHeader(sheet); + if (!isForm()) + { + createTableHeader(sheet); + } m_sheetCount++; // return sheet; @@ -417,7 +420,17 @@ public abstract class AbstractExcelExporter */ protected void export(OutputStream out) throws Exception { - HSSFSheet sheet= createTableSheet(); + HSSFSheet sheet= null; + if (out != null) + { + sheet = createTableSheet(); + } + else + { + m_dataFormat = m_workbook.createDataFormat(); + sheet = m_workbook.getSheetAt(0); + createTableHeader(sheet, sheet.getLastRowNum()+2); + } String sheetName = null; // int colnumMax = 0; @@ -429,7 +442,11 @@ public abstract class AbstractExcelExporter preValues = new Object [colSuppressRepeats.length]; } - int initxls_rownum = Math.max(noOfParameter+1, 1); + int initxls_rownum = 0; + if (out != null) + initxls_rownum = Math.max(noOfParameter+1, 1); + else + initxls_rownum = Math.max(noOfParameter+1, sheet.getLastRowNum()+1); for (int xls_rownum = initxls_rownum; rownum < lastRowNum; rownum++, xls_rownum++) { @@ -449,10 +466,35 @@ public abstract class AbstractExcelExporter if (isColumnPrinted(col)) { printColIndex++; - HSSFCell cell = row.createCell(colnum); - + HSSFCell cell = null; // line row Object obj = getValueAt(rownum, col); + if (isForm()) + { + if (isVisible(rownum, col) && (!isSuppressNull(col) || (obj != null && !Util.isEmpty(obj.toString(), true)))) + { + row = getFormRow(sheet, col); + cell = getFormCell(row, col); + String label = fixString(getHeaderName(col)); + if (!Util.isEmpty(label, true)) + { + cell.setCellValue(new HSSFRichTextString(label)); + int index = cell.getColumnIndex()+1; + cell = row.getCell(index); + if (cell == null) + cell = row.createCell(index); + } + } + else if (isSetFormRowPosition(col)) + { + row = getFormRow(sheet, col); + } + } + else + { + cell = row.createCell(colnum); + } + int displayType = getDisplayType(rownum, col); if (obj == null){ if (colSuppressRepeats != null && colSuppressRepeats[printColIndex]){ @@ -460,8 +502,9 @@ public abstract class AbstractExcelExporter } }else if (colSuppressRepeats != null && colSuppressRepeats[printColIndex] && obj.equals(preValues[printColIndex])){ //suppress - } - else if (DisplayType.isDate(displayType)) { + } else if (!isVisible(rownum, col)) { + ; + } else if (DisplayType.isDate(displayType)) { Timestamp value = (Timestamp)obj; cell.setCellValue(value); } @@ -485,8 +528,12 @@ public abstract class AbstractExcelExporter cell.setCellValue(new HSSFRichTextString(value)); } // - HSSFCellStyle style = getStyle(rownum, col); - cell.setCellStyle(style); + if (cell != null) { + HSSFCellStyle style = getStyle(rownum, col); + if (isForm()) + style.setWrapText(true); + cell.setCellStyle(style); + } // Page break if (isPageBreak(rownum, col)) { isPageBreak = true; @@ -507,7 +554,10 @@ public abstract class AbstractExcelExporter isPageBreak = false; } } // for all rows - closeTableSheet(sheet, sheetName, colnumMax); + if (out == null) + fixColumnWidth(sheet, colnumMax); + else + closeTableSheet(sheet, sheetName, colnumMax); // if(out!=null) @@ -562,4 +612,61 @@ public abstract class AbstractExcelExporter m_workbook = workbook; export(null); } + + /** + * @return true if it is form layout + */ + protected boolean isForm() + { + return false; + } + + /** + * + * @param row + * @param col + * @return true if column is visible + */ + protected boolean isVisible(int row, int col) + { + return true; + } + + /** + * + * @param col + * @return true if column should be hidden when it is null + */ + protected boolean isSuppressNull(int col) { + return false; + } + + /** + * + * @param col + * @return true if column is use to set new row position + */ + protected boolean isSetFormRowPosition(int col) { + return false; + } + + /** + * get cell for column. use for form layout + * @param row + * @param colnum + * @return cell for column + */ + protected HSSFCell getFormCell(HSSFRow row, int colnum) { + return null; + } + + /** + * get row for column. use for form layout + * @param sheet + * @param colnum + * @return row for column + */ + protected HSSFRow getFormRow(HSSFSheet sheet, int colnum) { + return null; + } } diff --git a/org.adempiere.base/src/org/adempiere/print/export/PrintDataExcelExporter.java b/org.adempiere.base/src/org/adempiere/print/export/PrintDataExcelExporter.java index 43e703b164..0be1716b35 100644 --- a/org.adempiere.base/src/org/adempiere/print/export/PrintDataExcelExporter.java +++ b/org.adempiere.base/src/org/adempiere/print/export/PrintDataExcelExporter.java @@ -37,7 +37,9 @@ import org.compiere.print.MPrintFormatItem; import org.compiere.print.MPrintPaper; import org.compiere.print.PrintData; import org.compiere.print.PrintDataElement; +import org.compiere.print.layout.PrintDataEvaluatee; import org.compiere.util.DisplayType; +import org.compiere.util.Evaluator; import org.compiere.util.Msg; import org.compiere.util.Util; @@ -50,12 +52,24 @@ import org.compiere.util.Util; public class PrintDataExcelExporter extends AbstractExcelExporter { + //constant for form rendering + private static final int COLUMN_WIDTH_DIVISOR = 64; + private static final int ROW_HEIGHT_DIVISOR = 20; + private PrintData m_printData; private MPrintFormat m_printFormat; private Map childPrintFormatDetails; private ArrayList columns; private MQuery m_query; + //variables for form rendering + private int m_previousFormRow = -1; + private int m_lastHeaderRow = -1; + private int m_firstHeaderRow = -1; + private int m_firstFooterRow = -1; + private int m_previousFormCol = -1; + private String m_previousAreaType = null; + public PrintDataExcelExporter(PrintData printData, MPrintFormat printFormat) { this(printData, printFormat, null, null); } @@ -156,6 +170,7 @@ extends AbstractExcelExporter PrintData printData = (PrintData)entry.getValue(); PrintDataExcelExporter exp =new PrintDataExcelExporter(printData, mPrintFormat); exp.exportToWorkbook(m_workbook, m_lang); + m_previousFormRow = m_workbook.getSheetAt(m_workbook.getNumberOfSheets()-1).getLastRowNum(); break; } } @@ -348,4 +363,174 @@ extends AbstractExcelExporter } } } + + @Override + protected boolean isForm() + { + return m_printFormat.isForm(); + } + + @Override + protected HSSFCell getFormCell(HSSFRow row, int colnum) { + HSSFCell cell = null; + if (colnum >= 0 && colnum < columns.size()) { + MPrintFormatItem item = (MPrintFormatItem) columns.get(colnum); + int previousCol = m_previousFormCol >= 0 ? m_previousFormCol : 0; + if (m_previousAreaType != null && !m_previousAreaType.equals(item.getPrintAreaType())) { + previousCol = 0; + } + if (item.isRelativePosition()) { + int offset = item.getXSpace() > 0 ? item.getXSpace() / COLUMN_WIDTH_DIVISOR : 0; + if (offset == 0 && item.getXSpace() > 0) + offset = 1; + int col = previousCol + offset; + cell = row.getCell(col); + if (cell == null) + cell = row.createCell(col); + } else { + int offset = item.getXPosition() > 0 ? item.getXPosition() / COLUMN_WIDTH_DIVISOR : 0; + cell = row.getCell(offset); + if (cell == null) + cell = row.createCell(offset); + } + if (cell != null) { + m_previousFormCol = cell.getColumnIndex(); + m_previousAreaType = item.getPrintAreaType(); + } + } + + return cell; + } + + @Override + protected HSSFRow getFormRow(HSSFSheet sheet, int colnum) { + HSSFRow row = null; + if (m_firstHeaderRow == -1) { + m_firstHeaderRow = sheet.getLastRowNum(); + } + if (colnum >= 0 && colnum < columns.size()) { + MPrintFormatItem item = (MPrintFormatItem) columns.get(colnum); + if (item.isRelativePosition()) { + int firstContentRow = m_lastHeaderRow >= 0 ? m_lastHeaderRow+1 : m_firstHeaderRow; + int relativeFrom = m_previousFormRow >= 0 ? m_previousFormRow : 0; + if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Content)) { + if (relativeFrom < firstContentRow) + relativeFrom = firstContentRow; + } else if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Footer)) { + if (relativeFrom < m_firstFooterRow) + relativeFrom = m_firstFooterRow; + else if (m_firstFooterRow==-1 && relativeFrom <= firstContentRow) + relativeFrom = firstContentRow + 1; + } + if (item.isNextLine()) { + int offset = 1; + row = sheet.getRow(relativeFrom+offset); + if (row == null) + row = sheet.createRow(relativeFrom+offset); + } else if (item.getYSpace() == 0) { + row = sheet.getRow(relativeFrom); + if (row == null) + row = sheet.createRow(relativeFrom); + } else { + int offset = (item.getYSpace() / ROW_HEIGHT_DIVISOR) + 1; + row = sheet.getRow(relativeFrom+offset); + if (row == null) + row = sheet.createRow(relativeFrom+offset); + } + m_previousFormRow = row.getRowNum(); + + if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Header)) { + if (row.getRowNum() > m_lastHeaderRow) { + m_lastHeaderRow = row.getRowNum(); + } + } + } else { + if (item.getYPosition() == 0) { + if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Header)) { + row = sheet.getRow(m_firstHeaderRow); + if (row.getRowNum() > m_lastHeaderRow) { + m_lastHeaderRow = row.getRowNum(); + } + } else if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Content)) { + if (m_lastHeaderRow >= 0) { + row = sheet.getRow(m_lastHeaderRow+1); + if (row == null) + row = sheet.createRow(m_lastHeaderRow+1); + } else { + row = sheet.getRow(m_firstHeaderRow); + } + } else if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Footer)) { + if (m_firstFooterRow >= 0) { + row = sheet.getRow(m_firstFooterRow); + } else { + row = sheet.getRow(sheet.getLastRowNum()+1); + if (row == null) + row = sheet.createRow(sheet.getLastRowNum()+1); + m_firstFooterRow = row.getRowNum(); + } + } + m_previousFormRow = row.getRowNum(); + } else { + int offset = item.getYPosition() / ROW_HEIGHT_DIVISOR; + if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Header)) { + row = sheet.getRow(m_firstHeaderRow+offset); + if (row == null) + row = sheet.createRow(m_firstHeaderRow+offset); + if (row.getRowNum() > m_lastHeaderRow) { + m_lastHeaderRow = row.getRowNum(); + } + } else if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Content)) { + int firstContentRow = m_lastHeaderRow >= 0 ? m_lastHeaderRow+1 : m_firstHeaderRow; + row = sheet.getRow(firstContentRow+offset); + if (row == null) + row = sheet.createRow(firstContentRow+offset); + } else if (item.getPrintAreaType().equals(MPrintFormatItem.PRINTAREATYPE_Footer)) { + if (m_firstFooterRow == -1) + m_firstFooterRow = sheet.getLastRowNum()+1; + row = sheet.getRow(m_firstFooterRow+offset); + if (row == null) + row = sheet.createRow(m_firstFooterRow+offset); + } + m_previousFormRow = row.getRowNum(); + } + } + } + return row; + } + + @Override + protected boolean isSetFormRowPosition(int col) { + Object value = col >= 0 && col < columns.size() ? columns.get(col) : null; + if (value instanceof MPrintFormatItem) { + MPrintFormatItem item = (MPrintFormatItem)value; + return item.isSetNLPosition(); + } + return super.isSetFormRowPosition(col); + } + + @Override + protected boolean isSuppressNull(int col) { + Object value = col >= 0 && col < columns.size() ? columns.get(col) : null; + if (value instanceof MPrintFormatItem) { + MPrintFormatItem item = (MPrintFormatItem)value; + return item.isSuppressNull(); + } + return super.isSuppressNull(col); + } + + @Override + protected boolean isVisible(int row, int col) { + Object value = col >= 0 && col < columns.size() ? columns.get(col) : null; + if (value instanceof MPrintFormatItem) { + MPrintFormatItem item = (MPrintFormatItem)value; + String displayLogic = item.getDisplayLogic(); + if (!Util.isEmpty(displayLogic, true)) { + if (m_printData.getRowIndex() != row) + m_printData.setRowIndex(row); + PrintDataEvaluatee evaluatee = new PrintDataEvaluatee(null, m_printData); + return Evaluator.evaluateLogic(evaluatee, displayLogic); + } + } + return super.isVisible(row, col); + } } diff --git a/org.adempiere.base/src/org/compiere/print/layout/PrintDataEvaluatee.java b/org.adempiere.base/src/org/compiere/print/layout/PrintDataEvaluatee.java index a8381ab981..cac55ce991 100644 --- a/org.adempiere.base/src/org/compiere/print/layout/PrintDataEvaluatee.java +++ b/org.adempiere.base/src/org/compiere/print/layout/PrintDataEvaluatee.java @@ -41,9 +41,9 @@ public class PrintDataEvaluatee implements Evaluatee { @Override public String get_ValueAsString(String variableName) { if (Page.CONTEXT_PAGE.equals(variableName)) { - return String.valueOf(m_page.getPageNo()); + return m_page != null ? String.valueOf(m_page.getPageNo()) : "1"; } else if (Page.CONTEXT_PAGECOUNT.equals(variableName)) { - return String.valueOf(m_page.getPageCount()); + return m_page != null ? String.valueOf(m_page.getPageCount()) : "1"; } //ref column