我创建了一个SOAP服务,可以正确生成XLSX Excel文件并将其保存到托管服务的服务器上。
此处的相关代码(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;
}
我使用以下代码使用此服务:
(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);
}
...
“saveAs”功能由“FileSaver.js”定义: https://github.com/eligrey/FileSaver.js/
SOAP调用正常运行并将字节数组返回给soap服务 - 但是在浏览器端下载后,Excel无法打开该文件。
FileOutputStream在服务器端保存的文件在Excel中正确打开。
使用NotePad ++(或任何可以看到不可见字符的编辑器),我看到一些不可见的字符已从结果文件中删除。
我猜我正在使用的一个或多个函数无法处理值并将其删除。有没有人知道我在Javascript端使用的函数是否是这种情况,或者是否有更好的方法来处理此返回请求,以便我可以正确地提示用户下载生成的soap返回值(字节数组)作为文件?
答案 0 :(得分:0)
几天后我想出了这个:
更新了有效的代码:
(Java)的
public byte[] getFile(@WebParam(name = "arg0") String schemaName, @WebParam(name = "arg1") String tableName) {
Table tableData = new Table(schemaName, tableName);
ArrayList<String> columns = tableData.getAllColumnNames();
XSSFWorkbook workbook = new XSSFWorkbook();
byte[] data;
//... Create Excel using Apache POI API Here ...
try {
FileOutputStream outputStream = new FileOutputStream("C:\\testPath\\test.xlsx");
workbook.write(outputStream);
Path path = Paths.get("C:\\testPath\\test.xlsx");
data = Files.readAllBytes(path);
return data;
}
catch (IOException e) {
e.printStackTrace();
}
return "".getBytes();
}
(JavaScript)的
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 contentType = 'vnd.ms-excel';
var y = x.childNodes[0];
var b64Data = y.nodeValue
var blob = b64toBlob(b64Data, contentType)
saveAs(blob, "text.xlsx");
}
}
}
利用函数“b64toBlob”将base 64数据转换为blob: Creating a Blob from a base64 string in JavaScript
我注意到的主要区别是新的b64toBlob函数使用切片大小,然后在转换后将每个切片推到主阵列上。我不知道为什么在一次转换整个东西时原来不起作用。