Hi
I created a xlsx file from flexcel on my xdata server in a tmemorystream. How do I save that stream on my webclient to a xlsx file.
Hi
I created a xlsx file from flexcel on my xdata server in a tmemorystream. How do I save that stream on my webclient to a xlsx file.
These posts might help you
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).
It seems the download payload is encoded as a Base64 file. Why does the Content-Type header say it's a spreadsheet rather than something appropriate for a Base64 data file? It might make sense if you want the client side (a web browser) to open and display it somehow, but not if you just want to work with it or save it to a file as binary data.
As an aside, @wlandgraf it would be really nice if there was a setting somewhere that enabled this for a given payload. Stuff the data into a compressed stream, convert it to Base64, put it into another TStream of some kind (if needed), send it down, then unpack it and deliver it as a TMemoryStream to the Client. Something similar would go from Client to Server, but that might be a slightly different process. (It may be a file on the server and a TMemoryStream on the Client. I'm not working with actual files on the Client side, just in-memory data. The files are all stored remotely.)
The reason that the underlying file type is provided is so that receiving applications know what has been encoded. In this instance I am just saving it, but that might not always be the case.
Hi Russel
Thanks for your help so far, on the client side I get the below error once it execute the following command
FileData := window.atob(AData);
DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded
I retested this here but couldn't see an issue.
I'd recommend to log AData in the console and verify if this is the correct expected base64 data and if not, check the code you use to get AData.
I was wondering what the atob(...) function is.
Thanks all, I did come write everything is working now, I appreciate all your help
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.