1818package it .eng .knowage .engine .cockpit .api .export .excel ;
1919
2020import java .io .ByteArrayOutputStream ;
21+ import java .io .FileInputStream ;
2122import java .io .IOException ;
23+ import java .net .URI ;
24+ import java .nio .file .Files ;
25+ import java .nio .file .Path ;
26+ import java .nio .file .Paths ;
2227import java .util .ArrayList ;
2328import java .util .Arrays ;
2429import java .util .HashMap ;
2530import java .util .List ;
2631import java .util .Locale ;
2732import java .util .Map ;
2833
34+ import javax .ws .rs .core .UriBuilder ;
35+
36+ import org .apache .commons .codec .binary .Base64 ;
2937import org .apache .log4j .LogMF ;
3038import org .apache .log4j .Logger ;
3139import org .apache .poi .hssf .usermodel .HSSFWorkbook ;
4957import it .eng .knowage .engine .cockpit .api .export .excel .crosstab .CrosstabXLSXExporter ;
5058import it .eng .qbe .serializer .SerializationException ;
5159import it .eng .spago .error .EMFAbstractError ;
60+ import it .eng .spago .error .EMFUserError ;
5261import it .eng .spagobi .analiticalmodel .document .bo .ObjTemplate ;
62+ import it .eng .spagobi .commons .SingletonConfig ;
5363import it .eng .spagobi .commons .constants .SpagoBIConstants ;
5464import it .eng .spagobi .commons .dao .DAOFactory ;
5565import it .eng .spagobi .tools .dataset .bo .IDataSet ;
@@ -74,14 +84,18 @@ public class ExcelExporter {
7484 private final JSONObject body ;
7585 private Locale locale ;
7686 private int uniqueId = 0 ;
87+ private String requestURL = "" ;
7788
7889 private static final String [] WIDGETS_TO_IGNORE = { "image" , "text" , "python" , "r" };
90+ private static final String SCRIPT_NAME = "cockpit-export-xls.js" ;
91+ private static final String CONFIG_NAME_FOR_EXPORT_SCRIPT_PATH = "internal.nodejs.chromium.export.path" ;
7992
8093 // Old implementation with parameterMap
81- public ExcelExporter (String outputType , String userUniqueIdentifier , Map <String , String []> parameterMap ) {
94+ public ExcelExporter (String outputType , String userUniqueIdentifier , Map <String , String []> parameterMap , String requestURL ) {
8295 this .outputType = outputType ;
8396 this .userUniqueIdentifier = userUniqueIdentifier ;
8497 this .exportWidget = false ;
98+ this .requestURL = requestURL ;
8599 this .body = new JSONObject ();
86100
87101 Locale locale = getLocale (parameterMap );
@@ -159,6 +173,61 @@ public String getMimeType() {
159173 return mimeType ;
160174 }
161175
176+ // used only for scheduled exports
177+ // leverages on an external script that uses chromium to open the cockpit and click on the export button
178+ public byte [] getBinaryData (String documentLabel ) throws IOException , InterruptedException , EMFUserError {
179+
180+ final Path outputDir = Files .createTempDirectory ("knowage-xls-exporter-" );
181+
182+ String encodedUserId = Base64 .encodeBase64String (userUniqueIdentifier .getBytes ("UTF-8" ));
183+
184+ // Script
185+ String cockpitExportScriptPath = SingletonConfig .getInstance ().getConfigValue (CONFIG_NAME_FOR_EXPORT_SCRIPT_PATH );
186+ Path exportScriptFullPath = Paths .get (cockpitExportScriptPath , SCRIPT_NAME );
187+
188+ if (!Files .isRegularFile (exportScriptFullPath )) {
189+ String msg = String .format ("Cannot find export script at \" %s\" : did you set the correct value for %s configuration?" , exportScriptFullPath ,
190+ CONFIG_NAME_FOR_EXPORT_SCRIPT_PATH );
191+ IllegalStateException ex = new IllegalStateException (msg );
192+ logger .error (msg , ex );
193+ throw ex ;
194+ }
195+
196+ URI url = UriBuilder .fromUri (requestURL ).replaceQueryParam ("outputType_description" , "HTML" ).replaceQueryParam ("outputType" , "HTML" ).build ();
197+
198+ ProcessBuilder processBuilder = new ProcessBuilder ("node" , exportScriptFullPath .toString (), encodedUserId , outputDir .toString (), url .toString ());
199+ Process exec = processBuilder .start ();
200+ exec .waitFor ();
201+ // the script creates the resulting xls and saves it to outputFile
202+ Path outputFile = outputDir .resolve (documentLabel + "." + outputType .toLowerCase ());
203+ return getByteArrayFromFile (outputFile , outputDir );
204+ }
205+
206+ private byte [] getByteArrayFromFile (Path excelFile , Path outputDir ) {
207+ try {
208+ FileInputStream fis = new FileInputStream (excelFile .toString ());
209+ ByteArrayOutputStream bos = new ByteArrayOutputStream ();
210+ byte [] buf = new byte [1024 ];
211+ for (int readNum ; (readNum = fis .read (buf )) != -1 ;) {
212+ // Writes len bytes from the specified byte array starting at offset off to this byte array output stream
213+ bos .write (buf , 0 , readNum ); // no doubt here is 0
214+ }
215+ fis .close ();
216+ return bos .toByteArray ();
217+ } catch (Exception e ) {
218+ logger .error ("Cannot serialize excel file" , e );
219+ throw new SpagoBIRuntimeException ("Cannot serialize excel file" , e );
220+ } finally {
221+ try {
222+ if (Files .isRegularFile (excelFile ))
223+ Files .delete (excelFile );
224+ Files .delete (outputDir );
225+ } catch (Exception e ) {
226+ logger .error ("Cannot delete temp file" , e );
227+ }
228+ }
229+ }
230+
162231 public byte [] getBinaryData (Integer documentId , String documentLabel , String templateString , String options ) throws JSONException , SerializationException {
163232 if (templateString == null ) {
164233 ObjTemplate template = null ;
0 commit comments