Search code examples
javaservletsxmlhttprequestapache-commons-fileuploadword-addins

Upload file via XHR and write stream to file


I send a word 2013 docx via my javascript word addin to a servlet. But after writing the stream to file the pdf/word (type compressed) file is corrupted and has different size. It has more bytes then slice.value.size in js output tells me (which shows the same size when i save file to hdd in word). Using FormData and Apache Fileupload has the same result. Any help would be appreciated.

JS:

function sendDoc(){
    Office.context.document.getFileAsync("pdf",
        function (result) {
            if (result.status == Office.AsyncResultStatus.Succeeded) {
                var myFile = result.value;
                myFile.getSliceAsync(0, function (slice) {
                    if (slice.status == Office.AsyncResultStatus.Succeeded) {
                        showMessage("sending (" + slice.value.size + " bytes)");

                        var request = new XMLHttpRequest();
                        request.onreadystatechange = function () {
                            if (request.readyState == 4) {
                                myFile.closeAsync(function (r) {
                                    if (r.status == Office.AsyncResultStatus.Succeeded) {
                                        showMessage("sent");
                                    }else {
                                        showMessage("error");
                                    }
                                });
                            }
                        }
                        request.open("POST", "myserver");
                        request.send(slice.value.data);

                    }else {
                        showMessage(slice.status);
                    }
                });
            } else {
                showMessage(result.status);
            }
        });
}

Servlet:

public void doPost(HttpServletRequest request, HttpServletResponse response) {
        try {
            InputStream in = request.getInputStream();
            FileOutputStream out = new FileOutputStream("c:/temp/test.pdf");
            IOUtils.copy(in, out);
            in.close();
            out.close();

        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

Solution

  • Solved it myself. I had to convert unicode number into character and encode BASE64:

    var fileContent = new String();
    var docdata = slice.value.data;
    for (var j = 0; j < docdata.length; j++) {
      fileContent += String.fromCharCode(docdata[j]);
    }
    var data = btoa(fileContent);
    request.send(data);