javascriptc#autosavems-wopi

Autosave file opened in WOPI for editing after an interval


I want to implement a functionality that saves the file (.docx, .pptx, .xlsx) opened in WOPI for editing in local storage after every 5 seconds, after checking that some changes are made to the file. And later that will be persisted in a database (after clicking submit button).

I did some research and found that we can achieve this with timer in c#, but how can I get the contents of the WOPI editor in bytes in the timer function to compare it for changes.

For an understanding of the code, I initialize a timer when the edit button in WOPI iframe is clicked. Then get the original file from originalfile_id passed from the WOPI iframe and use this id to fetch the file from local storage. Then compare its content with the content of the file open in WOPI for editing, if the byte arrays are different means changes are made and so I save the file with the latest changes.

This autosaving mechanism runs every 5 seconds and checks if changes are made then only it saves the file other does nothing until a change is made. When the user closes the editor or submits changes the timer stops.

public class FileSave
{
    private static System.Timers.Timer aTimer;
    public static string _originalfile_id;
    public static String _Id;

    public FileSave(string originalfile_id)
    {
        _originalfile_id = originalfile_id;

    // Create a timer with a two-second interval.
        aTimer = new Timer(5000);
       
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

    public static void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        // Ensure the timer is stopped so we don't try saving multiple times at once
        aTimer.Stop();
        SaveFileLocally();

        //Restart Timer
        aTimer.Start();
    }


    public static void SaveFileLocally()
    {
        
        FileInfo originalfile = new FileInfo(_originalfile_id);
        byte[] originalcontent = GetFileContent(originalfile);
        
        //the content in WOPI Editor
        byte[] editedcontent = WOPITextbox.content
        
        if (originalcontent.Length == editedcontent.Length)
        {
            for (int i = 0; i < originalcontent.Length; i++)
            {
                if (originalcontent[i] != editedcontent[i])
                {
                    SaveLocally(_Id, editedcontent);

                    return;
                }
            }
            return;
        }
        SaveLocally(_Id, editedcontent);
        return;
    }

How to get this content opened in WOPI for editing something like this: byte[] editedcontent = WOPITextbox.content


Solution

  • What you are describing would require the WOPI client (Office Online) to expose some kind of a browser API that would contain the current value of an edited document in a byte array. That's not the case. The only way to interact with the currently edited document is via the PostMessage API which offers quite a limited set of interactions. If you want to store the file periodically in a local storage, different than the WOPI Host storage, I'd recommend using the WOPI Host's API.