Contract delivery usually calls for PDF, archiving may call for DOCX, and some pages also need to export HTML or TXT. Spire.OfficeJS converts the document currently in the editor into these formats and hands it to the browser for download. This article uses Word as an example to explain how to convert and download documents with Spire.OfficeJS:

Document conversion and download process

The download takes four steps:

Spire.OfficeJS document conversion and download process

  1. The user opens a document in the editor.
  2. The user clicks the convert-and-download button on the page, which calls docEditor.downloadAs() with the target format.
  3. The editor converts the current document to the target format.
  4. The browser downloads the document locally.

Using downloadAs

The editor provides the downloadAs() method to convert the current document to a specified format and hand it to the browser for download. You can call it once the editor is initialized; the conversion runs in the browser, and the result is a local copy.

Example configuration (converting to PDF):

var onDownloadAs = function () {
  docEditor.downloadAs({ format: 'pdf'});
};

format takes the target format's file extension and is case-insensitive.

Complete code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Spire.OfficeJS Convert File - downloadAs</title>
  <style>
    html, body { height: 100%; margin: 0; }
    body { display: flex; flex-direction: column; }
    #editor { flex: 1; min-height: 0; }
    #editor iframe { width: 100%; height: 100%; border: 0; }
  </style>
</head>
<body>
  <button type="button" id="download" onclick="onDownloadAs()" disabled>Download PDF</button>
  <div id="editor"></div>
  <script src="http://LocalExample:3000/web/editors/spireapi/SpireCloudEditor.js"></script>
  <script>
    var SERVER = 'http://LocalExample:3000';
    var downloadButton = document.getElementById('download');

    var config = {
      fileAttrs: {
        fileInfo: { name: 'sample.docx', ext: 'docx' },
        sourceUrl: SERVER + '/samples/sample.docx'
      },
      user: { id: 'uid-1', name: 'Jonn' },
      editorAttrs: {
        editorMode: 'edit',
        editorType: 'document',
        viewLanguage: 'en',
        canDownload: true,
        useWebAssemblyDoc: true,
        serverless: { useServerless: true, baseUrl: SERVER },
        events: {
          onStart: function () {
            downloadButton.disabled = false;
          }
        }
      }
    };

    var docEditor = new SpireCloudEditor.OpenApi('editor', config);

    function onDownloadAs() {
      docEditor.downloadAs({ format: 'pdf' });
    }
  </script>
</body>
</html>

After selecting a document and clicking the download button, the editor converts it and the browser downloads the resulting PDF:

DownloadAs in action

Supported formats

The formats you can convert to depend on the editor that opened the document. Word, Excel, and Presentation load on different pages and support different target formats, so pick the format for the editor that matches the document. The target formats supported by each editor are listed below:

Editor Supported formats
Spire.WordJS DOCX, PDF, PDFA, ODT, DOTX, OTT, RTF, HTML, TXT
Spire.ExcelJS XLSX, XLTX, PDF, PDFA, CSV, ODS, OTS
Spire.PresentationJS PPTX, PDF, ODP, POTX, OTP

FAQ

Does downloading modify the original document or trigger save callbacks

Cause: Downloading does not call callbackUrl or onSave, and it does not write back to sourceUrl; it only generates the document in the browser and downloads it.

Solution: No extra handling is needed. The download is a local copy; neither the original document nor the one in your business system is modified.

format is set, but the downloaded document's format does not change

Cause: If format is unrecognized, the document editor falls back to the document's original format.

Solution: Use the target formats listed for the matching editor in the supported formats table. For example, with sample.docx as the original and format: 'bogus', the downloaded document is still sample.docx.

Can multiple documents be converted at once

Cause: downloadAs() converts only the document currently open in the editor, and one call produces one document in the target format.

Solution: To convert multiple documents, open each document in turn and call downloadAs() for each one, for example by opening the next document after each conversion on the business page.

Spire.OfficeJS License Configuration

2026-10-28 03:54:46 Written by liu talia

A valid License is required after Spire.OfficeJS is deployed. Without a License, opened documents show a red trial notice and the content is restricted: Word is limited to 500 paragraphs and 25 tables, Excel to 5 worksheets with up to 200 rows per worksheet, and Presentation and PDF to 10 pages. For details on the restrictions, see the trial version notes on the official download page.

