1
votes

I have used the below JS code provided by Microsoft in order to save a document in PDF:

Office.context.document.getFileAsync(Office.FileType.Pdf,
        function(result) {
            if (result.status == "succeeded") {
                var myFile = result.value;
                var sliceCount = myFile.sliceCount;
                var slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
                console.log("File size:" + myFile.size + " #Slices: " + sliceCount);
                // Now, you can call getSliceAsync to download the files,
                // as described in the previous code segment (compressed format).
                // Get the file slices.
                getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
                myFile.closeAsync();
            }
            else {
                console.log("Error:", result.error.message);
            }
        }
    );

function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
    file.getSliceAsync(nextSlice, function (sliceResult) {
        if (sliceResult.status == "succeeded") {
            if (!gotAllSlices) { // Failed to get all slices, no need to continue.
                return;
            }

            // Got one slice, store it in a temporary array.
            // (Or you can do something else, such as
            // send it to a third-party server.)
            docdataSlices[sliceResult.value.index] = sliceResult.value.data;
            if (++slicesReceived == sliceCount) {
              // All slices have been received.
              file.closeAsync();
              onGotAllSlices(docdataSlices);
            }
            else {
                getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
            }
        }
            else {
                gotAllSlices = false;
                file.closeAsync();
                console.log("getSliceAsync Error:", sliceResult.error.message);
            }
    });
}

function onGotAllSlices(docdataSlices) {
    var docdata = [];
    for (var i = 0; i < docdataSlices.length; i++) {
        docdata = docdata.concat(docdataSlices[i]);
    }

    var fileContent = new String();
    for (var j = 0; j < docdata.length; j++) {
        fileContent += String.fromCharCode(docdata[j]);
    }

    console.log('Final PDF content is received and stored in fileContent.');


    send_file_content(fileContent);
}

function send_file_content(word_doc) {
    var formData = new FormData();
    var blob = new Blob([word_doc], { type: "application/pdf"});
    formData.append("file", blob);
    $.ajax({
        type: 'POST',
        url: 'My-upload-URL',
        data: formData,
        processData: false,
        contentType: false
    }).done(function(data) {
        console.log('* Word Document successfully uploaded: ', data.filepath);
    });
}

I'm pretty sure that the server side is OK as I have uploaded zillions of PDF documents and it works as expected, but when I upload Word PDF Document via the above JS code I get a blank page on server side. If the word document contains 3 pages then I will get 3 blank pages on server-side as a PDF file.

1

1 Answers

4
votes

The Microsoft Documentation goes with charCodeAt function which ruins the data and makes a blank PDF document.

Instead of using that function, I used Uint8Array on the byte array directly:

var blob = new Blob([new Uint8Array(myFinalByteArray)], { type: 'application/pdf' });

And then uploaded the Blob using FormData into a remote server. The problem gone away with this approach.