Set Excel Workbook Summary and Custom Properties in React

A workbook exported by a reporting system usually carries nothing but the system name as its author, with the title, subject and keywords left blank; teams meanwhile need to attach fields the export does not produce — an export batch, an owner, an approval state — for archiving and searching. None of this takes up a cell: it all lives in the workbook's document properties, which Excel shows under "File > Info > Properties". Spire.XLS for JavaScript writes them in the browser on top of WebAssembly, using a virtual file system (VFS) for input and output files, so no back-end service is needed.

This article covers three feature points:

For installation and project setup, see Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module has been initialised.


Set the summary properties of a workbook

The summary properties are the layer of description Excel shows in File Explorer and under "File > Info", and the first thing a search of the archive picks up. A workbook produced by a program usually has only the system name as its author and leaves the other entries blank; filling them in gives the file a readable context as it moves between people. The text entries take a plain assignment, while the two date entries have to be given a date object. The steps are:

  1. Load the workbook and take the summary property collection from workbook.DocumentProperties.
  2. Assign the text entries — Title, Subject, Author, Keywords, Comments and Category — directly.
  3. Assign Company and Manager the same way; Excel carries these two in its extended properties.
  4. Set CreatedTime and LastSaveTime to Date objects.
  5. Save the workbook.

Here is a complete code example showing how to set the summary properties of a workbook in React:

function App() {
  const setSummaryProperties = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);

    // Load the Excel file into the VFS
    const inputFileName = 'WorkbookProperties.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile(inputFileName);

    // Set the text entries of the summary properties
    const summary = workbook.DocumentProperties;
    summary.Title = 'Q3 2026 Sales Report';
    summary.Subject = 'Quarterly results by sales department';
    summary.Author = 'E-iceblue';
    summary.Keywords = 'sales, report, Excel';
    summary.Comments = 'Summary filled in after the export';
    summary.Category = 'Sales Report';

    // Set the entries carried by the extended properties
    summary.Company = 'E-iceblue';
    summary.Manager = 'Sales Manager';

    // Set the document dates; a Date object is required here
    summary.CreatedTime = new Date(2026, 8, 1);
    summary.LastSaveTime = new Date(2026, 8, 20);

    // Save the workbook
    const outputFileName = 'SetSummaryProperties.xlsx';
    workbook.SaveToFile(outputFileName);

    // Release resources
    workbook.Dispose();

    // Read the result file back out of the VFS and download it
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Set workbook summary properties</h1>
      <button onClick={setSummaryProperties}>Start</button>
    </div>
  );
}

export default App;

The effect of setting the summary properties of a workbook:

Set the workbook summary properties


Add custom properties

Custom properties carry the business fields the summary properties have no room for, such as an export batch, a contact phone number, a revision number or an approval date. Unlike the summary properties they have no fixed set of entries: the caller decides the name and the type, and Excel accepts text, integer, decimal, boolean and date-and-time values. The steps are:

  1. Load the workbook and take the custom property collection from workbook.CustomDocumentProperties.
  2. Call Add to append a property; the name and the value can be written as a named object such as { strName, boolValue }, or passed directly as two arguments.
  3. Pick the member that matches the type of the value: intValue for an integer, dblValue for a decimal.
  4. Pass a Date object as dtValue for a date-and-time value.
  5. Save the workbook.

Here is a complete code example showing how to add custom properties to a workbook in React:

function App() {
  const addCustomProperties = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);

    // Load the Excel file into the VFS
    const inputFileName = 'WorkbookProperties.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile(inputFileName);

    // Add a boolean property; _MarkAsFinal marks the document as final
    workbook.CustomDocumentProperties.Add({ strName: '_MarkAsFinal', boolValue: true });

    // Add a text property; a name and a value can also be passed directly
    workbook.CustomDocumentProperties.Add('The Editor', 'E-iceblue');

    // Add an integer property
    workbook.CustomDocumentProperties.Add({ strName: 'Phone number', intValue: 81705109 });

    // Add a decimal property
    workbook.CustomDocumentProperties.Add({ strName: 'Revision number', dblValue: 7.12 });

    // Add a date and time property
    workbook.CustomDocumentProperties.Add({ strName: 'Revision date', dtValue: new Date(2026, 8, 1) });

    // Save the workbook
    const outputFileName = 'AddCustomProperties.xlsx';
    workbook.SaveToFile(outputFileName);

    // Release resources
    workbook.Dispose();

    // Read the result file back out of the VFS and download it
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add custom properties</h1>
      <button onClick={addCustomProperties}>Start</button>
    </div>
  );
}

export default App;

The effect of adding custom properties:

Add custom properties


Update the value of a custom property

The value of a business field changes with the way it is counted: an export record count, say, has to be rewritten to a new figure once the data is topped up. Custom properties offer no member that assigns a value directly, but Add is keyed on the name — calling it again for a name that already exists does not append a duplicate entry, it replaces the value of the existing one. The steps are:

  1. Load the workbook and take the custom property collection from workbook.CustomDocumentProperties.
  2. Call Add again, passing the same name as the existing entry together with the new value.
  3. Save the workbook.

Here is a complete code example showing how to update a custom property of a workbook in React:

function App() {
  const updateCustomProperties = async () => {
    // Get the Spire.XLS WASM module
    const xlsModule = window.wasmModule?.spirexls;

    // Check that the module is ready
    if (!xlsModule) {
      alert('Spire.Xls is not ready yet');
      return;
    }

    // Load the font into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);

    // Load the Excel file into the VFS
    const inputFileName = 'WorkbookProperties.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile(inputFileName);

    // Rewrite the exported record count; adding an existing name overwrites it
    workbook.CustomDocumentProperties.Add({ strName: 'ExportedRecords', intValue: 256 });

    // Save the workbook
    const outputFileName = 'UpdateCustomProperties.xlsx';
    workbook.SaveToFile(outputFileName);

    // Release resources
    workbook.Dispose();

    // Read the result file back out of the VFS and download it
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Update the value of a custom property</h1>
      <button onClick={updateCustomProperties}>Start</button>
    </div>
  );
}

export default App;

The effect of updating the value of a custom property:

Update the value of a custom property


FAQ

Why does assigning to CreatedTime throw "Assert failed: Value is not a Date"

Cause: CreatedTime and LastSaveTime take a JavaScript Date object and nothing else. A date string such as '2026-09-01', a timestamp number, or a hand-made object that only carries a toISOString() method all fail the type check and throw Assert failed: Value is not a Date.

Solution: build the Date with new Date(...) first, then assign it:

// 1 September 2026; months count from 0, so 8 means September
workbook.DocumentProperties.CreatedTime = new Date(2026, 8, 1);

Why does assigning to the Value of a custom property throw ArgumentNull_Generic

Cause: the Value property only reads. Assigning to it throws ArgumentNull_Generic Arg_ParamName_Name, value, and the original value does not change. Updating an existing property has to go through Add.

Solution: overwrite the original value with a same-name Add:

workbook.CustomDocumentProperties.Add({ strName: 'ExportedRecords', intValue: 256 });

Get a Free License

Spire.XLS for JavaScript offers a 30-day full-featured free trial license with no functional limitations. Apply here to evaluate before purchasing.