Get a License

To purchase a License or apply for a 30-day temporary License, contact sales@e-iceblue.com. When you contact us, please provide the IP address or domain name of the server you plan to deploy on, and the email address that should receive the license file.

After purchasing or applying for a trial, you will receive a license file in XML format, usually named license.elic.xml. Open the file with a text editor, copy the value of the Key attribute from the root element <License Key="..."> (without the quotes and tags), and fill it into the corresponding field in the table below. The file is digitally signed; do not modify it.

License configuration

The bundled example system and your own frontend project use the same license fields; only the location where you configure them differs. The licensed products and their corresponding fields are:

Licensed product License field
Spire.OfficeJS spireOfficeJsLicense
Spire.WordJS spireDocJsLicense
Spire.ExcelJS spireXlsJsLicense
Spire.PresentationJS spirePresentationJsLicense
Spire.PDFJS spirePdfJsLicense

Whichever product you purchased, fill its License Key into the corresponding field, and leave the fields for products you have not purchased as empty strings "". For example, if you only purchased Spire.WordJS, fill in spireDocJsLicense:

"editorAttrs": {
  "spireDocJsLicense": "WordJS License Key",
  "spireXlsJsLicense": "",
  "spirePresentationJsLicense": "",
  "spirePdfJsLicense": "",
  "spireOfficeJsLicense": ""
}

If you purchased the Spire.OfficeJS suite license, fill in only spireOfficeJsLicense and leave the other four fields empty. The suite already includes Spire.WordJS, Spire.ExcelJS, Spire.PresentationJS, and Spire.PDFJS.

Where to configure the License depends on how you use Spire.OfficeJS: use the example system bundled with the product package for a quick trial, or integrate the editor into your own frontend project.

Option 1: Use the bundled example system (default port 3000)

When using the example system bundled with the product package, the license fields are located under server.customization in example/config/default.json. Only the license fields are listed below; leave the other settings unchanged:

"customization": {
  "spireDocJsLicense": "WordJS License Key",
  "spireXlsJsLicense": "",
  "spirePresentationJsLicense": "",
  "spirePdfJsLicense": "",
  "spireOfficeJsLicense": ""
}

After saving, restart the example service for the new configuration to take effect.

Option 2: Integrate into your own frontend project

In your own frontend project, the license fields are written under the editorAttrs object passed to the editor. For example, in Vue:

config.value = {
        "editorAttrs": {
            "spireDocJsLicense": "WordJS License Key",
            "spireXlsJsLicense": "",
            "spirePresentationJsLicense": "",
            "spirePdfJsLicense": "",
            "spireOfficeJsLicense": "",
        }
    };

Other frameworks work the same way: find editorAttrs in your configuration and fill in the same fields.

For complete integration steps for each framework, see: JavaScript, Vue, React, Angular.

Take effect and verify

After modifying editorAttrs, save and refresh the page for the changes to take effect. When only the frontend configuration is changed, there is no need to restart OfficeServer.

  • Vue / React (Vite): hot reload usually applies the changes automatically. If the editor does not reload, refresh the page first; if that still does not work, run npm run dev.
  • Angular: if the changes do not take effect, run ng serve.

After making the changes, open a document of a licensed product and check whether the red trial notice is gone. For a suite license, open one document each in Word, Excel, Presentation, and PDF to verify.

The Spire.OfficeJS review feature records modifications as revision marks instead of overwriting the original text. This state is often called review mode (also known as track-changes mode), where all changes are kept as suggestions layered over the original text, waiting for a reviewer to handle them. Once Track Changes is on, insertions, deletions, and formatting adjustments are recorded with their author, and other people can inspect, accept, or reject them one by one. This article uses Word as an example to explain the operations and permission configuration. In this article, "review" refers to the revision-related features on the Review tab.

Review Tab Capabilities

The Review tab in the Word editor provides the following revision-related capabilities:

