I am making an app that uploads images to an UploadCollection (SAPUI5) with instantUpload=false. I have extended the UploadCollection control to process these image files before the upload process begins. In this redefinition I have merged all these images in a PDF using the library "jsPDF".
The problem arrives when uploading the PDF file in a "standard" way, it means, using the standard "sendFiles" function of the UploadCollection. This method needs that these files are of type: "File". What I have is a base64 string. This means I need to use the "new File()" constructor.
With this base64 string I have created a blob and with this blob I have created a File. I achieve uploading the file, but when I try to open it, the file is unreadable. I believe that the creation process of the file is wrong.
I followed several tutorials and could not resolve my problem.
I know that in Ajax I can upload the blob, but I don't want to use Ajax as I need to use ODataModel because of best practices of my company.
If I parse the base64 string into a PDF file I can see the PDF right, so the problem is not the base64 string generation.
If I use Chrome, the generation of the file works but I can see that the name property contains the blob and the localURL contains the name, as if there was a missorder in the parameters. Is like if Chrome doesn't follow this API: https://www.w3.org/TR/FileAPI/#dfn-file
If I use Firefox the properties are correct, but when I download the file I have the same problem. The file can't be displayed.
I have tried so many things that I can't list them all here.
/**
* Function that converts string to blob
* @param {String} sBase64Data String with the base64 info
* @param {String} sContentType mimeType of the data: application/pdf
* @returns {Blob} Blob for the new File()
*/
_b64toBlob: function (sBase64Data, sContentType) {
var aByteCharacters = atob(sBase64Data);
var aByteArrays = [];
var iSliceSize = 512;
// var iSliceSize = 1;
for (var offset = 0; offset < aByteCharacters.length; offset += iSliceSize) {
var slice = aByteCharacters.slice(offset, offset + iSliceSize);
var aByteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
aByteNumbers[i] = slice.charCodeAt(i);
}
var aByteArray = new Uint8Array(aByteNumbers);
aByteArrays.push(aByteArray);
}
var blob = new Blob(aByteArrays, {
type: sContentType
});
return blob;
},
//In other part of the code....
var sContentType = "application/pdf";
var sPDFBase64 = btoa(doc.output());
var oBlob = this._b64toBlob(sPDFBase64, sContentType);
var fFile = new File([oBlob], sFileName, { type: sContentType });
aFiles.push(fFile);
this._sendFilesWithXHR(aFiles);