Office Apps, how send copy of doc file with ajax to C# controller

738 views Asked by At

hello i have this problem:

I have a addins for office(word);

I want to send a copy of current file (.docx) to C# controller, i have this code now, at this stage of the code i get a array of chars or somethis in the "yourfile", how ca i get a .docx file?

JavaScript

function sendFile() {
    Office.context.document.getFileAsync("compressed",
        { sliceSize: 100000 },
        function (result) {

            if (result.status == Office.AsyncResultStatus.Succeeded) {
                var myFile = result.value;
                var state = {
                    file: myFile,
                    counter: 0,
                    sliceCount: myFile.sliceCount
                };

                getSlice(state);

            }
        });
            }

function getSlice(state) {

    state.file.getSliceAsync(state.counter, function (result) {
        if (result.status == Office.AsyncResultStatus.Succeeded) {

            sendSlice(result.value, state);
        }

    });
}

 function myEncodeBase64(str) 

{
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
            return String.fromCharCode('0x' + p1);
        }));
    }

 function sendSlice(slice, state) {
        var data = slice.data;

        if (data) {

           var fileData = myEncodeBase64(data);
           var _url = '../../api/file';

            useAjax(_url, 'Post', JSON.stringify(fileData), _contentType).done(function (data) {
                writeData(data);
                app.showNotification("Translation was successfully done!");
            });
        }

    }

And the C# CONTROLLER:

    public static string filemame = @"c:\yourfile";

    [Route("file")]
    [HttpPost]
    public void getFile([FromBody] string data)
    {

        Base64ToFile(data,filemame);

    }

 public static void Base64ToFile(string base64String, string filename)
        {


            byte[] fileByteArray = Convert.FromBase64String(base64String);
            // Instantiate FileStream to create a new file
            System.IO.FileStream writeFileStream = new System.IO.FileStream(filename, System.IO.FileMode.Create, System.IO.FileAccess.Write);
            // Write converted base64String to newly created file
            writeFileStream.Write(fileByteArray, 0, fileByteArray.Length);
            // Clean up / disposal
            writeFileStream.Close();
        }
2

There are 2 answers

2
andreea On

Late to the party, but I'm adding the answer here nonetheless, in case someone else will need it at some later date.

Instead of using myEncodeBase64 you should use

var fileData = OSF.OUtil.encodeBase64(data);

It's a function that is part of the Office API, so you don't have to define anything else.

0
Dennis Rosenbaum On

I have been struggling to construct a correct pptx serverside. Eventually this is what I came up with.

Javascript

function sendSlice(slice, state) {
    var data = slice.data;
    if (data) {
        var isLastSlice = state.counter >= (state.sliceCount -1);
        var ajaxData = {
            isLastSlice: isLastSlice,
            counter: state.counter,
            documentData: btoa(data)
        }

        $.ajax({
            url: "/api/Constructpptx", method: "POST", data: ajaxData, success: function (result) {
                state.counter++;
                if (isLastSlice) {
                   closeFile(state);
                }
                else {
                    getSlice(state);
                }

            }, error: function (xhr, status, error) {
            }
        });
    }
}

And as an API backend I use this C# ApiController

public class ConstructpptxController : ApiController
{
    public static List<byte> Document { get; set; } = new List<byte>();

    public string Post([FromBody]ConstructpptxPayload payload)
    {
        if (payload.counter == 0)
            Document.Clear();

        var payloadData = Convert.FromBase64String(payload.documentData);
        var pptBytes = Encoding.UTF8.GetString(payloadData).Split(',').Select(byte.Parse).ToArray();
        Document.AddRange(pptBytes);
        if(payload.isLastSlice)
        {
            var path = @"C:/Some/Local/Path/Presentation.pptx";                
            var fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
            fileStream.Write(Document.ToArray(), 0, Document.Count());
            fileStream.Close();

            Document.Clear();
        }
        return $"Counter: {payload.counter}, isLast: {payload.isLastSlice}, docLength: {Document.Count}";
    }
} 

public class ConstructpptxPayload
{
    public bool isLastSlice { get; set; }
    public int counter { get; set; }
    public string documentData { get; set; }
}

Please note: only use this example as a quick starting point, as you don't want to save the bytes in a static List Document. Instead you want to make your webserver stateless.