From d832d1f352f2188198b03179d7574b1d4859935f Mon Sep 17 00:00:00 2001 From: hengsin Date: Sat, 19 Jun 2021 04:22:36 +0800 Subject: [PATCH] IDEMPIERE-4565 Report (XLSX output) : add header (#729) sync xls and xlsx output --- .../impexp/AbstractXLSXExporter.java | 205 +++++++-- .../print/export/PrintDataXLSXExporter.java | 389 +++++++++++++++++- .../src/org/compiere/print/ReportEngine.java | 3 +- 3 files changed, 546 insertions(+), 51 deletions(-) diff --git a/org.adempiere.base/src/org/adempiere/impexp/AbstractXLSXExporter.java b/org.adempiere.base/src/org/adempiere/impexp/AbstractXLSXExporter.java index 5663ca3440..9f586fe839 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/AbstractXLSXExporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/AbstractXLSXExporter.java @@ -15,6 +15,7 @@ package org.adempiere.impexp; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; +import java.sql.Date; import java.sql.Timestamp; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -23,8 +24,6 @@ import java.util.HashMap; import java.util.Properties; import java.util.logging.Level; -import org.apache.poi.hssf.usermodel.HSSFDataFormat; -import org.apache.poi.hssf.usermodel.HSSFHeader; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Footer; import org.apache.poi.ss.usermodel.Header; @@ -141,11 +140,11 @@ public abstract class AbstractXLSXExporter /** Logger */ protected final CLogger log = CLogger.getCLogger(getClass()); // - private XSSFWorkbook m_workbook; + protected XSSFWorkbook m_workbook; private XSSFDataFormat m_dataFormat; private XSSFFont m_fontHeader = null; private XSSFFont m_fontDefault = null; - private Language m_lang = null; + protected Language m_lang = null; private int m_sheetCount = 0; // private int m_colSplit = 1; @@ -155,6 +154,7 @@ public abstract class AbstractXLSXExporter private HashMap m_styles = new HashMap(); protected Boolean[] colSuppressRepeats; + private int noOfParameter = 0; public AbstractXLSXExporter() { @@ -269,7 +269,6 @@ public abstract class AbstractXLSXExporter XSSFCellStyle cs = m_styles.get(key); if (cs == null) { - boolean isHighlightNegativeNumbers = true; cs = m_workbook.createCellStyle(); XSSFFont font = getFont(false); cs.setFont(font); @@ -279,21 +278,29 @@ public abstract class AbstractXLSXExporter cs.setBorderRight(BorderStyle.THIN); cs.setBorderBottom(BorderStyle.THIN); // - if (DisplayType.isDate(displayType)) - { - cs.setDataFormat(m_dataFormat.getFormat(DisplayType.getDateFormat(getLanguage()).toPattern())); - } - else if (DisplayType.isNumeric(displayType)) - { - DecimalFormat df = DisplayType.getNumberFormat(displayType, getLanguage()); - String format = getFormatString(df, isHighlightNegativeNumbers); - cs.setDataFormat(m_dataFormat.getFormat(format)); - } + String cellFormat = getCellFormat(row, col); + if (cellFormat != null) + cs.setDataFormat(m_dataFormat.getFormat(cellFormat)); m_styles.put(key, cs); } return cs; } + protected String getCellFormat(int row, int col) { + boolean isHighlightNegativeNumbers = true; + int displayType = getDisplayType(row, col); + String cellFormat = null; + + if (DisplayType.isDate(displayType)) { + cellFormat = DisplayType.getDateFormat(getLanguage()).toPattern(); + } else if (DisplayType.isNumeric(displayType)) { + DecimalFormat df = DisplayType.getNumberFormat(displayType, getLanguage()); + cellFormat = getFormatString(df, isHighlightNegativeNumbers); + } + + return cellFormat; + } + private XSSFCellStyle getHeaderStyle(int col) { String key = "header-" + col; @@ -307,7 +314,7 @@ public abstract class AbstractXLSXExporter cs_header.setBorderTop(BorderStyle.MEDIUM); cs_header.setBorderRight(BorderStyle.MEDIUM); cs_header.setBorderBottom(BorderStyle.MEDIUM); - cs_header.setDataFormat(HSSFDataFormat.getBuiltinFormat("text")); + cs_header.setDataFormat(m_workbook.createDataFormat().getFormat("text")); cs_header.setWrapText(true); m_styles.put(key, cs_header); } @@ -328,7 +335,7 @@ public abstract class AbstractXLSXExporter 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) { @@ -349,17 +356,26 @@ public abstract class AbstractXLSXExporter XSSFSheet sheet = m_workbook.createSheet(); formatPage(sheet); createHeaderFooter(sheet); - createTableHeader(sheet); + createParameter(sheet); + if (!isForm()) + { + createTableHeader(sheet); + } m_sheetCount++; // return sheet; } private void createTableHeader(XSSFSheet sheet) + { + createTableHeader(sheet, Math.max(noOfParameter, 0)); + } + + private void createTableHeader(XSSFSheet sheet, int headerRowNum) { int colnumMax = 0; - XSSFRow row = sheet.createRow(0); + XSSFRow row = sheet.createRow(headerRowNum); // for all columns int colnum = 0; for (int col = 0; col < getColumnCount(); col++) @@ -384,7 +400,9 @@ public abstract class AbstractXLSXExporter { // Sheet Header Header header = sheet.getHeader(); - header.setRight(HSSFHeader.page() + " / " + HSSFHeader.numPages()); + //&P == current page number + //&N == page numbers + header.setRight("&P / &N"); // Sheet Footer Footer footer = sheet.getFooter(); footer.setLeft(Env.getStandardReportFooterTrademarkText()); @@ -428,9 +446,19 @@ public abstract class AbstractXLSXExporter * @param out * @throws Exception */ - private void export(OutputStream out) throws Exception + protected void export(OutputStream out) throws Exception { - XSSFSheet sheet = createTableSheet(); + XSSFSheet 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; @@ -443,7 +471,13 @@ public abstract class AbstractXLSXExporter preValues = new Object[colSuppressRepeats.length]; } - for (int xls_rownum = 1; rownum < lastRowNum; rownum++, xls_rownum++) + 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++) { if (!isCurrentRowOnly()) setCurrentRow(rownum); @@ -461,10 +495,35 @@ public abstract class AbstractXLSXExporter if (isColumnPrinted(col)) { printColIndex++; - XSSFCell cell = row.createCell(colnum); - + XSSFCell 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 XSSFRichTextString(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 || !isDisplayed(rownum, col)) { @@ -478,9 +537,17 @@ public abstract class AbstractXLSXExporter { // suppress } + else if (!isVisible(rownum, col)) + { + ; + } else if (DisplayType.isDate(displayType)) { - Timestamp value = (Timestamp) obj; + Timestamp value = null; + if (obj instanceof Date) + value = new Timestamp(((Date)obj).getTime()); + else + value = (Timestamp)obj; cell.setCellValue(value); } else if (DisplayType.isNumeric(displayType)) @@ -507,8 +574,13 @@ public abstract class AbstractXLSXExporter cell.setCellValue(new XSSFRichTextString(value)); } // - XSSFCellStyle style = getStyle(rownum, col); - cell.setCellStyle(style); + if (cell != null) + { + XSSFCellStyle style = getStyle(rownum, col); + if (isForm()) + style.setWrapText(true); + cell.setCellStyle(style); + } // Page break if (isPageBreak(rownum, col)) { @@ -531,7 +603,10 @@ public abstract class AbstractXLSXExporter isPageBreak = false; } } // for all rows - closeTableSheet(sheet, sheetName, colnumMax); + if (out == null) + fixColumnWidth(sheet, colnumMax); + else + closeTableSheet(sheet, sheetName, colnumMax); // if (out != null) @@ -586,4 +661,76 @@ public abstract class AbstractXLSXExporter m_workbook = workbook; export(null); } + + /** + * @return true if it is form layout + */ + protected boolean isForm() + { + return false; + } + + protected int getNoOfParameter() + { + return noOfParameter; + } + + protected void setNoOfParameter(int noOfParameter) + { + this.noOfParameter = noOfParameter; + } + + protected void createParameter(XSSFSheet sheet) + { + + } + + /** + * + * @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 XSSFCell getFormCell(XSSFRow row, int colnum) { + return null; + } + + /** + * get row for column. use for form layout + * @param sheet + * @param colnum + * @return row for column + */ + protected XSSFRow getFormRow(XSSFSheet sheet, int colnum) { + return null; + } } diff --git a/org.adempiere.base/src/org/adempiere/print/export/PrintDataXLSXExporter.java b/org.adempiere.base/src/org/adempiere/print/export/PrintDataXLSXExporter.java index 68c4192d7f..2735c592be 100644 --- a/org.adempiere.base/src/org/adempiere/print/export/PrintDataXLSXExporter.java +++ b/org.adempiere.base/src/org/adempiere/print/export/PrintDataXLSXExporter.java @@ -12,23 +12,36 @@ *****************************************************************************/ package org.adempiere.print.export; +import java.io.OutputStream; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.logging.Level; import javax.print.attribute.standard.MediaSizeName; import org.adempiere.impexp.AbstractXLSXExporter; -import org.apache.poi.hssf.usermodel.HSSFPrintSetup; -import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFPrintSetup; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.compiere.model.MQuery; import org.compiere.print.MPrintFormat; 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; + /** * Export PrintData to Excel (XLSX) file * @@ -36,21 +49,48 @@ import org.compiere.util.Util; */ public class PrintDataXLSXExporter extends AbstractXLSXExporter { + //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 PrintDataXLSXExporter(PrintData printData, MPrintFormat printFormat) + { + this(printData, printFormat, null); + } + public PrintDataXLSXExporter(PrintData printData, MPrintFormat printFormat, Boolean[] colSuppressRepeats) + { + this(printData, printFormat, null, colSuppressRepeats, null); + } + + public PrintDataXLSXExporter(PrintData printData, MPrintFormat printFormat, Map childPrintFormatDetails, Boolean[] colSuppressRepeats, MQuery query) { super(); this.m_printData = printData; this.m_printFormat = printFormat; this.colSuppressRepeats = colSuppressRepeats; + this.childPrintFormatDetails = childPrintFormatDetails; + this.m_query = query; } @Override public int getColumnCount() { - return m_printFormat.getItemCount(); + return columns.size(); } private PrintDataElement getPDE(int row, int col) @@ -58,11 +98,22 @@ public class PrintDataXLSXExporter extends AbstractXLSXExporter if (m_printData.getRowIndex() != row) m_printData.setRowIndex(row); // - MPrintFormatItem item = m_printFormat.getItem(col); - int AD_Column_ID = item.getAD_Column_ID(); + MPrintFormatItem item = (MPrintFormatItem) columns.get(col); Object obj = null; - if (AD_Column_ID > 0) - obj = m_printData.getNode(Integer.valueOf(AD_Column_ID)); + + if (item.isTypeField() || item.isTypePrintFormat() && item.isImageField()) + { + int AD_Column_ID = item.getAD_Column_ID(); + if (AD_Column_ID > 0) + obj = m_printData.getNode(Integer.valueOf(AD_Column_ID)); + } + + /** DEVCOFFEE: script column **/ + if (item.isTypeScript()) + { + obj = m_printData.getNode(item.getName()); + } + if (obj != null && obj instanceof PrintDataElement) { return (PrintDataElement) obj; @@ -118,13 +169,52 @@ public class PrintDataXLSXExporter extends AbstractXLSXExporter value = pde.getValueDisplay(getLanguage()); } // + MPrintFormatItem item = null; + Object colObj = columns.get(col); + if (colObj instanceof MPrintFormatItem) + item = (MPrintFormatItem) colObj; + if(item != null && item.getAD_PrintFormatChild_ID()!=0) + { + MPrintFormat mPrintFormat = null; + + if(childPrintFormatDetails!=null) + { + for (Iterator> iter = childPrintFormatDetails.entrySet().iterator(); iter.hasNext();) + { + try { + Map.Entry entry = (Map.Entry) iter.next(); + MPrintFormatItem mPrintFormatItem = (MPrintFormatItem)entry.getKey(); + if (mPrintFormatItem.equals(item)) + { + mPrintFormat = new MPrintFormat(getCtx(), mPrintFormatItem.getAD_PrintFormatChild_ID(), null); + PrintData printData = (PrintData)entry.getValue(); + PrintDataXLSXExporter exp =new PrintDataXLSXExporter(printData, mPrintFormat); + exp.exportToWorkbook(m_workbook, m_lang); + m_previousFormRow = m_workbook.getSheetAt(m_workbook.getNumberOfSheets()-1).getLastRowNum(); + break; + } + } + catch(Exception ex) + { + log.log(Level.WARNING, ex.getMessage(), ex); + break; + } + } + } + } return value; } @Override public String getHeaderName(int col) { - return m_printFormat.getItem(col).getPrintName(getLanguage()); + Object colObj = columns.get(col); + if (colObj instanceof MPrintFormatItem) { + MPrintFormatItem item = (MPrintFormatItem) colObj; + return item.getPrintName(getLanguage()); + } else { + return ""; + } } @Override @@ -136,8 +226,10 @@ public class PrintDataXLSXExporter extends AbstractXLSXExporter @Override public boolean isColumnPrinted(int col) { - MPrintFormatItem item = m_printFormat.getItem(col); - return item.isPrinted(); + if (columns != null && col < columns.size()) + return true; + else + return false; } @Override @@ -175,31 +267,31 @@ public class PrintDataXLSXExporter extends AbstractXLSXExporter MediaSizeName mediaSizeName = paper.getMediaSize().getMediaSizeName(); if (MediaSizeName.NA_LETTER.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.LETTER_PAPERSIZE; + paperSize = XSSFPrintSetup.LETTER_PAPERSIZE; } else if (MediaSizeName.NA_LEGAL.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.LEGAL_PAPERSIZE; + paperSize = XSSFPrintSetup.LEGAL_PAPERSIZE; } else if (MediaSizeName.EXECUTIVE.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.EXECUTIVE_PAPERSIZE; + paperSize = XSSFPrintSetup.EXECUTIVE_PAPERSIZE; } else if (MediaSizeName.ISO_A4.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.A4_PAPERSIZE; + paperSize = XSSFPrintSetup.A4_PAPERSIZE; } else if (MediaSizeName.ISO_A5.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.A5_PAPERSIZE; + paperSize = XSSFPrintSetup.A5_PAPERSIZE; } else if (MediaSizeName.NA_NUMBER_10_ENVELOPE.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.ENVELOPE_10_PAPERSIZE; + paperSize = XSSFPrintSetup.ENVELOPE_10_PAPERSIZE; } else if (MediaSizeName.MONARCH_ENVELOPE.equals(mediaSizeName)) { - paperSize = HSSFPrintSetup.ENVELOPE_MONARCH_PAPERSIZE; + paperSize = XSSFPrintSetup.ENVELOPE_MONARCH_PAPERSIZE; } if (paperSize != -1) { @@ -210,10 +302,10 @@ public class PrintDataXLSXExporter extends AbstractXLSXExporter sheet.getPrintSetup().setLandscape(paper.isLandscape()); // Set Paper Margin: - sheet.setMargin(HSSFSheet.TopMargin, ((double) paper.getMarginTop()) / 72); - sheet.setMargin(HSSFSheet.RightMargin, ((double) paper.getMarginRight()) / 72); - sheet.setMargin(HSSFSheet.LeftMargin, ((double) paper.getMarginLeft()) / 72); - sheet.setMargin(HSSFSheet.BottomMargin, ((double) paper.getMarginBottom()) / 72); + sheet.setMargin(XSSFSheet.TopMargin, ((double) paper.getMarginTop()) / 72); + sheet.setMargin(XSSFSheet.RightMargin, ((double) paper.getMarginRight()) / 72); + sheet.setMargin(XSSFSheet.LeftMargin, ((double) paper.getMarginLeft()) / 72); + sheet.setMargin(XSSFSheet.BottomMargin, ((double) paper.getMarginBottom()) / 72); } @@ -229,4 +321,259 @@ public class PrintDataXLSXExporter extends AbstractXLSXExporter return Evaluator.evaluateLogic(new PrintDataEvaluatee(null, m_printData), item.getDisplayLogic()); } + + @Override + protected String getCellFormat(int row, int col) { + String cellFormat = null; + PrintDataElement pde = getPDE(row, col); + + if (pde != null && !Util.isEmpty(pde.getM_formatPattern())) { + String formatPattern = pde.getM_formatPattern(); + int displayType = pde.getDisplayType(); + if (DisplayType.isDate(displayType)) { + cellFormat = DisplayType.getDateFormat(displayType, getLanguage(), formatPattern).toPattern(); + } else if (DisplayType.isNumeric(displayType)) { + cellFormat = DisplayType.getNumberFormat(displayType, getLanguage(), formatPattern).toPattern(); + } + } else { + return super.getCellFormat(row, col); + } + + return cellFormat; + } + + @Override + protected void export(OutputStream out) throws Exception { + columns = new ArrayList<>(); + for (int col = 0; col < m_printFormat.getItemCount(); col++) + { + MPrintFormatItem item = m_printFormat.getItem(col); + if (item.isPrinted()) + { + columns.add(item); + } + } + + super.export(out); + } + + @Override + protected void createParameter(XSSFSheet sheet) { + if (!m_printFormat.isForm()) { + if (m_query != null && m_query.isActive()) { + int rows = m_query.getReportProcessQuery() != null ? m_query.getReportProcessQuery().getRestrictionCount() : m_query.getRestrictionCount(); + if (rows > 0) { + setNoOfParameter(rows); + setFreezePane(1, rows + 1); + + XSSFCellStyle parameterStyle = m_workbook.createCellStyle(); + XSSFFont parameterFont = m_workbook.createFont(); + parameterFont.setItalic(true); + parameterStyle.setFont(parameterFont); + + MQuery query = m_query; + if (m_query.getReportProcessQuery() != null) + query = m_query.getReportProcessQuery(); + for (int r = 0; r < query.getRestrictionCount(); r++) + { + XSSFRow row = sheet.createRow(r); + if (r == 0) { + XSSFCell cell = row.createCell(0); + XSSFCellStyle style = m_workbook.createCellStyle(); + XSSFFont font = m_workbook.createFont(); + font.setBold(true); + style.setFont(font); + cell.setCellStyle(style); + String value = Util.stripDiacritics(Msg.getMsg(getCtx(), "Parameter") + ":"); + cell.setCellValue(new XSSFRichTextString(value)); + } + XSSFCell cell = row.createCell(1); + cell.setCellStyle(parameterStyle); + String value = Util.stripDiacritics(query.getInfoName(r)); + cell.setCellValue(new XSSFRichTextString(value)); + + cell = row.createCell(2); + cell.setCellStyle(parameterStyle); + value = Util.stripDiacritics(query.getInfoOperator(r)); + cell.setCellValue(new XSSFRichTextString(value)); + + cell = row.createCell(3); + cell.setCellStyle(parameterStyle); + value = Util.stripDiacritics(query.getInfoDisplayAll(r)); + cell.setCellValue(new XSSFRichTextString(value)); + } + } + } + } + } + + @Override + protected boolean isForm() + { + return m_printFormat.isForm(); + } + + @Override + protected XSSFCell getFormCell(XSSFRow row, int colnum) { + XSSFCell 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 XSSFRow getFormRow(XSSFSheet sheet, int colnum) { + XSSFRow 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/ReportEngine.java b/org.adempiere.base/src/org/compiere/print/ReportEngine.java index 2e545d6087..5613cea3f8 100644 --- a/org.adempiere.base/src/org/compiere/print/ReportEngine.java +++ b/org.adempiere.base/src/org/compiere/print/ReportEngine.java @@ -1553,7 +1553,8 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) throws Exception { Boolean [] colSuppressRepeats = m_layout == null || m_layout.colSuppressRepeats == null? LayoutEngine.getColSuppressRepeats(m_printFormat):m_layout.colSuppressRepeats; - PrintDataXLSXExporter exp = new PrintDataXLSXExporter(getPrintData(), getPrintFormat(), colSuppressRepeats); + Map childFormats = m_layout != null ? m_layout.getChildPrintFormatDetails() : null; + PrintDataXLSXExporter exp = new PrintDataXLSXExporter(getPrintData(), getPrintFormat(), childFormats, colSuppressRepeats, m_query); exp.export(outFile, language); }