Document Editing Made Easy: Syncfusion Word Processor + Wisej

Suresh Mohan - May 5 '22 - - Dev Community

A challenge we see while working on modernization projects for desktop applications involves local file access. Web projects have a completely different approach to working with user files that don’t include unrestricted access to the client’s file system. Until recently, if you wanted to modify a file on the client’s file system, you had to go through traditional upload and download dialogs, ending up with the same document multiple times in the downloads folder.

With the introduction of Wisej’s Syncfusion Essential Studio JS integration and the Client File System API, working with local user files is a breeze. In this blog post, we show several different ways to integrate Word documents into the JS 2 Word Processor control.

The first approach uses the server’s file system. The second approach shows the integration using Wisej’s Client File System extension.

About Wisej

Wisej is a powerful SPA web framework for C# and VB.NET developers. It helps us to migrate existing WinForms, VB6, and Visual Web GUI applications to a modernized, cross-platform solution with minimal code changes. We can easily migrate the existing Syncfusion controls for desktop to their corresponding web-based equivalents without the hassle of entirely rewriting the application. Wisej features a pixel-perfect WYSIWYG designer that helps us to drag and drop controls, assign properties, and attach events with the click of a button. Hot reload and a powerful theming system allows developers to see changes in real-time.

If you’ve never used Wisej before, you can get it here.

Getting started

To use the JS 2 Word Processor in Wisej, we have to add several Syncfusion libraries to the project:

  • Syncfusion.Compression.Base
  • Syncfusion.DocIO.Base
  • Syncfusion.EJ2.DocumentEditor
  • Syncfusion.Licensing
  • Syncfusion.OfficeChart.Base

We can easily retrieve these libraries from the Syncfusion website.

You can download the full demo project here.

Retrieving documents on the server

We can fetch documents from the server’s file system and show them in the client’s browser using a few simple calls in Wisej.

To get started, load a Word document into a Stream.

var stream = new FileStream(Application.MapPath("Some/Location/In/My/App.docx"), FileMode.Open);
Enter fullscreen mode Exit fullscreen mode

Once the file is in a stream, it can be loaded into a WordDocument(Syncfusion.EJ2.DocumentEditor.WordDocument) instance:

using (var stream = new FileStream(Application.MapPath("Some/Location/In/My/App.docx"), FileMode.Open))
{
  var document = WordDocument.Load(stream, FormatType.Docx);
}

Enter fullscreen mode Exit fullscreen mode

We can serialize the WordDocument instance to get the corresponding Syncfusion Document Text (SFDT) string.

using (var stream = new FileStream(Application.MapPath("Some/Location/In/My/App.docx"), FileMode.Open))
{
  var document = WordDocument.Load(stream, FormatType.Docx);
  var sfdt = JsonConvert.SerializeObject(document);
}

Enter fullscreen mode Exit fullscreen mode

Once we have the SFDT, we can add a Syncfusion Word Processor (documentEditor in the code) from the Wisej toolbox and load the text into the widget.

Hint: If the DocumentEditor control is missing from the Toolbox, you can right-click the toolbox, choose items, and select the Wisej.Web.Ext.Syncfusion2.dll.

using (var stream = new FileStream(Application.MapPath("Some/Location/In/My/App.docx"), FileMode.Open))
{
  var document = WordDocument.Load(stream, FormatType.Docx);
  var sfdt = JsonConvert.SerializeObject(document);
  this.documentEditor1.OpenFile(sfdt);
}

Enter fullscreen mode Exit fullscreen mode

Design-Time Experience of JS 2 Word Processor in Wisej

Design-Time Experience of JS Word Processor in Wisej

Resulting JS 2 Word Processor

Resulting JS Word Processor

Retrieving documents from the client

We can fetch the documents from the client’s file system and show them within the Wisej app without a traditional upload dialog.

To get started, add the Wisej.Ext.ClientFileSystem extension to the project.

After adding the extension, the Wisej application can access directories on the local file system through the browser’s File System Access API.

It is important to note that read and write permissions must be granted for each directory (unless a member of the directory’s upper hierarchy has already approved access). File access is revoked upon a page refresh, so it is important to request access again.

// get a directory from the client. 
var directoryHandle = await ClientFileSystem.ShowDirectoryPickerAsync();   

// get the files from that directory. 
var fileHandles = await directoryHandle.GetFilesAsync("*.docx");
Enter fullscreen mode Exit fullscreen mode

After retrieving the files, the contents of a file can be queried.

// get a directory from the client. 
var directoryHandle = await ClientFileSystem.ShowDirectoryPickerAsync();   

// get the files from that directory. 
var fileHandles = await directoryHandle.GetFilesAsync("*.docx"); 
if (fileHandles.Length > 0) 
{ 
   // load the first Word document. 
   var fileHandle = fileHandles[0];
  // save a reference to the file if using it later. 
  this.selectedFileHandle = fileHandle;   

  // query read and write permissions on the file. 
  var state = await fileHandle.QueryPermissionAsync(Permission.ReadWrite); 
  if (state == PermissionState.Granted) 
  { 
     // read and load the file. 
     var bytes = await fileHandle.ReadBytesAsync(); 
  } 
}
Enter fullscreen mode Exit fullscreen mode

The rest is the same as the server-side file loading.

// get a directory from the client. 
var directoryHandle = await ClientFileSystem.ShowDirectoryPickerAsync();   

// get the files from that directory. 
var fileHandles = await directoryHandle.GetFilesAsync("*.docx"); 
if (fileHandles.Length > 0) 
{ 
  // load the first Word document. 
  var fileHandle = fileHandles[0];   

  // query read and write permissions on the file. 
  var state = await fileHandle.QueryPermissionAsync(Permission.ReadWrite); 
  if (state == PermissionState.Granted) 
  { 
    var bytes = await fileHandle.ReadBytesAsync(); 
    using (var stream = new MemoryStream(bytes)) 
    { 
      var document = WordDocument.Load(stream, FormatType.Docx); 
      var sfdt = JsonConvert.SerializeObject(document);   

      this.documentEditor1.OpenFile(sfdt); 
    } 
  } 
}
Enter fullscreen mode Exit fullscreen mode

Saving documents

The documents have been loaded into the client-side viewer, we can now save the documents back to the server or to the client.

To retrieve the document stream from the client, simply use the following.

var document = await this.documentEditor1.GetDocumentAsync();

Enter fullscreen mode Exit fullscreen mode

Saving server-side documents

To save a document to a server location, simply use System.IO.File.WriteAllBytes().

System.IO.File.WriteAllBytes(Application.MapPath("path/to/file.docx"), document.ToArray());
Enter fullscreen mode Exit fullscreen mode

Saving client-side documents

To save the document to a client-side location, use the reference from the client-side file handle.

this.selectedFileHandle.WriteBytesAsync(document.ToArray(), 0, WritableType.Write, false);
Enter fullscreen mode Exit fullscreen mode

Opening client-side documents using Word

When using the client’s file system to load documents into the viewer, documents can be opened directly in Word from a Wisej application.

Microsoft Office includes a custom data scheme (ms-word://) that provides functionality to open a file path in Word from the browser. You can learn more about it here.

As an example, we can directly open a client-side file located at F:/Play/Test.docx from a Wisej application using Application.Navigate().

Keep in mind the full path of the directory must be known to the Wisej application and the path cannot contain spaces.

Application.Navigate("ms-word:ofe|u|F:/Play/Test.docx");
Enter fullscreen mode Exit fullscreen mode

Also, you can get the demo project from GitHub here. I hope this blog has been helpful to you. Thank you for reading.

Related blogs

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .