Save Documents to AWS S3 in JavaScript DOCX Editor

28 Aug 202612 minutes to read

To save a document to AWS S3, follow the steps below.

Step 1: Create a simple JavaScript DOCX Editor (Document Editor) sample in JavaScript (ES5).

Follow the instructions provided in this link to create a simple DOCX Editor sample in JavaScript. This will give you a basic setup of the DOCX Editor component.

Step 2: Modify the DocumentEditorController.cs File in the Web Service Project

  • Create a web service project in .NET Core 3.0 or above. You can refer to this link for instructions on how to create a web service project.

  • Open the DocumentEditorController.cs file in your web service project.

  • Import the required namespaces at the top of the file:

using System.IO;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
  • Add the following private fields and constructor parameters to the DocumentEditorController class. In the constructor, assign the values from the configuration to the corresponding fields.
private IConfiguration _configuration;
public readonly string _accessKey;
public readonly string _secretKey;
public readonly string _bucketName;

public DocumentEditorController(IWebHostEnvironment hostingEnvironment, IMemoryCache cache, IConfiguration configuration)
{
  _hostingEnvironment = hostingEnvironment;
  _cache = cache;
  _configuration = configuration;
  _accessKey = _configuration.GetValue<string>("AccessKey");
  _secretKey = _configuration.GetValue<string>("SecretKey");
  _bucketName = _configuration.GetValue<string>("BucketName");
}
  • Create the SaveToS3() method to save the document to AWS S3 bucket
[AcceptVerbs("Post")]
[HttpPost]
[EnableCors("AllowAllOrigins")]
[Route("SaveToS3")]
//Post action to save the document to AWS S3

public void SaveToS3(IFormCollection data)
{
  if (data.Files.Count == 0)
    return;
  RegionEndpoint bucketRegion = RegionEndpoint.USEast1;
  // Configure the AWS SDK with your access credentials and other settings
  var s3Client = new AmazonS3Client(_accessKey, _secretKey, bucketRegion);
  string bucketName = _bucketName;
  IFormFile file = data.Files[0];
  string documentName = this.GetValue(data, "documentName");
  string result = Path.GetFileNameWithoutExtension(documentName);
  Stream stream = new MemoryStream();
  file.CopyTo(stream);
  var request = new PutObjectRequest
  {
    BucketName = bucketName,
    Key = result + "_downloaded.docx",
    InputStream = stream,
  };
  // Upload the document to AWS S3
  var response = s3Client.PutObjectAsync(request).Result;
}

private string GetValue(IFormCollection data, string key)
{
    if (data.ContainsKey(key))
    {
        string[] values = data[key];
        if (values.Length > 0)
        {
            return values[0];
        }
    }
    return "";
}
  • Open the appsettings.json file in your web service project. Add the following lines below the existing "AllowedHosts" configuration.
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AccessKey": "Your Access Key from AWS S3",
  "SecretKey": "Your Secret Key from AWS S3",
  "BucketName": "Your Bucket name from AWS S3"
}

Replace Your Access Key from AWS S3, Your Secret Key from AWS S3, and Your Bucket name from AWS S3 with your actual AWS access key, secret key, and bucket name.

Step 3: Modify the index file in the DOCX Editor sample

On the client side, export the document to a blob using saveAsBlob and send it to the server side for saving in an AWS S3 Bucket.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 DocumentEditor</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Typescript UI Controls">
    <meta name="author" content="Syncfusion">
    <!-- EJ2 Document Editor dependent theme -->
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/material.css" rel="stylesheet" type="text/css"
        rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-buttons/styles/material.css" rel="stylesheet" type="text/css"
        rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-inputs/styles/material.css" rel="stylesheet" type="text/css"
        rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-popups/styles/material.css" rel="stylesheet" type="text/css"
        rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-lists/styles/material.css" rel="stylesheet" type="text/css"
        rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-navigations/styles/material.css" rel="stylesheet"
        type="text/css" rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-splitbuttons/styles/material.css" rel="stylesheet"
        type="text/css" rel='nofollow' />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-dropdowns/styles/material.css" rel="stylesheet"
        type="text/css" rel='nofollow' />

    <!-- EJ2 Document Editor theme -->
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-documenteditor/styles/material.css" rel="stylesheet"
        type="text/css" rel='nofollow' />

    <!-- EJ2 Document Editor dependent scripts -->
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/dist/global/ej2-base.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-data/dist/global/ej2-data.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-svg-base/dist/global/ej2-svg-base.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-file-utils/dist/global/ej2-file-utils.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-compression/dist/global/ej2-compression.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-pdf-export/dist/global/ej2-pdf-export.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-buttons/dist/global/ej2-buttons.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-popups/dist/global/ej2-popups.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-splitbuttons/dist/global/ej2-splitbuttons.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-inputs/dist/global/ej2-inputs.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-lists/dist/global/ej2-lists.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-navigations/dist/global/ej2-navigations.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-dropdowns/dist/global/ej2-dropdowns.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-calendars/dist/global/ej2-calendars.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-charts/dist/global/ej2-charts.min.js"
        type="text/javascript"></script>
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-office-chart/dist/global/ej2-office-chart.min.js"
        type="text/javascript"></script>
    <!-- EJ2 Document Editor script -->
    <script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-documenteditor/dist/global/ej2-documenteditor.min.js"
        type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div>
        <button id="export">Save to AWS S3 Bucket</button>
    </div>
    <div id='DocumentEditor' style='height:620px'></div>
    <script>
        // Initialize DocumentEditorContainer component.
        var documenteditorContainer = new ej.documenteditor.DocumentEditorContainer({ enableToolbar: true, height: '590px' });
        ej.documenteditor.DocumentEditorContainer.Inject(ej.documenteditor.Toolbar);
        documenteditorContainer.serviceUrl = 'http://localhost:62870/api/documenteditor/';
        //DocumentEditorContainer control rendering starts
        documenteditorContainer.appendTo('#DocumentEditor');
        document.getElementById('export').addEventListener('click', function () {
            save();
        });

        async function save() {
            container.documentEditor.saveAsBlob('Docx').then((blob) => {
                var exportedDocument = blob;
                //Now, save the document where ever you want.
                var formData = new FormData();
                formData.append('documentName', container.documentEditor.documentName);
                formData.append('data', exportedDocument);
                /* tslint:disable */
                var req = new XMLHttpRequest();
                // Replace your running Url here
                req.open(
                    'POST',
                    'http://localhost:62870/api/documenteditor/SaveToS3',
                    true
                );
                req.onreadystatechange = () => {
                    if (req.readyState === 4) {
                        if (req.status === 200 || req.status === 304) {
                            console.log('Saved sucessfully');
                        }
                    }
                };
                req.send(formData);
            });
        }
    </script>
</body>

</html>

The AWSSDK.S3 NuGet package must be installed in your application to use the previous code example.