Profile picture for user m3b

Hi all

is this possible and how ?  

We'd like to give the end users a (possibly) permanent URL where they could retrieve the report output (which could be stored in Aris Connect Document Repository)

 

Thanks

PS : a javascript solution is OK as our report is not a wysiwyg report

by Robert Goldenbaum
Badge for 'Question Solver' achievement
Posted on Fri, 04/01/2022 - 12:43

Hi,

well, it should be possible, but a little bit complicated...   just generate the output file, then get the ADS document (e.g. by link) and update the document there...

But "just" is - as I said - complicated :-)

Robert

0
by Michel Bénard Author
Posted on Fri, 04/01/2022 - 13:33

In reply to by rgoldenbaum

Hi Robert

OK, let's assume I know how to get the report  ouput  content in my report

Looking at https://your_aris_server_/abs/help/en/script/ba/index.htm#report_OBJECTS_ADSReportComponent.htm 

One could go along the following lines :

var stream = (scheduled report output content, don t know yet how to get it)

var ads = Context.getComponent("ADS")

var repository = ads.getADSRepository ( "MyRepositoryFolder") 

var doc  = repository.getDocument("Myreportoutput.xls")

if (doc==null) // doc does not exist
{
var metaInfo = repository.createDocumentMetaInfo("DocTitle","filename","Description");
doc = repository.createDocument(parentFolder,metaInfo,stream);
}
else //doc exists , create new wersion
{
repository.updateDocumentContent(doc,doc.getDocumentMetaInfo(), stream,"Update")
}

 

0
by Robert Goldenbaum
Badge for 'Question Solver' achievement
Posted on Fri, 04/01/2022 - 14:03

Well, there could be two ways:

1) directly when running the script

      var oFile = Context.getFile(Context.getSelectedFile(), Constants.LOCATION_OUTPUT);
      var oByteArrayInputStream = new java.io.ByteArrayInputStream(oFile);
      var oInputStream = new java.io.BufferedInputStream(oByteArrayInputStream);
 

2) by usage of an second script that uses the report scheduler 

        var reportScheduler = Context.getComponent("ReportScheduler");
        var aByteArrayResult =
reportScheduler.getDecryptedScheduleResult("scheduledReportGUID", "username", "password", false);
        var aSelectedFile =
reportScheduler.getZipEntries(aByteArrayResult);
        var aByteArrayXLSX = null;
        for (var i in aSelectedFile) {
            if (aSelectedFile[i].getName().equals("OutputFile.xlsx")) {
                aByteArrayXLSX = aSelectedFile[i].getData();
                break;
            }
        }
        var outputFile = new java.io.File(filePath + "\\OutputFile.xlsx");
        var fop = new java.io.FileOutputStream(outputFile);
        if (!outputFile.exists()) {
            outputFile.createNewFile();
        }
        fop.write(aByteArrayXLSX);
        fop.flush();
        fop.close();
 

Not quite sure if the second one works, but the first one should be usable anyway...

Robert

1
by Michel Bénard Author
Posted on Fri, 04/01/2022 - 14:14

Thanks , I'll give it a try

 

0
by Michel Bénard Author
Posted on Fri, 04/01/2022 - 14:28

I guess I'll have to write two scheduled reports

  •  the first one to create the document I want to share with end users (and which will be stored encrypted somewhere on the aris server, not avaialble to end users)
  • the second one who will retrieve that document and store it in Aris Document Storage, available to Aris connect end users
0
by Kay Fischbach
Posted on Fri, 04/01/2022 - 15:24

In reply to by m3b

Why though? If you want to store something in the ARIS Document Storage, just store it in the ARIS Document storage.

I've written about this topic in this thread https://www.ariscommunity.com/users/nishabaste/2021-05-18-using-ads-through-aris-scripting#comment-27914 explaining how to retrieve and update ARIS Document Storage documents by report.

It boils down to

1. Write output file as if you'd want to send it to a client

2. Locate ADS Document with ADS Report Component Interface

3. Get output file as byte array with Context.getFile(...)

4. Create Java ByteArrayInputStream with byte array

5.give ByteArrayInputStream to ADS method which will use it to update the document

6. If you want to make sure nobody can use your report to get the file directly, wipe it from the output directory with Context.deleteFile(...)

 

0
by Michel Bénard Author
Posted on Fri, 04/01/2022 - 15:59

In reply to by Kay Fischbach

Hi Kay

the use case is : schedule a report and make the output available in the ADS

. Write output file as if you'd want to send it to a client

Can this be done from within a scheduled report ? 

0
by Harm Verschuren
Posted on Thu, 03/23/2023 - 15:48

In reply to by m3b

Hello Michel,

Today I was hitting the same issue  of uploading report output directly to ADS, not willing to have an intermediate step where the output is stored in a file on the server.

