Downloading a xls/xlsx file through webspeed

MG_

New Member
#1
I am currently developing a webpage where users must be able download multiple spreadsheet files.
The issue that I have is that the drive where the files reside external users do not have access to, as such I need a way in which I can load those files into memory then avail them for download when users click their respective links, I had the same issue when developing an upload functionality where external users must upload files to be saved on the same drive, for that I used the get-binary-data progress function. Capture.PNG
 

Cecil

19+ years progress programming and still learning.
#4
High level answer.

cfilename = get-value(‘file’).

Copy-lob from file cfilename to object memptr.

{&out-long} memptr.
 

Cecil

19+ years progress programming and still learning.
#5
My last post sucked. I was typing it on my phone.

Here is a chunk of code from my file delivery mechanism. It not fully complete as I removed a lot of code related to multi download stream. Adobe PDF browses want to download a PDF file in multiple streams for performance.

Hopefully, it will give you a clue on exporting files to the webstream.

Code:
    SET-SIZE(mpData) = 0.
 
 
        output-http-header("Status":U,'200 OK':U).
                output-http-header("X-Powered-By":U, SUBSTITUTE('&1 &2',PROVERSION, OPSYS)).

                IF ttDocument.MODIFIED NE ? THEN
                    output-http-header("Last-Modified":U, FormattedHTTPDate(DATETIME(ttDocument.Modified))).

                output-http-header("Cache-Control":U,'private':U).
    /*             output-http-header("Pragma":U, "no-cache":U). */
                output-http-header("Expires":U, "3600":U).
                output-http-header("Accept-Ranges":U, "bytes":U).
                output-http-header("Content-Transfer-Encoding":U, "binary":U).
    
                COPY-LOB FROM FILE chDirectory + '/' + ttDocument.UIDFilename TO OBJECT mpData NO-CONVERT.
    
                output-http-header("Content-MD5",   STRING(MD5-DIGEST(mpData))).
                output-http-header("Content-Length",STRING(GET-SIZE(mpData)  )).
            END.
        END.
            
        CASE get-value('content'):
            WHEN 'inline' THEN
                output-http-header("Content-Disposition":U, SUBSTITUTE('inline~;filename=&1':U,
                                                                       get-field('filename')
                                                                       )
                                   ).
            OTHERWISE
                output-http-header("Content-Disposition":U, SUBSTITUTE('attachment~;filename="&1"':U,
                                                                       get-field('filename')
                                                                       )
                                   ).
        END CASE.

        CASE get-value('contenttype':U):
            WHEN 'PDF':U THEN
                output-content-type (SUBSTITUTE('application/pdf; name=&1':U,
                                                ttDocument.Filename)
                                     ).
            WHEN 'XLSX':U THEN
                output-content-type (SUBSTITUTE('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; name=&1':U,
                                                ttDocument.Filename)
                                     ).       
            WHEN 'XLS':U THEN
                output-content-type (SUBSTITUTE('application/vnd.ms-excel; name=&1':U,
                                                ttDocument.Filename)
                                     ).               
            WHEN 'CSV':U THEN
                output-content-type (SUBSTITUTE('text/csv; name=&1':U,
                                                ttDocument.Filename)
                                     ).                                           
            OTHERWISE
                output-content-type ('application/octet-stream':U).
        END CASE.
            
        ASSIGN           
            inSeekPosOffset = 1
            inBytesRemaing  = GET-SIZE(mpData)
            inRangeLength   = 1024 * 8
            .
        
        EXPORT-TO-STREAM:
        DO WHILE inBytesRemaing GT 0 STOP-AFTER 20 ON STOP UNDO, RETRY EXPORT-TO-STREAM:

            IF RETRY THEN DO:
                MESSAGE 'STOP CONDITIONED RAISED.'.
                RUN ClientEventFailed(INPUT GetClientGUID(),
                                      INPUT 'Download',
                                      INPUT SUBSTITUTE('Stop request issued. &1 &2',
                                                       chDirectory + '/' + ttDocument.UIDFILENAME,
                                                       get-field('filename')
                                                       )
                                      ).
                LEAVE EXPORT-TO-STREAM.
            END.

            SET-SIZE(mpDataBuffer) = 0.

            /** Get the remaing bytes...**/
            IF inBytesRemaing LT inRangeLength THEN
                ASSIGN
                    inRangeLength = inBytesRemaing.

            COPY-LOB FROM OBJECT mpData STARTING AT inSeekPosOffset FOR inRangeLength TO OBJECT mpDataBuffer NO-CONVERT NO-ERROR.

            IF ERROR-STATUS:ERROR THEN
                LEAVE EXPORT-TO-STREAM.

            {&OUT-LONG} mpDataBuffer.

            PUT {&WEB-STREAM} CONTROL NULL(0).
            
            ASSIGN
                inBytesRemaing  = inBytesRemaing  - inRangeLength
                inSeekPosOffset = inSeekPosOffset + inRangeLength.

/*             MESSAGE STRING(((inSeekPosOffset / GET-SIZE(mpData)) * 100),'->>9.99%'). */
/*                                                                                      */
/*             PAUSE 1 NO-MESSAGE.                                                      */

/*             MESSAGE inBytesRemaing.                                                */
/*             MESSAGE inSeekPosOffset.                                                         */
/*             MESSAGE STRING((inBytesRemaing / GET-SIZE(mpData) ) * 100, 'zz9.99%'). */
/*                                                                                    */
        END.
        SET-SIZE(mpDataBuffer) = 0.


/*         MESSAGE SUBSTITUTE('Chunked Data To Stream: &1 Seconds &2 (KB per Second)', */
/*                            inTimeTaken,                                             */
/*                            INTEGER((GET-SIZE(mpData) / inTimeTaken) / 1024)         */
/*                            ).                                                       */

/*         {&OUT-LONG} mpData.                                                               */
/*         MESSAGE SUBSTITUTE('Large Chunked Data To Stream: &1 Seconds &2 (KB per Second)', */
/*                            inTimeTaken,                                                   */
/*                            INTEGER((GET-SIZE(mpData) / inTimeTaken) / 1024)               */
/*                            ).                                                             */

        

        SET-SIZE(mpData) = 0.
 
Top