I have created a SOAP service that correctly makes an XLSX Excel file and saves it to the server that the service is hosted on.
Relevant code here (Java):
public byte[] getFile(@WebParam(name = "arg0") String schemaName, @WebParam(name = "arg1") String tableName) {
FileOutputStream outputStream = new FileOutputStream("example.xlsx");
workbook.write(outputStream);
File myFile = new File("example.xlsx");
byte[] bytesArray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
fis.read(bytesArray);
fis.close();
return bytesArray;
}
I consume this service using the following code:
(Javascript)
function sendFileSoap() {
var xmlhttp = new XMLHttpRequest();
var responseMessage;
var fullResponse;
xmlhttp.open('POST', 'http://127.0.0.1:7101/Application3-Model-context-root/ExcelConverterPort', true);
// build SOAP request
var requestBody =
'<?xml version="1.0" encoding="utf-8"?>' +
'<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://model/">' +
'<env:Header/>' +
'<env:Body>' +
'<ns1:getFile>' +
'<arg0>' + document.getElementById('sname1').value + '<\/arg0>' +
'<arg1>' + document.getElementById('fname1').value + '<\/arg1>' +
'<\/ns1:getFile>' +
'<\/env:Body>' +
'<\/env:Envelope>'
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
fullResponse = xmlhttp.responseText;
alert(fullResponse);
var xmlDoc = xmlhttp.responseXML;
var x = xmlDoc.getElementsByTagName("return")[0];
var y = x.childNodes[0];
downloadFile(y.nodeValue)
}
}
}
xmlhttp.setRequestHeader('Content-Type', 'text/xml');
alert(requestBody);
xmlhttp.send(requestBody);
return responseMessage;
}
function downloadFile(characters) {
// convert base64 string to byte array
var byteCharacters = atob(characters);
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
// now that we have the byte array, construct the blob from it
var blob1 = new Blob([byteCharacters], {type: "application/vnd.ms-excel"});
var fileName1 = "table.xlsx";
saveAs(blob1, fileName1);
}
...
The "saveAs" function is defined by "FileSaver.js" available here: https://github.com/eligrey/FileSaver.js/
The SOAP call is functioning correctly and returning a byte array to the soap service - however Excel is unable to open the file after the download on the browser side.
The file that is saved server-side by the FileOutputStream properly opens in Excel.
Using NotePad++ (or any editor that lets you see invisible characters), I see that some of the non-visible characters have been stripped from the resulting file.
I am guessing one or more of the functions I'm using just can't handle values and strip them out. Does anyone know if this is the case for the functions I used on the Javascript side or if there is a better way to handle this return request so that I can properly prompt the user to download the resulting soap return value (byte array) as a file?