I succeeded in doing this and am happy to share with the ARIS Community. Fair to say is that I've been inspired by the file ADSUploader.js which can be found in the 'Reports/Dashboard data' folder. The folder structure (Dashboarding/<database name>/) is inspired by the ADSUploader.js. You can change this and all hard-coded variables to your needs.

All required code is inside the function. One can copy/paste the function into ones code and then call it like shown in the first code snippet.

var xmlOutput = Context.createXMLOutputObject("Models.xml", "Models");
// assemble your XML document...
uploadXmlOutputToAds(xmlOutput, "DHAN", "Models.xml", "All models as xml", "All models as xml description.");

The upload function:

// Upload an in-memory XML document directly to ADS.
// params:
//   outputObject  : XML outputObject.
//   adsFolderName : Last part of the folder name in ADS where the document is stored.
//                   Complete foldername: /Dashboarding/<database name>/<adsFolderName>
//   adsFileName   : Name of the file in ADS. Include extension.
//   documentTitle : Title of the document as shown in ADS metadata.
//   documentDescription : Description of the document as shown in ADS metadata. Optional.
//
// When the folder in ADS doesn't exist, it will be created.
function uploadXmlOutputToAds(outputObject, adsFolderName, adsFileName, documentTitle, documentDescription) {
    var ads = Context.getComponent("ADS");
    var db  = ArisData.getActiveDatabase().Name(Context.getSelectedLanguage());
    var repository = ads.getADSRepository("portal");
    var rootFolder = repository.getRootFolder();
    var folderName = "Dashboarding\\" + db + "\\" + adsFolderName;
    var adsFolder = repository.getFolder(rootFolder, folderName);
    if (!adsFolder) {
        adsFodler = repository.createFolder(rootFolder, folderName);
    }
    var documentInfo = repository.createDocumentMetaInfo(documentTitle, adsFileName, documentDescription);
    var outputByteArray = outputObject.getDocumentContent();
    var document = repository.createAndOverwriteExistingDocument(
                        adsFolder, documentInfo,
                        new java.io.ByteArrayInputStream(outputByteArray) )
}

A screenshot of the result in ADS is attached.

Best regards,
Harm

File attachments
1
by Michel Bénard Author
Posted on Sat, 04/02/2022 - 18:31

In reply to by Kay Fischbach

Ok ,thanks to Robert and Kay I managed to :

  • execute the report , either by hand or by scheduling it
  • send the report output file to the ADS (updating the existing document if it already exists or creating it if not)

For those interested , the working code is just below.

However there is still something that bugs me.

The script works like this :

  1. The report creates its output and writes it (to the desktop client if executed manually , or on the server I guess if scheduled) . This is done when calling writeReport()
  2. The reports then reads back the file, turns it into a stream, then sends the stream to the ADS which creates a new file

First question is : how to delete the unused file (the one created in setp one above) ?

Second question :  how to avoid altogetther the creation of this temporary file ? Is there a function of the OutputObject  that could be called to get the byte stream needed by the ADS functions ? 

Thanks

Working code snipet : 

oOutput.WriteReport() // report output is written to a file

// retrieve the file content
      var oFile = Context.getFile(Context.getSelectedFile(), Constants.LOCATION_OUTPUT);
      var oByteArrayInputStream = new java.io.ByteArrayInputStream(oFile);
      var oInputStream = new java.io.BufferedInputStream(oByteArrayInputStream);

// connect to the ADS
      var ads = Context.getComponent("ADS")

      var repository = ads.getADSRepository ( "portal")  // has to be portal according to Aris documentation
      var parentFolder = repository.getFolder("MyDirectory/MySubDirectory"); // whare I want to put the report output
    
      var doc  = repository.getDocument(parentFolder,null,Context.getSelectedFile())

        if (doc==null) // doc does not exist
        {
        var metaInfo = repository.createDocumentMetaInfo("DocTitle","myoutput.xlsx","Description");
       
        doc = repository.createDocument(parentFolder,metaInfo,oInputStream);
        }
        else //doc exists , create new wersion
        {
        repository.updateDocumentContent(doc,doc.getDocumentMetaInfo(), oInputStream,"Update")
        }

 

0
by Kay Fischbach
Posted on Mon, 04/04/2022 - 18:03

In reply to by m3b

The report creates its output and writes it (to the desktop client if executed manually , or on the server I guess if scheduled) . This is done when calling writeReport()

No, calling writeReport() writes a file whose content previously only existed in Server RAM to a temporary output directory (on the server) that is specifically created for an instance of your report execution. It does nothing more - no file is passed to the client while the report is running.

After your report concludes there are two conditions for a file to be transfered to the client:

  • the file name must be registered as an output file (the selected file is registered by default, you may manually add more file names e.g. with Context.addOutputFileName(...))
  • the file must actually exist (obviously not even the automatically registered selected file can be transfered if you never wrote such a file to the output directory, or if you wiped it from the output directory before the report concludes)