Capability UI Location Description
Track Changes toggle Review → Track Changes When on, new edits are recorded as revisions instead of changing the body text directly
Display mode Review → Display Mode Switches the view between "All Markup", "No Markup", and "Original"
Reviewing pane Review → Reviewing Pane Lists the revisions in the document in one place, click a revision to jump to its location
Previous / Next Review Browses revisions one by one
Accept / Reject Review Accepts or rejects the current revision, or processes all revisions at once
Restrict Editing Review → Restrict Editing Protects the document, can be set to read-only, or to allow changes only as tracked changes

The following sections explain display modes and the accept and reject operations. The other capabilities can be used directly from the locations listed in the table.

Display Modes

Option UI Description Actual Meaning
All Markup All changes (edits) Shows all revision marks, suitable for editing and reviewing one by one
No Markup Accepted all changes (preview) Previews the result after "Accept All", without actually accepting revisions
Original Rejected all changes (preview) Previews the result after "Reject All", without actually rejecting revisions

Note

"No Markup" and "Original" are previews only. To truly remove revisions, you must use "Accept" or "Reject". If you switch the display mode and then save, the revisions remain in the document.

Accept and Reject Revisions

"Accept" and "Reject" process one revision at a time by default and then jump to the next one. The drop-down menu can process all revisions at once, or you can click a revision mark in the body text to choose directly. Accepting or rejecting changes the body text directly, and you can undo before saving.

Configure Review Capabilities

Revision capabilities are controlled by editorAttrs: canReview determines whether review is enabled, and canEdit determines whether editing is allowed.

editorAttrs: {
  editorMode: 'edit',
  canEdit: true,
  canReview: true
}

Review operations

Review State on Open

The review state when a document opens is controlled by two switches under user.customization.public.common. Both are false by default, and you can turn them on individually as needed:

  • openReviewChanges: true: enters the track-changes state immediately after the document opens, so you do not need to click "Track Changes" manually.
  • openReviewPanel: true: expands the reviewing pane when the document opens, suitable for handling revisions in one place, and requires canReview to be true.
user: {
  customization: {
    public: {
      common: {
        openReviewChanges: true, // enters the track-changes state immediately after the document opens
        openReviewPanel: true    // expands the reviewing pane when the document opens
      }
    }
  }
}

Track-changes state and reviewing pane

Read-Only Review

External reviewers can only view revisions and the reviewing pane. They cannot change the body text, and they cannot accept or reject revisions:

editorAttrs: {
  editorMode: 'edit',
  canEdit: false,
  canReview: true
}

Read-only review

Disable Review

editorAttrs: {
  canReview: false
}

Users can still edit normally, but the Review tab no longer provides revision-related capabilities. Disabling review

Control Review-Related Buttons

canReview only toggles the review capability as a whole. If you want to hide only some buttons (for example, keep viewing and navigation but remove "Accept" and "Reject"), configure user.customization.public.common.btnPermissions.docBtnPermissions. Removed buttons and their corresponding shortcuts are disabled as well:

user: {
  customization: {
    public: {
      common: {
        btnPermissions: {
          docBtnPermissions: [
            { modular: 'Toolbar', subModule: ['btnTurnOn', 'Accept', 'Reject'] }
          ]
        }
      }
    }
  }
}

Review-Related Buttons

For more about button permission configuration, see the documentation on customizing the toolbar menu.

FAQ

The Track Changes toggle or Accept/Reject buttons are unavailable

Common causes are that the current session is in read-only review (canEdit: false, canReview: true), the document is protected, or the user does not have edit permission. Read-only review can view revisions but cannot toggle Track Changes or accept or reject revisions. If a reviewer needs to handle revisions, they must be given edit permission. If they need to handle revisions but should not change the body text freely, enable "Restrict Editing → Tracked Changes", so that all modifications can only be produced as tracked changes.

The Review tab is not visible after opening a document

Check the following in order:

  1. Whether editorAttrs.editorMode is edit. view mode does not provide editing or review.
  2. Whether editorAttrs.canReview is true, and whether both canEdit: true and a valid license are available.
  3. Whether btnReview was removed through btnPermissions, or the document is protected as read-only.

Revision authors are wrong or all the same

Revision authors come from user.name in the current session, and the user identity comes from user.id. Make sure each user uses a unique, stable id, pass the correct display name when opening the document, and do not let multiple users share a fixed account.

Page 3 of 371
page 3