My code on the xdata server:
TDirectDownload = class
FFilename: String;
Data: String;
ContentType: String;
end;
function TReportService.DirectDownload(const ReportId: Integer; const ParamValues: string): TDirectDownload;
var
lFileName, lFullPath: string;
lFileStream: TFileStream;
lOutStream: TStringStream;
Dataset: TDataset;
lTitle: string;
begin
lTitle := '';
lFileName := '';
Dataset := GetData(ReportId, ParamValues, lFileName, lTitle);
try
CreateXLS(Dataset, lFileName, lTitle);
finally
Dataset.Free;
end;
result := TDirectDownload.Create;
result.FFilename := lFileName;
result.ContentType := 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
lFullPath := TPath.Combine(SavePath, lFileName);
if not TFile.Exists(lFullPath) then
raise EFileNotFoundException.Create('The file was not found');
// TXDATAOperationContext.Current.Response.Headers.AddValue('Content-type', 'application/pdf');
// TXDATAOperationContext.Current.Response.Headers.AddValue('Content-Disposition', 'filename=' + lFileName);
lFileStream := TFileStream.Create(lFullPath, fmOpenRead);
try
lFileStream.Position := 0;
lOutStream := TStringStream.Create('');
try
TNetEncoding.Base64.Encode(lFileStream, lOutStream);
lOutStream.Position := 0;
result.Data := lOutStream.DataString;
finally
lOutStream.Free;
end;
finally
lFileStream.Free;
end;
end;
And on webcore:
class procedure TFileSupport.SaveEncoded64File(const aFileName, AData: string);
var
FileData: WideString;
FileLen: Integer;
I: Integer;
AB: TJSArrayBuffer;
AV: TJSUInt8Array;
begin
try
FileData := window.atob(AData);
FileLen := Length(FileData);
except
on E: Exception do
begin
console.log('ERROR: (Base64) File could not be decoded');
raise Exception.Create('ERROR: (Base64) File could not be decoded');
end;
end;
if (FileLen <> -1) then
begin
console.log('Retrieved (Base64) File: ' + IntToStr(Length(AData)) + ' bytes');
console.log('Decoded (Base64) File: ' + IntToStr(FileLen) + ' bytes');
end;
AB := TJSArrayBuffer.new(FileLen);
AV := TJSUInt8Array.new(AB);
for I := 0 to FileLen - 1 do
AV[i] := TJSString(FileData).charCodeAt(i);
Application.DownloadBinaryFile(AV, aFileName);
end;
I'll leave you the exercise of creating the connecting core
I am in the process of putting these all into some support libraries that I'll publish on github - some are there already (part formed).