IDEMPIERE-2924 Export to XLS limited to 65536

* Complete ticket - implement support for XLSX in scheduler, background jobs, jasper reporting, default types
* Synchronize xlsx with xls exporter to use ZK_FOOTER_SERVER_MSG and ZK_FOOTER_SERVER_DATETIME_FORMAT SysConfig
* Excel alerts now export to xlsx instead of xls
This commit is contained in:
Carlos Ruiz 2020-01-04 17:26:00 +01:00
parent 503ca8eb62
commit 21eb285e5b
14 changed files with 195 additions and 15 deletions

View File

@ -0,0 +1,27 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-2924 Export to XLS limited to 65536
-- Jan 4, 2020, 3:56:13 PM CET
UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type form, possible values are PDF, HTML, XLS, CSV, XLSX',Updated=TO_DATE('2020-01-04 15:56:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200002
;
-- Jan 4, 2020, 3:56:18 PM CET
UPDATE AD_SysConfig SET Description='Type of output in zkwebui for jasper reports, possible values are PDF, HTML, XLS, CSV, SSV, XLSX',Updated=TO_DATE('2020-01-04 15:56:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200030
;
-- Jan 4, 2020, 3:56:21 PM CET
UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type table, possible values are PDF, HTML, XLS, CSV, XLSX',Updated=TO_DATE('2020-01-04 15:56:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200003
;
-- Jan 4, 2020, 4:09:08 PM CET
UPDATE AD_Ref_List SET Name='XLS',Updated=TO_DATE('2020-01-04 16:09:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=200472
;
-- Jan 4, 2020, 4:09:17 PM CET
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200491,'XLSX',200169,'XLSX',0,0,'Y',TO_DATE('2020-01-04 16:09:16','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-01-04 16:09:16','YYYY-MM-DD HH24:MI:SS'),100,'D','2ebce9b0-ffa1-429d-aa8e-42be54bc161b')
;
SELECT register_migration_script('202001041556_IDEMPIERE-2924.sql') FROM dual
;

View File

@ -0,0 +1,24 @@
-- IDEMPIERE-2924 Export to XLS limited to 65536
-- Jan 4, 2020, 3:56:13 PM CET
UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type form, possible values are PDF, HTML, XLS, CSV, XLSX',Updated=TO_TIMESTAMP('2020-01-04 15:56:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200002
;
-- Jan 4, 2020, 3:56:18 PM CET
UPDATE AD_SysConfig SET Description='Type of output in zkwebui for jasper reports, possible values are PDF, HTML, XLS, CSV, SSV, XLSX',Updated=TO_TIMESTAMP('2020-01-04 15:56:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200030
;
-- Jan 4, 2020, 3:56:21 PM CET
UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type table, possible values are PDF, HTML, XLS, CSV, XLSX',Updated=TO_TIMESTAMP('2020-01-04 15:56:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200003
;
-- Jan 4, 2020, 4:09:08 PM CET
UPDATE AD_Ref_List SET Name='XLS',Updated=TO_TIMESTAMP('2020-01-04 16:09:08','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Ref_List_ID=200472
;
-- Jan 4, 2020, 4:09:17 PM CET
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200491,'XLSX',200169,'XLSX',0,0,'Y',TO_TIMESTAMP('2020-01-04 16:09:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-01-04 16:09:16','YYYY-MM-DD HH24:MI:SS'),100,'D','2ebce9b0-ffa1-429d-aa8e-42be54bc161b')
;
SELECT register_migration_script('202001041556_IDEMPIERE-2924.sql') FROM dual
;

View File

@ -18,6 +18,7 @@ import java.io.OutputStream;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.Level;
@ -36,6 +37,7 @@ import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.compiere.model.MSysConfig;
import org.compiere.util.CLogger;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
@ -377,8 +379,16 @@ public abstract class AbstractXLSXExporter
// Sheet Footer
Footer footer = sheet.getFooter();
footer.setLeft(Env.getStandardReportFooterTrademarkText());
String s = MSysConfig.getValue(MSysConfig.ZK_FOOTER_SERVER_MSG, "", Env.getAD_Client_ID(Env.getCtx()));
if (Util.isEmpty(s, true))
footer.setCenter(Env.getHeader(getCtx(), 0));
else
footer.setCenter(Msg.parseTranslation(Env.getCtx(), s));
Timestamp now = new Timestamp(System.currentTimeMillis());
s = MSysConfig.getValue(MSysConfig.ZK_FOOTER_SERVER_DATETIME_FORMAT, Env.getAD_Client_ID(Env.getCtx()));
if (!Util.isEmpty(s, true))
footer.setRight(new SimpleDateFormat(s).format(System.currentTimeMillis()));
else
footer.setRight(DisplayType.getDateFormat(DisplayType.DateTime, getLanguage()).format(now));
}

View File

@ -26,7 +26,7 @@ import org.compiere.util.Util;
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
*
*/
public class ArrayExcelExporter extends AbstractExcelExporter {
public class ArrayExcelExporter extends AbstractXLSXExporter {
private Properties m_ctx = null;
private ArrayList<ArrayList<Object>> m_data = null;

View File

@ -31,7 +31,7 @@ public class X_AD_Scheduler extends PO implements I_AD_Scheduler, I_Persistent
/**
*
*/
private static final long serialVersionUID = 20191121L;
private static final long serialVersionUID = 20200104L;
/** Standard Constructor */
public X_AD_Scheduler (Properties ctx, int AD_Scheduler_ID, String trxName)
@ -369,10 +369,12 @@ public class X_AD_Scheduler extends PO implements I_AD_Scheduler, I_Persistent
public static final String REPORTOUTPUTTYPE_PDF = "PDF";
/** HTML = HTML */
public static final String REPORTOUTPUTTYPE_HTML = "HTML";
/** Excel = XLS */
public static final String REPORTOUTPUTTYPE_Excel = "XLS";
/** XLS = XLS */
public static final String REPORTOUTPUTTYPE_XLS = "XLS";
/** CSV = CSV */
public static final String REPORTOUTPUTTYPE_CSV = "CSV";
/** XLSX = XLSX */
public static final String REPORTOUTPUTTYPE_XLSX = "XLSX";
/** Set Report Output Type.
@param ReportOutputType Report Output Type */
public void setReportOutputType (String ReportOutputType)

View File

@ -1322,6 +1322,44 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount)
}
} // getXLS
/**************************************************************************
* Create XLSX file.
* (created in temporary storage)
* @return XLSX file
*/
public File getXLSX()
{
return getXLSX(null);
} // getXLSX
/**
* Create XLSX file.
* @param file file
* @return XLSX file
*/
public File getXLSX(File file)
{
try
{
if (file == null)
file = File.createTempFile (makePrefix(getName()), ".xlsx");
}
catch (IOException e)
{
log.log(Level.SEVERE, "", e);
}
try
{
createXLSX(file, Env.getLanguage(getCtx()));
return file;
}
catch (Exception e)
{
log.log(Level.SEVERE, "", e);
return null;
}
} // getXLSX
/**
* Create PDF File
* @param file file

View File

@ -112,6 +112,12 @@ public class ServerReportCtl {
pi.setExportFileExtension("xls");
pi.setExportFile(re.getXLS());
}
else if ("XLSX".equals(pi.getReportType()))
{
pi.setExport(true);
pi.setExportFileExtension("xlsx");
pi.setExportFile(re.getXLSX());
}
else
{
pi.setPDFReport(re.getPDF());
@ -303,6 +309,12 @@ public class ServerReportCtl {
pi.setExportFileExtension("xls");
pi.setExportFile(re.getXLS());
}
else if ("XLSX".equals(pi.getReportType()))
{
pi.setExport(true);
pi.setExportFileExtension("xlsx");
pi.setExportFile(re.getXLSX());
}
else
{
pi.setPDFReport(re.getPDF());
@ -345,6 +357,12 @@ public class ServerReportCtl {
pi.setExportFileExtension("xls");
pi.setExportFile(re.getXLS());
}
else if ("XLSX".equals(pi.getReportType()))
{
pi.setExport(true);
pi.setExportFileExtension("xlsx");
pi.setExportFile(re.getXLSX());
}
else
{
pi.setPDFReport(re.getPDF());
@ -403,6 +421,12 @@ public class ServerReportCtl {
pi.setExportFileExtension("xls");
pi.setExportFile(re.getXLS());
}
else if ("XLSX".equals(pi.getReportType()))
{
pi.setExport(true);
pi.setExportFileExtension("xlsx");
pi.setExportFile(re.getXLSX());
}
else
{
pi.setPDFReport(re.getPDF());

View File

@ -95,6 +95,7 @@ import net.sf.jasperreports.engine.export.JRPrintServiceExporter;
import net.sf.jasperreports.engine.export.JRTextExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.fill.JRBaseFiller;
import net.sf.jasperreports.engine.fill.JRFiller;
import net.sf.jasperreports.engine.fill.JRSwapFileVirtualizer;
@ -116,6 +117,7 @@ import net.sf.jasperreports.export.SimplePrintServiceExporterConfiguration;
import net.sf.jasperreports.export.SimpleTextExporterConfiguration;
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;
import net.sf.jasperreports.export.SimpleXmlExporterOutput;
/**
@ -810,6 +812,14 @@ public class ReportStarter implements ProcessCall, ClientProcess
exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(strm));
exporterXLS.setConfiguration(xlsConfig);
exporter = exporterXLS;
} else if (ext.equals("xlsx")) {
JRXlsxExporter exporterXLSX = new JRXlsxExporter(jasperContext);
SimpleXlsxReportConfiguration xlsxConfig = new SimpleXlsxReportConfiguration();
xlsxConfig.setOnePagePerSheet(false);
exporterXLSX.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
exporterXLSX.setExporterOutput(new SimpleOutputStreamExporterOutput(strm));
exporterXLSX.setConfiguration(xlsxConfig);
exporter = exporterXLSX;
} else {
log.severe("FileInvalidExtension="+ext);
strm.close();

View File

@ -440,7 +440,7 @@ public class AlertProcessor extends AdempiereServer
if (data.size() <= 1)
return null;
// File
File file = rule.createReportFile("xls");
File file = rule.createReportFile("xlsx");
//
ArrayExcelExporter exporter = new ArrayExcelExporter(getCtx(), data);
exporter.export(file, language, false);

View File

@ -195,6 +195,8 @@ public class Scheduler extends AdempiereServer
pi.setExportFileExtension("csv");
else if ("XLS".equals(pi.getReportType()))
pi.setExportFileExtension("xls");
else if ("XLSX".equals(pi.getReportType()))
pi.setExportFileExtension("xlsx");
else
pi.setExportFileExtension("pdf");
}

View File

@ -20,6 +20,7 @@ Import-Package: groovy.transform.stc;version="2.4.7",
javax.xml.bind;version="2.3.0",
net.sf.jasperreports.engine,
net.sf.jasperreports.engine.export,
net.sf.jasperreports.engine.export.ooxml,
net.sf.jasperreports.engine.util,
net.sf.jasperreports.export,
org.adempiere.report.jasper,

View File

@ -107,7 +107,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
/**
*
*/
private static final long serialVersionUID = 8232462327114180974L;
private static final long serialVersionUID = -9220870163215609274L;
private static final String ON_COMPLETE = "onComplete";
private static final String ON_STATUS_UPDATE = "onStatusUpdate";
@ -611,8 +611,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
if (m_isCanExport)
{
freportType.appendItem("Excel", "XLS");
freportType.appendItem("XLS", "XLS");
freportType.appendItem("CSV", "CSV");
freportType.appendItem("XLSX", "XLSX");
}
freportType.setSelectedIndex(-1);
}
@ -1211,6 +1212,8 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI
m_pi.setExportFileExtension("csv");
else if ("XLS".equals(m_pi.getReportType()))
m_pi.setExportFileExtension("xls");
else if ("XLSX".equals(m_pi.getReportType()))
m_pi.setExportFileExtension("xlsx");
else
m_pi.setExportFileExtension("pdf");
}

