【问题标题】:Saving an xslx document from a soap response with javascript使用 javascript 从肥皂响应中保存 xslx 文档
【发布时间】:2017-03-09 18:34:37
【问题描述】:

我创建了一个 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 返回值(字节数组)作为文件?

【问题讨论】:

    标签: javascript java web-services soap file-transfer


    【解决方案1】:

    几天后我想通了:

    更新的有效代码:

    (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"); 
            }
        }
    }
    

    在此处使用将 base 64 数据转换为 blob 的函数“b64toBlob”: Creating a Blob from a base64 string in JavaScript

    我注意到的主要区别是新的 b64toBlob 函数使用切片大小,然后在转换后将每个切片推入主数组。我不知道为什么在一次转换整个东西时最初不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多