how to delete the unused file (the one created in setp one above) ?

The file created in step one can be deleted with

Context.deleteFile(Context.getSelectedFile(), Constants.LOCATION_OUTPUT);

In addition to deleting the file I also recommend that if you really don't want to transmit your file to any potential client you create your file with a different filename than the one provided by Context.getSelectedFile() (and adjust the first parameter of the Context.deleteFile(...) call). As I've written before, this file name is registered by default for output file transfer, therefore if you instead use something like "businessReport." + your file extension without registering this made up file name as an output file it would never be transfered to begin with. Also make sure to set the selected file with Context.setSelectedFile("noRealName.noRealExtension") to something that's not "businessReport." + your file extension. This prevents users from acquiring the file even if they were to manually set their output file name to "businessReport." + your file extension.

how to avoid altogetther the creation of this temporary file ? Is there a function of the OutputObject  that could be called to get the byte stream needed by the ADS functions ?

That I don't know. The ARIS OutputObject is most likely backed by different libraries depending on the output format (e.g. Apache POI if you create a docx Document, ...) and I doubt there is a universal method to tell all those different libraries to output into a buffer instead of writing a file to the filesystem.

0
by Robert Goldenbaum
Badge for 'Question Solver' achievement
Posted on Tue, 04/05/2022 - 08:42

In reply to by Kay Fischbach

Hm, I think if you set "Context.setScriptError(Constants.ERR_NOFILECREATED);"  no file is sent to the Client when the script is finished...

0
by Robert Goldenbaum
Badge for 'Question Solver' achievement
Posted on Fri, 04/01/2022 - 15:47

Yes, solution (1) :-)

0
by Robert Goldenbaum
Badge for 'Question Solver' achievement
Posted on Mon, 04/04/2022 - 09:15

Hm, you just don't use the WriteReport (as this moves the file to the end user), but grab the file from the temporary folder on the ARIS server instead...

If I find an example, I will post it...

0
by Michel Bénard Author
Posted on Thu, 12/08/2022 - 10:56

Thanks all @Robert Goldenblaum  and @Kay Fischbach

For the record below a code snippet that achieves the desired result

var outputFilename ="test.txt";
var outputObject = Context.createOutputObject(Constants.OutputTXT,outputFilename);
outputObject.OutputTxt(Context.getScriptInfo(Constants.SCRIPT_NAME)+"\n");
var docTitle = "Doc title";
// add more output
outputObject.WriteReport() ;
// save to ADS
var ads = Context.getComponent("ADS")
var repository = ads.getADSRepository ("PORTAL");
var parentFolder = repository.getFolder("My Folder");
var file = Context.getFile(outputFilename ,Constants.LOCATION_OUTPUT);
var byteArrayInputStream = new java.io.ByteArrayInputStream(file);
var inputStream = new java.io.BufferedInputStream(byteArrayInputStream);
var metaInfo = repository.createDocumentMetaInfo(docTitle,outputFilename ,"My description");    
repository.createAndOverwriteExistingDocument (parentFolder, metaInfo, inputStream );
// or if one wants to add versions instead of overwriting
/*
 var doc  = repository.getDocument(parentFolder,docTitle,outputFilename);
 if (doc==null) // doc does not exist
        {
            doc = repository.createDocument(parentFolder,metaInfo,inputStream);
        }
        else //doc exists , create new wersion
        {
            metaInfo = doc.getDocumentMetaInfo();
            repository.updateDocumentContent(doc,metaInfo,inputStream,"Update")
        }
*/
0

Featured achievement

Rookie
Say hello to the ARIS Community! Personalize your community experience by following forums or tags, liking a post or uploading a profile picture.
Recent Unlocks

Leaderboard

|
icon-arrow-down icon-arrow-cerulean-left icon-arrow-cerulean-right icon-arrow-down icon-arrow-left icon-arrow-right icon-arrow icon-back icon-close icon-comments icon-correct-answer icon-tick icon-download icon-facebook icon-flag icon-google-plus icon-hamburger icon-in icon-info icon-instagram icon-login-true icon-login icon-mail-notification icon-mail icon-mortarboard icon-newsletter icon-notification icon-pinterest icon-plus icon-rss icon-search icon-share icon-shield icon-snapchat icon-star icon-tutorials icon-twitter icon-universities icon-videos icon-views icon-whatsapp icon-xing icon-youtube icon-jobs icon-heart icon-heart2 aris-express bpm-glossary help-intro help-design Process_Mining_Icon help-publishing help-administration help-dashboarding help-archive help-risk icon-knowledge icon-question icon-events icon-message icon-more icon-pencil forum-icon icon-lock