Display PDF from BLOB

I've got some PDFs stored in SQL Server as BLOB fields. I'm trying to retrieve these using XData and deliver them to the Web Core frontend as a download.

I've followed the BLOB posts on the forum regarding images, but these don't work for what I'm doing.

So far, I have the data retrieved fine using XData, but I need to find out how to save the BLOB contents to a stream to send to the browser as a PDF.

Is this possible ? Maybe save the BLOB to a file (In Delphi I would just do SaveToFile or SaveToStream for the BlobField), then send that to the browser.

Thanks

The Application object exposes

    procedure DownloadPDFFile(const AData: TBytes; const AFileName: string = ''; const ANewTab: Boolean = False); overload;
    procedure DownloadPDFFile(const AData: TJSUint8Array; const AFileName: string = ''; const ANewTab: Boolean = False); overload;

So, if you have the PDF data as TBytes type or TJSUint8Array (or convert it to either of these 2 types) you can programmatically start its download.

Thanks Bruno. I can see how that should work. The problem I have is that the data being retreived from the server with XData isn't in the correct format. I'm retreiving the data, then using DataSetToJSON to convert this to a string.

In the Web Core client, I am doing this to get the JSON back to a dataset :

procedure JSONResponseToDataSet(DS: TXDataWebDataSet; Response: TXDataClientResponse);
var
FADATA: string;
FJSARRAY: TJSArray;
begin
DS.Close;
FADATA := JS.ToString(JS.ToObject(Response.Result)['value']);
FJSARRAY := TJSArray(TJSJson.Parse(FADATA));
DS.SetJsonData(FJSARRAY);
DS.Open;
end;

But it's not correct, and I'm guessing I need to do something to this data to make it a PDF Blob again.

Is this the corret way to exchange and re-assemble the BLOB data between XData and Web Core ?

I've managed to download the attachment using Application.Download and assembling the URL. This data is on a different server though, so the URL in the bar changes. Is there a way to hide the URL or to go back to the previous page when the download has finished ? I can't see a way to tell when the download has completed.

Last param of DownloadPDFFile is boolean NewTab.
Set this to true to force the download in a new tab and leave the running app unaffected.

Hi Bruno, I'm using Application.Download which only has the URL parameter.

But I hinted at

procedure DownloadPDFFile(const AData: TBytes; const AFileName: string = ''; const ANewTab: Boolean = False); overload;
procedure DownloadPDFFile(const AData: TJSUint8Array; const AFileName: string = ''; const ANewTab: Boolean = False); overload;

I know Bruno, but I'm struggling to get my XData JSON in the correct format, so Application.Download was my second choice.

Sorry, at this moment we don't have the specifier there yet to force the download in a new tab.

You could try
Application.Navigate(URL, ntBlank);

George,

I think if you do not encode your XData response as JSON but binary, most modern web browsers would be able to display the PDF when you open a new window/tab with the URL of the XData endpoint that delivers the PDF.

Just make certain that your service method returns TStream and not any other data type. That way XData will NOT encode the result as JSON but keep as is. (I show this in Hands-on 1, but have your question in the back of my head as a good thing to show with TMS WEB Core)

Added: I just checked. It works. If you do not use a JSON serialized result, the web browser will show or download the PDF depending on the configuration.

Here's an example using the example web service from Hands on 1. When you click the button, the TWebBrowserControl navigates to the PDF endpoint. It displays an 'Open...' button to open the PDF. I am sure there are many other possibilities using hosted forms etc.

image

procedure TForm1.WebButton1Click(Sender: TObject);
begin
  Browser.Navigate('http://localhost/flix/reportingservice/getcompanyprofile?aid=L13000088031');
end;