/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 2008 SC ARHIPAC SERVICE SRL. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * *****************************************************************************/ 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.List; import java.util.Map; import java.util.logging.Level; import javax.print.attribute.standard.MediaSizeName; import org.adempiere.impexp.AbstractExcelExporter; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFPrintSetup; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; 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.InstanceAttributeColumn; import org.compiere.print.layout.InstanceAttributeData; 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 (XLS) file * @author Teo Sarca, SC ARHIPAC SERVICE SRL *
  • BF [ 1939010 ] Excel Export ERROR - java.sql.Date - integrated Mario Grigioni's fix *
  • BF [ 1974309 ] Exporting a report to XLS is not setting page format */ 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; /** * @param printData * @param printFormat */ public PrintDataExcelExporter(PrintData printData, MPrintFormat printFormat) { this(printData, printFormat, null, null); } /** * @param printData * @param printFormat * @param childPrintFormatDetails * @param colSuppressRepeats */ public PrintDataExcelExporter(PrintData printData, MPrintFormat printFormat, Map childPrintFormatDetails, Boolean[] colSuppressRepeats) { this(printData, printFormat, childPrintFormatDetails, colSuppressRepeats, null); } /** * @param printData * @param printFormat * @param childPrintFormatDetails * @param colSuppressRepeats * @param query */ public PrintDataExcelExporter(PrintData printData, MPrintFormat printFormat, Map childPrintFormatDetails, Boolean[] colSuppressRepeats, MQuery query) { super(); this.m_printData = printData; this.m_printFormat = printFormat; this.childPrintFormatDetails = childPrintFormatDetails; this.colSuppressRepeats = colSuppressRepeats; this.m_query = query; } @Override public int getColumnCount() { return columns.size(); } /** * @param row * @param col * @return PrintDataElement for row and col or null */ private PrintDataElement getPDE(int row, int col) { if (m_printData.getRowIndex() != row) m_printData.setRowIndex(row); // Object colObj = columns.get(col); if (colObj instanceof InstanceAttributeColumn) { InstanceAttributeColumn ia = (InstanceAttributeColumn) colObj; return ia.getPrintDataElement(row); } else if (colObj instanceof MPrintFormatItem) { MPrintFormatItem item = (MPrintFormatItem) colObj; Object obj = null; if (item.isTypeField() || item.isTypePrintFormat() && item.isImageField()) { obj = m_printData.getNodeByPrintFormatItemId(item.getAD_PrintFormatItem_ID()); } /** DEVCOFFEE: script column **/ if (item.isTypeScript()) { obj = m_printData.getNodeByPrintFormatItemId(item.getAD_PrintFormatItem_ID()); } if (obj != null && obj instanceof PrintDataElement) { return (PrintDataElement)obj; } } return null; } @Override public int getDisplayType(int row, int col) { PrintDataElement pde = getPDE(row, col); if (pde != null) { return pde.getDisplayType(); } return -1; // } @Override public Object getValueAt(int row, int col) { PrintDataElement pde = getPDE(row, col); Object value = null; if (pde == null) ; else if (pde.isDate()) { Object o = pde.getValue(); if (o instanceof Date) value = new Timestamp(((Date)o).getTime()); else value = (Timestamp)pde.getValue(); } else if (pde.isNumeric()) { Object o = pde.getValue(); if (o instanceof Number) { value = ((Number)o).doubleValue(); } } else if (pde.isYesNo()) { value = pde.getValue(); } else if (pde.isPKey()) { value = pde.getValueAsString(); } else { 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(); PrintDataExcelExporter exp =new PrintDataExcelExporter(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) { Object colObj = columns.get(col); if (colObj instanceof MPrintFormatItem) { MPrintFormatItem item = (MPrintFormatItem) colObj; return item.getPrintName(getLanguage()); } else if (colObj instanceof InstanceAttributeColumn) { InstanceAttributeColumn ia = (InstanceAttributeColumn) colObj; return ia.getName(); } else { return ""; } } @Override public int getRowCount() { return m_printData.getRowCount(); } @Override public boolean isColumnPrinted(int col) { if (columns != null && col < columns.size()) return true; else return false; } @Override public boolean isPageBreak(int row, int col) { PrintDataElement pde = getPDE(row, col); return pde != null ? pde.isPageBreak() : false; } @Override protected void setCurrentRow(int row) { m_printData.setRowIndex(row); } @Override protected int getCurrentRow() { return m_printData.getRowIndex(); } @Override public boolean isFunctionRow() { return m_printData.isFunctionRow(); } @Override protected void formatPage(HSSFSheet sheet) { super.formatPage(sheet); MPrintPaper paper = MPrintPaper.get(this.m_printFormat.getAD_PrintPaper_ID()); // // Set paper size: short paperSize = -1; MediaSizeName mediaSizeName = paper.getMediaSize().getMediaSizeName(); if (MediaSizeName.NA_LETTER.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.LETTER_PAPERSIZE; } else if (MediaSizeName.NA_LEGAL.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.LEGAL_PAPERSIZE; } else if (MediaSizeName.EXECUTIVE.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.EXECUTIVE_PAPERSIZE; } else if (MediaSizeName.ISO_A4.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.A4_PAPERSIZE; } else if (MediaSizeName.ISO_A5.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.A5_PAPERSIZE; } else if (MediaSizeName.NA_NUMBER_10_ENVELOPE.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.ENVELOPE_10_PAPERSIZE; } else if (MediaSizeName.MONARCH_ENVELOPE.equals(mediaSizeName)) { paperSize = HSSFPrintSetup.ENVELOPE_MONARCH_PAPERSIZE; } if (paperSize != -1) { sheet.getPrintSetup().setPaperSize(paperSize); } // // Set Landscape/Portrait: 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); // } @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<>(); List asiElements = new ArrayList<>(); int columnCount = 0; for (int col = 0; col < m_printFormat.getItemCount(); col++) { MPrintFormatItem item = m_printFormat.getItem(col); if (item.isPrinted()) { if (item.isTypeField() && item.isPrintInstanceAttributes()) { InstanceAttributeData asiElement = new InstanceAttributeData(item, columnCount); asiElement.readAttributesData(m_printData); asiElements.add(asiElement); continue; } else { columns.add(item); columnCount++; } } } if (asiElements.size() > 0) { int columnCreated = 0; for(InstanceAttributeData data : asiElements) { List instanceColumns = data.getColumns(); int index = data.getColumnIndex() + columnCreated; for(InstanceAttributeColumn c : instanceColumns) { columns.add(index, c); index++; columnCreated++; } } } super.export(out); } @Override protected void createParameter(HSSFSheet 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); HSSFCellStyle parameterStyle = m_workbook.createCellStyle(); HSSFFont 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++) { HSSFRow row = sheet.createRow(r); if (r == 0) { HSSFCell cell = row.createCell(0); HSSFCellStyle style = m_workbook.createCellStyle(); HSSFFont font = m_workbook.createFont(); font.setBold(true); style.setFont(font); cell.setCellStyle(style); String value = Util.stripDiacritics(Msg.getMsg(getCtx(), "Parameter") + ":"); cell.setCellValue(new HSSFRichTextString(value)); } HSSFCell cell = row.createCell(1); cell.setCellStyle(parameterStyle); String value = Util.stripDiacritics(query.getInfoName(r)); cell.setCellValue(new HSSFRichTextString(value)); cell = row.createCell(2); cell.setCellStyle(parameterStyle); value = Util.stripDiacritics(query.getInfoOperator(r)); cell.setCellValue(new HSSFRichTextString(value)); cell = row.createCell(3); cell.setCellStyle(parameterStyle); value = Util.stripDiacritics(query.getInfoDisplayAll(r)); cell.setCellValue(new HSSFRichTextString(value)); } } } } } @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); } @Override public boolean isDisplayed(int row, int col) { if (m_printData.getRowIndex() != row) m_printData.setRowIndex(row); Object colobj = columns.get(col); MPrintFormatItem item = colobj instanceof InstanceAttributeColumn ? ((InstanceAttributeColumn)colobj).getPrintFormatItem() : (MPrintFormatItem)colobj; if (Util.isEmpty(item.getDisplayLogic())) return true; return Evaluator.evaluateLogic(new PrintDataEvaluatee(null, m_printData), item.getDisplayLogic()); } }