View File

@ -63,6 +63,7 @@ import net.sf.jasperreports.engine.export.HtmlExporter;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.export.SimpleCsvExporterConfiguration;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
@ -70,12 +71,13 @@ import net.sf.jasperreports.export.SimpleHtmlReportConfiguration;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
import net.sf.jasperreports.export.SimpleXlsReportConfiguration;
import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;
public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCloseHandler {
/**
*
*/
private static final long serialVersionUID = -7047317766671393738L;
private static final long serialVersionUID = -812700088629098149L;
private JasperPrint jasperPrint;
private java.util.List<JasperPrint> jasperPrintList;
@ -161,9 +163,10 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
if (isCanExport) {
previewType.appendItem("PDF", "PDF");
previewType.appendItem("HTML", "HTML");
previewType.appendItem("Excel", "XLS");
previewType.appendItem("XLS", "XLS");
previewType.appendItem("CSV", "CSV");
previewType.appendItem("SSV", "SSV");
previewType.appendItem("XLSX", "XLSX");
if ("PDF".equals(defaultType)) {
previewType.setSelectedIndex(0);
} else if ("HTML".equals(defaultType)) {
@ -174,6 +177,8 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
previewType.setSelectedIndex(3);
} else if ("SSV".equals(defaultType)) {
previewType.setSelectedIndex(4);
} else if ("XLSX".equals(defaultType)) {
previewType.setSelectedIndex(5);
} else {
previewType.setSelectedIndex(0);
log.info("Format not Valid: "+defaultType);
@ -191,6 +196,8 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
previewType.setSelectedIndex(0); // default to PDF if cannot export
} else if ("SSV".equals(defaultType)) {
previewType.setSelectedIndex(0); // default to PDF if cannot export
} else if ("XLSX".equals(defaultType)) {
previewType.setSelectedIndex(0); // default to PDF if cannot export
} else {
previewType.setSelectedIndex(0);
log.info("Format not Valid: "+defaultType);
@ -403,6 +410,34 @@ public class ZkJRViewer extends Window implements EventListener<Event>, ITabOnCl
exporterXLS.exportReport();
media = new AMedia(m_title + ".xls", "xls", "application/vnd.ms-excel", file, true);
} else if ("XLSX".equals(reportType)) {
String path = System.getProperty("java.io.tmpdir");
String prefix = null;
if (isList)
prefix = makePrefix(jasperPrintList.get(0).getName())+"_List";
else
prefix = makePrefix(jasperPrint.getName());
if (prefix.length() < 3)
prefix += "_".repeat(3-prefix.length());
if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix);
File file = File.createTempFile(prefix, ".xlsx", new File(path));
FileOutputStream fos = new FileOutputStream(file);
// coding For Excel:
JRXlsxExporter exporterXLSX = new JRXlsxExporter();
SimpleXlsxReportConfiguration xlsxConfig = new SimpleXlsxReportConfiguration();
xlsxConfig.setOnePagePerSheet(false);
if (!isList){
jasperPrintList = new ArrayList<>();
jasperPrintList.add(jasperPrint);
}
exporterXLSX.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
exporterXLSX.setExporterOutput(new SimpleOutputStreamExporterOutput(fos));
exporterXLSX.setConfiguration(xlsxConfig);
exporterXLSX.exportReport();
media = new AMedia(m_title + ".xlsx", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file, true);
}else if ("CSV".equals(reportType)) {
String path = System.getProperty("java.io.tmpdir");
String prefix = null;

View File

@ -143,7 +143,7 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
/**
*
*/
private static final long serialVersionUID = -5315520059451132465L;
private static final long serialVersionUID = -424164233048709765L;
/** Window No */
private int m_WindowNo = -1;
@ -278,9 +278,9 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
if ( m_isCanExport )
{
previewType.appendItem("Excel", "XLS");
previewType.appendItem("XLS", "XLS");
previewType.appendItem("CSV", "CSV");
previewType.appendItem("Excel X", "XLSX");
previewType.appendItem("XLSX", "XLSX");
}
toolBar.appendChild(previewType);
@ -298,6 +298,8 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
pTypeIndex = 2;
else if (m_reportEngine.getReportType().equals("CSV") && m_isCanExport)
pTypeIndex = 3;
else if (m_reportEngine.getReportType().equals("XLSX") && m_isCanExport)
pTypeIndex = 4;
}
else
{
@ -315,6 +317,8 @@ public class ZkReportViewer extends Window implements EventListener<Event>, ITab
pTypeIndex = 2;
} else if ("CSV".equals(type) && m_isCanExport) {
pTypeIndex = 3;
} else if ("XLSX".equals(type) && m_isCanExport) {
pTypeIndex = 4;
}
}