In daily work, we often need to hide some worksheets to simplify the interface display or protect sensitive data, and we can unhide them when necessary. In addition, when converting a workbook to HTML, you may also need to control whether hidden worksheets appear in the conversion result. Spire.XLS for JavaScript performs these operations directly in the browser based on WebAssembly, managing input and output files through the virtual file system (VFS), without any backend service support.

This article covers three core feature points:

For installation and project configuration, please refer to How to Integrate Spire.XLS for JavaScript in a React Project. The following examples assume that Spire.XLS is installed and the WebAssembly module has been initialized.


Hide a Worksheet

Hiding a worksheet is often used to simplify the display of a workbook or protect internal data. With Spire.XLS for JavaScript, you can hide a specified worksheet by setting the Visibility property of the worksheet object to WorksheetVisibility.Hidden.

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

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

    // Load the font and Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'HideOrShowWorksheet.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the worksheet named "Sheet1" and hide it
    let sheet1 = workbook.Worksheets.get("Sheet1");
    sheet1.Visibility = xlsModule.WorksheetVisibility.Hidden;

    // Save the workbook
    const outputFileName = "HideWorksheet_output.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger the download
    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>Hide Worksheet</h1>
      <button onClick={hideSheet}>
        Start
      </button>
    </div>
  );
}

export default App;

Original document (Sheet2 is already hidden) Original document Hide Sheet1 Hide Sheet1


Show a Hidden Worksheet

When you need to view or edit a hidden worksheet again, you can show it again by setting the Visibility property to WorksheetVisibility.Visible.

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

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

    // Load the font and Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'HideOrShowWorksheet.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the second worksheet and set it as visible
    let sheet2 = workbook.Worksheets.get(1);
    sheet2.Visibility = xlsModule.WorksheetVisibility.Visible;

    // Save the workbook
    const outputFileName = "ShowWorksheet_output.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger the download
    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>Show Worksheet</h1>
      <button onClick={showSheet}>
        Start
      </button>
    </div>
  );
}

export default App;

Unhide Sheet2 Unhide Sheet2


Control Whether to Include Hidden Worksheets When Converting to HTML

When converting to HTML, you can use the skipHideSheet parameter of the SaveToHtml method to control whether hidden worksheets are included in the conversion result. When set to false, the generated HTML includes hidden worksheets; when set to true, hidden worksheets are skipped and only visible worksheets remain in the HTML.

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

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

    // Load the font and Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'HideOrShowWorksheet.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Hide the worksheet named "Sheet1"
    let sheet1 = workbook.Worksheets.get("Sheet1");
    sheet1.Visibility = xlsModule.WorksheetVisibility.Hidden;

    // Set the output HTML file name
    const result = "result.html";

    // false --- Save HTML with hidden worksheets
    // true --- Save HTML without hidden worksheets
    workbook.SaveToHtml({
      fileName: result,
      skipHideSheet: false
    });

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(result);
    const blob = new Blob([fileArray], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = result;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Convert Workbook to HTML</h1>
      <button onClick={saveToHtml}>
        Start
      </button>
    </div>
  );
}

export default App;

After conversion After conversion


FAQ

The HTML conversion result contains extra worksheets

Cause: The original Excel document has multiple hidden worksheets. When the skipHideSheet parameter of SaveToHtml is set to false, all hidden worksheets appear in the conversion result.

Solution: You can use the following code to iterate through and check the hidden state of all sheets in the Excel file.

    const sheetCount = workbook.Worksheets.Count;
    for (let i = 0; i < sheetCount; i++) {
        let sheet = workbook.Worksheets.get(i);
        const visibility = sheet.Visibility;
    }

Get a Free License

If you want to remove the evaluation message in the generated documents or get rid of functional limitations, please contact us to get a temporary license valid for 30 days.

Reconciliation is one of the most frequent and tedious tasks in corporate finance, and the source data often comes in different forms: bank statements are CSV files exported from online banking, while system transaction records may be PDF detail reports. The two tables have different column names, inconsistent date and amount formats, and even stray spaces and missing values. This article shows how to use Spire.Agent.Office Excel AI capabilities to automatically read CSV and PDF data sources, identify and map column names, clean the data, and finally generate an Excel reconciliation detail report.

For product installation and SpireToken configuration, please refer to Integrate Spire.Agent.Office in a .NET Project. The following examples assume Spire.Agent.Office is installed and SpireToken is configured.


Reconcile by Statement Number

Reconcile and analyze the CSV-format bank statement with the PDF-format system transaction records by statement number.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;

// Data source files: bank statement (CSV) and system transaction records (PDF)
string[] attachmentPaths = new string[]
{
    @"bank-statement.csv",   
    @"system-records.pdf"    
};

// Excel processing configuration
string inputPath = "";  
string savePath = "out.xlsx";  
// SpireToken Key
string key = "**************************"; 
string instruction =
    "Reconcile the bank statement (CSV) with the system transaction records (PDF) in the attachments: " +
    "1. Establish the column mapping of the two tables by semantics: transaction date, amount, counterparty account, description, statement number; " +
    "2. Cleaning: strip leading/trailing and internal extra spaces from text; write dates as yyyy-MM-dd text; convert amounts to numbers by removing currency symbols and thousands separators; mark empty description or empty counterparty as 'Unknown', mark empty amount as 'Amount missing'; " +
    "3. Match row by row using the statement number as the unique key, and mark the status: 'Matched'/'Amount mismatch'/'Bank only'/'System only'; " +
    "4. Generate a 'Reconciliation Detail' worksheet: each record with bank amount, system amount, difference, status and remark; " +
    "5. Highlight difference rows: yellow for amount mismatch, orange for bank only, blue for system only; " +
    "Finally save the output as an Excel file";

// Call the Excel document processing function
AIResult result = ExecuteDemoExcel(instruction, inputPath, savePath, key,  attachmentPaths);


// Execute Excel document AI processing
static AIResult ExecuteDemoExcel(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    // Create an AIOptions configuration object
    AIOptions options = new AIOptions();
    options.SpireToken = key; 

    // Use the Workbook object to process the Excel document
    using (Workbook workbook = new Workbook())
    {
        // Load the Excel template from a file
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            workbook.LoadFromFile(inputPath);
        }
        // Create the AI document processor
        AIWorkbookProcessor processor = workbook.AI(options);

        // Execute the AI instruction
        return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
    }
}

Original bank statement CSV Original bank statement CSV Original system transaction PDF Original system transaction PDF Reconciliation detail after Excel AI reconciliation Reconciliation detail after Excel AI reconciliation


Reconcile by Date and Amount Combination

When the data source does not contain a unique statement number, you can use the "transaction date + amount" combination as the matching key for reconciliation: first group by date, then pair the records by amount within the same date.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;

// Data source files without statement numbers: bank statement (CSV) and system transaction records (PDF)
string[] attachmentPaths = new string[]
{
    @"bank-statement-noId.csv",   
    @"system-records-noId.pdf"   
};

// Excel processing configuration
string inputPath = "";  
string savePath = "out.xlsx";  
// SpireToken Key
string key = "**************************";  
string instruction =
    "Reconcile the bank statement (CSV) with the system transaction records (PDF) in the attachments: " +
    "1. Establish the column mapping of the two tables by semantics: transaction date, amount, counterparty account, description; " +
    "2. Cleaning: strip extra spaces from text; write dates as yyyy-MM-dd text; convert amounts to numbers; mark missing values as 'Unknown' or 'Amount missing'; " +
    "3. Use the 'transaction date + amount' combination as the matching key: first group by date, then pair the records by amount within the same date, and mark the status: 'Matched'/'Amount mismatch'/'Bank only'/'System only'; " +
    "4. Generate a 'Reconciliation Detail' worksheet (bank amount, system amount, difference, status); " +
    "5. Highlight difference rows: yellow for amount mismatch, orange for bank only, blue for system only; " +
    "Finally save the output as an Excel file";

// Call the Excel document processing function
AIResult result = ExecuteDemoExcel(instruction, inputPath, savePath, key,  attachmentPaths);


// Execute Excel document AI processing
static AIResult ExecuteDemoExcel(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    // Create an AIOptions configuration object
    AIOptions options = new AIOptions();
    options.SpireToken = key; 

    // Use the Workbook object to process the Excel document
    using (Workbook workbook = new Workbook())
    {
        // Load the Excel template from a file
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            workbook.LoadFromFile(inputPath);
        }
        // Create the AI document processor
        AIWorkbookProcessor processor = workbook.AI(options);

        // Execute the AI instruction
        return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
    }
}

Original bank statement CSV Original bank statement CSV Original system transaction PDF Original system transaction PDF Reconciliation detail after Excel AI reconciliation Reconciliation detail after Excel AI reconciliation


Comparison with Traditional SDK API Processing

Traditional Spire.Office for .NET API Spire.Agent.Office Processing
Driving approach Requires writing large amounts of code for CSV/PDF parsing, column mapping, data cleaning, matching and exception logic Describe reconciliation rules in natural language, and AI understands and orchestrates the execution automatically
Data format CSV and PDF must be parsed with different components, each with its own format Directly attach CSV and PDF, and AI understands the content automatically
Field mapping Hard-coded column name mappings; changing column names or formats requires code changes AI maps columns automatically based on column names and content semantics
Exception handling Need to hand-write difference judgment, alert text and style logic AI automatically identifies differences and provides handling suggestions

Frequently Asked Questions

Inconsistent date and amount formats in the bank statement CSV

Cause: In the CSV exported from online banking, dates may be written as 2026-07-01, 2026/7/1, etc., and amounts may carry , thousands separators, or leading/trailing spaces, leading to misjudgment during matching.

Solution: Explicitly require in the instruction "unify dates as yyyy-MM-dd and amounts as numeric formats and remove spaces", and AI will complete the standardization automatically before reconciliation.

The system transaction PDF table spans pages or has headers/footers

Cause: PDF detail reports may have pagination, repeated headers, or footer annotations, which affect AI's reading of the table data.

Solution: Add "ignore headers/footers and repeated header rows, only read the table data rows" to the instruction.

The same amount appears multiple times on the same day, causing mismatches

Cause: When reconciling by the "date + amount" combination, there may be multiple transactions with the same amount on the same day, making the exact correspondence impossible to determine.

Solution: Prefer precise reconciliation by statement number; if there is really no statement number, you can require in the instruction to "mark records that cannot be matched one-to-one on the same day as 'Amount mismatch'".


Get a SpireToken Key

Configure it in code:

AIOptions options = new AIOptions();
options.SpireToken = key;

When browsing an Excel worksheet that contains a large amount of data, pinning the header or key columns can significantly improve the efficiency of data viewing. The freeze panes feature keeps the specified rows or columns visible while scrolling. Querying the frozen pane range confirms which areas of the current worksheet are frozen. Unfreezing panes restores the normal browsing mode when the fixed display is no longer needed. Spire.XLS for JavaScript completes these operations directly in the browser based on WebAssembly, and manages input and output files through the virtual file system (VFS), without requiring backend service support.

This article introduces three core feature points:

For installation and project configuration, refer to Integrate Spire.XLS for JavaScript in a React Project. The following examples assume that Spire.XLS is installed and the WebAssembly module has been initialized.


Freeze Panes

When a worksheet contains a large amount of data, freezing panes can pin the header or a specific area so that you can always see the key rows or columns while scrolling through the data. Spire.XLS for JavaScript freezes the panes above and to the left of the specified position through the FreezePanes method. For example, FreezePanes(2, 1) freezes the first row, keeping it visible when scrolling vertically.

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

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

    // Load the font and the Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'FreezePanes.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    const sheet = workbook.Worksheets.get(0);

    // Freeze the first row
    sheet.FreezePanes(2, 1);

    // Set the width of the second column
    sheet.SetColumnWidth(2, 10);

    const outputFileName = "FreezePanes_output.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger the download
    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>Freeze Panes</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Original document Original document After freezing the first row After freezing the first row


Get the Freeze Pane Range

When working with frozen panes, sometimes you need to confirm the position of the frozen panes in the current worksheet. Spire.XLS for JavaScript obtains the row index and column index of the frozen panes through the GetFreezePanes method, and a return value of 0 indicates that the corresponding direction is not frozen.

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

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

    // Load the font and the Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'GetFreezePaneRange.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    const sheet = workbook.Worksheets.get(0);

    // Get the row index and column index of the frozen panes
    const indexs = sheet.GetFreezePanes();
    const rowIndex = indexs[0];
    const colIndex = indexs[1];

    // Write the query result to a text file
    const outputFileName = "GetFreezePaneRange_output.txt";
    window.dotnetRuntime.Module.FS.writeFile(outputFileName, `Row index: ${rowIndex}, column index: ${colIndex}`);

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger the download
    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "text/plain" });
    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>Get Freeze Pane Range</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Original document with frozen panes Original document with frozen panes Query result Query result


Unfreeze Panes

When the fixed display is no longer needed, you can cancel the frozen panes that have been set in the worksheet through the RemovePanes method and restore normal scrolling.

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

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

    // Load the font and the Excel file into the VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'Template_Xls_2.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    const sheet = workbook.Worksheets.get(0);

    // Unfreeze the panes
    sheet.RemovePanes();

    const outputFileName = "UnfreezeExcelPanes_output.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Dispose of the workbook object to release resources
    workbook.Dispose();

    // Read the converted file from the VFS and trigger the download
    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>Unfreeze Panes</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Before unfreezing Before unfreezing After unfreezing After unfreezing

FAQ

The first row still scrolls after freezing panes

Reason: The parameters of the FreezePanes method are set incorrectly, so the frozen area is not the expected row or column.

Solution: The FreezePanes method uses the specified position as the boundary and freezes the panes above and to the left of that position. For example, use FreezePanes(2, 1) to freeze the first row, FreezePanes(3, 1) to freeze the first two rows, and FreezePanes(2, 2) to freeze both the first row and the first column.

Querying the freeze pane range returns 0

Reason: The worksheet has not set any frozen panes, so the queried row and column indexes are 0.

Solution: Call the FreezePanes method to set frozen panes first, and then call GetFreezePanes to query the frozen range.

The freeze effect still shows after unfreezing panes

Reason: The workbook was not saved correctly after unfreezing, or the file opened is the one before the modification.

Solution: After calling the RemovePanes method, be sure to save the workbook with SaveToFile and open the output file to confirm the unfreeze effect.


Get a Free License

If you want to remove the evaluation message in the result documents or get rid of the feature limitations, please contact sales to obtain a 30-day temporary license.

In procurement and sales scenarios, price comparison is one of the most critical and time-consuming steps. Procurement teams receive quotation sheets from various vendors — some organized by rows, some by columns, some containing multiple hidden costs, and some with inconsistent units. The Spire.Agent.Office Excel AI agent can understand quotation sheets in different formats, automatically align each vendor's quotations to a unified template, calculate line-item totals and grand totals, and mark the lowest prices.

This article explains how to use the Spire.Agent.Office Excel AI capability to automatically align quotation sheets from multiple different vendors to a unified template, calculate totals for comparison, and highlight the lowest price.

For product installation and SpireToken configuration, please refer to Integrating Spire.Agent.Office in a .NET Project. The following examples assume that Spire.Agent.Office is installed and SpireToken is configured.


Excel Format Quote Comparison

The core challenge of comparing multi-format quotation sheets is that each vendor's quotation sheet differs.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;

// Quotation files from different vendors
string[] attachmentPaths = new string[]
{
    @"vendor_A.xlsx",
    @"vendor_B.xlsx",
    @"vendor_C.xlsx",
    @"vendor_D.xlsx"
};

// Output template file
string inputPath = @"template.xlsx";  
// Result document
string savePath = @"quote-comparison.xlsx";  
string key = "**************************";  
string instruction =
    "Read the quotation sheets of the vendors in the attachments (Vendor A, Vendor B, Vendor C, Vendor D) and process them as follows:" +
    "1. Identify the item, unit price, quantity, and total price columns in each quotation sheet, and align them to the Unit Price and Amount columns of the corresponding vendor (A, B, C, D) in the template;" +
    "2. If a vendor has not quoted a product, leave the corresponding unit price and amount cells blank and mark them as 'Not quoted';" +
    "3. Calculate the amount (quantity x unit price) for each product of each quoting vendor and fill it into the corresponding columns; compute each vendor's total quotation at the bottom of the template;" +
    "4. In the total price row, fill the cell of the vendor with the lowest total quotation with a green background (RGB:198,224,180);" +
    "5. In the 'Lowest Price Vendor' column, mark the vendor that offers the lowest unit price for each product, and fill the corresponding lowest unit price into the 'Lowest Price' column;" +
    "6. Preserve the template's layout style, fonts, and column widths;" +
    "Finally save the output as an Excel file";

// Call the Excel document processing function
AIResult result = ExecuteDemoExcel(instruction, inputPath, savePath, key,  attachmentPaths);


// Execute Excel document AI processing
static AIResult ExecuteDemoExcel(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    // Create the AIOptions configuration object
    AIOptions options = new AIOptions();
    options.SpireToken = key; 

    // Use the Workbook object to process the Excel document
    using (Workbook workbook = new Workbook())
    {
        // Load the Excel template from file
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            workbook.LoadFromFile(inputPath);
        }
        // Create the AI document processor
        AIWorkbookProcessor processor = workbook.AI(options);

        // Execute the AI instruction
        return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
    }
}

Original quotation sheets of each vendor Original quotation sheets Original Excel template Original template Comparison summary generated by Excel AI AI comparison summary


PDF Format Quote Comparison

When the original quotations are in PDF format, Spire.Agent.Office can equally extract the required data with ease and automatically complete the summary statistics. Simply add the source documents in different formats, and the AI instruction can be reused without reconfiguration, greatly improving processing efficiency.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;

// Quotation files from different vendors
string[] attachmentPaths = new string[]
{
    @"vendor_A.pdf",
    @"vendor_B.pdf",
    @"vendor_C.pdf",
    @"vendor_D.pdf"
};

// Output template file
string inputPath = @"template.xlsx";  
// Result document
string savePath = @"quote-comparison.xlsx";  
string key = "**************************";  
string instruction =
    "Read the quotation sheets of the vendors in the attachments (Vendor A, Vendor B, Vendor C, Vendor D) and process them as follows:" +
    "1. Identify the item, unit price, quantity, and total price columns in each quotation sheet, and align them to the Unit Price and Amount columns of the corresponding vendor (A, B, C, D) in the template;" +
    "2. If a vendor has not quoted a product, leave the corresponding unit price and amount cells blank and mark them as 'Not quoted';" +
    "3. Calculate the amount (quantity x unit price) for each product of each quoting vendor and fill it into the corresponding columns; compute each vendor's total quotation at the bottom of the template;" +
    "4. In the total price row, fill the cell of the vendor with the lowest total quotation with a green background (RGB:198,224,180);" +
    "5. In the 'Lowest Price Vendor' column, mark the vendor that offers the lowest unit price for each product, and fill the corresponding lowest unit price into the 'Lowest Price' column;" +
    "6. Preserve the template's layout style, fonts, and column widths;" +
    "Finally save the output as an Excel file";

// Call the Excel document processing function
AIResult result = ExecuteDemoExcel(instruction, inputPath, savePath, key,  attachmentPaths);


// Execute Excel document AI processing
static AIResult ExecuteDemoExcel(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    // Create the AIOptions configuration object
    AIOptions options = new AIOptions();
    options.SpireToken = key; 

    // Use the Workbook object to process the Excel document
    using (Workbook workbook = new Workbook())
    {
        // Load the Excel template from file
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            workbook.LoadFromFile(inputPath);
        }
        // Create the AI document processor
        AIWorkbookProcessor processor = workbook.AI(options);

        // Execute the AI instruction
        return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
    }
}

Original PDF quotation of each vendor Original quotation sheets Original Excel template Original template Comparison summary generated by Excel AI AI comparison summary


Comparison with Traditional SDK API Processing

Spire.Office for .NET API Spire.Agent.Office
Code Volume Reading data, mapping rows and columns, filling formulas, and applying conditional formatting require extensive code Handled intelligently with a single natural language instruction
Format Adaptation With the traditional SDK APIs, quotation sheets in different formats must be processed with different products Just use the Excel AI to process data sources in various formats
Calculation Logic Formulas and formatting must be set through APIs AI understands and automatically completes the calculation and formatting
Requirement Changes Modify the code and re-debug Modify the instruction, effective immediately

FAQ

Merged Cells in Quotation Sheets Cause Data Misalignment

Cause: Vendor quotation sheets may contain merged title cells or category labels merged across rows, which affect the AI's judgment of the row/column structure.

Solution: Clearly specify in the instruction "ignore the merged header rows and start reading data from row X," or provide a template file as a structural reference. If the issue persists, add the description "treat merged cells as ordinary cells and take their top-left value."

Processed Format Does Not Match Expectations

Cause: When understanding complex table layouts, the AI model may not preserve details such as column widths, row heights, and fonts precisely enough.

Solution: Add specific descriptions to the instruction, such as "preserve the existing column widths, row heights, fonts, borders, and alignment of the template."

Some Products Lack Vendor Quotations

Cause: The product lists provided by different vendors are not completely consistent, and some vendors may not have quoted certain products.

Solution: Clearly specify how to handle missing items in the instruction, such as "mark the cells without quotations as 'Not quoted' or leave them blank," and the AI will automatically identify and process them as required.


Obtaining a SpireToken Key

Configure it in code:

AIOptions options = new AIOptions();
options.SpireToken = key;

Page breaks are an important tool for controlling the print layout of Excel. They determine where data is divided across printed pages. Setting page breaks properly prevents data from being broken apart pointlessly when printing, resulting in clean, readable paper or PDF reports. Spire.XLS for JavaScript uses WebAssembly to add, preview, and remove page breaks directly in the browser, managing input and output files through a virtual file system (VFS) — no backend server required.

This article covers three core features:

For installation and project configuration, refer to Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module is initialized.


Add Page Breaks

When printing reports, we often want to split data by a fixed number of rows and columns, for example printing a fixed number of data rows per page. Spire.XLS for JavaScript adds horizontal page breaks using the HPageBreaks.Add method and vertical page breaks using the VPageBreaks.Add method, enabling precise page break control.

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

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

    // Load fonts and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'Template_Xls_4.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    const sheet = workbook.Worksheets.get(0);

    // Add a horizontal page break at row E4
    sheet.HPageBreaks.Add(sheet.Range.get("E4"));
    // Add a vertical page break at column C4
    sheet.VPageBreaks.Add(sheet.Range.get("C4"));

    const outputFileName = "AddPageBreakInXlsFile.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger download
    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 Page Break</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Original document Original document Add page break Add page break


Page Break View Zoom Scale Setting

When viewing page break positions in the view mode, Spire.XLS for JavaScript supports setting the zoom scale of the page break preview view through the ZoomScalePageBreakView property.

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

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

    // Load fonts and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'Template_Xls_4.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    const sheet = workbook.Worksheets.get(0);

    // Set the zoom scale of the page break preview view
    sheet.ZoomScalePageBreakView = 80;

    const outputFileName = "PageBreakPreview.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger download
    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>Page Break Preview</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Before setting the zoom scale Before setting the zoom scale After setting the zoom scale After setting the zoom scale


Remove Page Breaks

When page breaks are no longer needed, you can clear all page breaks in a specific direction using the Clear method, or delete the page break at a specific position by index using the RemoveAt method. After removal, you can also switch the worksheet to the page break preview view via the ViewMode property to visually confirm the page break effect.

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

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

    // Load fonts and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'PageBreak.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    const sheet = workbook.Worksheets.get(0);

    // Clear all vertical page breaks
    sheet.VPageBreaks.Clear();

    // Remove the first horizontal page break
    sheet.HPageBreaks.RemoveAt(0);

    // Set the view mode to page break preview to check the page break effect
    sheet.ViewMode = xlsModule.ViewMode.Preview;

    const outputFileName = "RemovePageBreak_output.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger download
    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>Remove Page Break</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

Before removing the page break Before removing the page break After removing the page break After removing the page break

FAQ

Page breaks do not take effect when printing after being added

Cause: The page break was added to a blank area, or the worksheet has a fixed print zoom scale set, causing the actual page break positions during printing to differ from what was expected.

Solution: Confirm that the page break is added on the row or column of a cell containing data, and check the worksheet's print zoom settings. If necessary, adjust the zoom scale through properties such as ZoomScalePageBreakView so the page breaks take effect as expected.

Page break lines still display after removal

Cause: The worksheet is still in page break preview view mode, or there are automatic page breaks that are generated automatically based on the amount of data.

Solution: Automatic page breaks cannot be removed directly by programming; automatic page breaks are determined by the number of data rows, columns, and the page size. They can be eliminated by adjusting row heights, column widths, or the print zoom scale.


Get a Free License

If you want to remove the evaluation messages in the resulting documents, or get rid of functional limitations, please contact sales to obtain a temporary license valid for 30 days.

Efficiently transferring technical knowledge is a core challenge for every enterprise in day-to-day business. A large number of technical specification documents — such as operation manuals, safety and maintenance guides, and supply chain standard documents — are often dozens or even hundreds of pages long. How to quickly turn the core knowledge in these dense technical specifications into easy-to-understand PPT material is a key pain point in enterprise knowledge management.

This article demonstrates how to use the Spire.Agent.Office Presentation AI capability to analyze and summarize data sources in various formats, extract the core points, and generate professional PPT presentations.

Comparing with Traditional SDK/API Processing

Traditional Spire.Office for .NET API Spire.Agent.Office
Driving approach Requires calling the APIs of four products — Word, Excel, PDF, PowerPoint — extracting content from each document type via code, then calling the PowerPoint API to create slides page by page, add elements, and manually calculate layouts Directly describe the requirement in natural language, and the AI understands and generates the PPT automatically
Development complexity You need to be familiar with 4 different API sets, write separate parsing code for each format (.docx/.xlsx/.pdf), and then piece together the PowerPoint generation logic — large amount of code with high coupling One natural-language instruction completes the entire workflow
Document parsing You must manually specify which data to extract from each type of document; the parsing logic is hard-coded, and any document structure change requires synchronized code modification AI automatically analyzes the document structure in depth and accurately extracts the key information
Versatility & maintainability Each document format requires its own parsing logic; format changes or new document types require extensive code changes, with poor reusability The same set of natural-language instructions adapts to different documents
Processing cycle Several days (large documents require senior engineers to spend full time writing/debugging code) Minutes (upload document + template + one instruction)

Regarding product installation and SpireToken configuration, please refer to Integrating Spire.Agent.Office in a .NET Project. The examples below assume that Spire.Agent.Office is installed and SpireToken is configured.


Generate PPT from a Word Document

Generate a minimalist-style PPT presentation based on the content of a Word document according to a natural-language instruction.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Presentation;

// Source data document
string inputPath = @"technical_requirements.docx";
// Result document path
string savePath = @"SafetyTechnicalRequirements.pptx";
// SpireToken Key
string key = "sk-TF***************************r";
// Natural language instruction
string instruction = "Extract the core points from 'technical_requirements.docx' to generate a PPT. 1. Ensure proper layout and formatting 2. Use a minimalist style with a light yellow theme 3. Generate 20 slides";
// AI generation
PPTGenerationResult result = GeneratePPT(inputPath, instruction, savePath, key);

// AI-assisted PPT generation
static PPTGenerationResult GeneratePPT(string input, string instruction, string savePath, string key)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    options.TimeoutMs = 1000000;
    using (Presentation ppt = new Presentation())
    {
        AIDocumentProcessor processor = ppt.AI(options);
        return processor.GeneratePresentation(input, instruction, savePath);
    }
}

Generate PPT from a Word document


Generate PPT from a PDF Document

Automatically analyze the internal hierarchy of a PDF document, accurately extract the key information, and generate a retro-green themed PPT presentation according to the instruction.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Presentation;

// Source data document
string inputPath = @"procedures.pdf";
// Result document path
string savePath = @"SafetyOperationProcedures.pptx";
// SpireToken Key
string key = "sk-TF***************************r";
// Natural language instruction
string instruction = "Extract the key points from 'procedures.pdf' and generate a PPT. " +
                     "1. Ensure a well-structured layout and visual appeal; " +
                     "2. Include relevant diagrams and charts; " +
                     "3. Use a simple purple style as the theme; "+
                     "4. 9 pages";
// AI generation
PPTGenerationResult result = GeneratePPT(inputPath, instruction, savePath, key);


// AI-assisted PPT generation
static PPTGenerationResult GeneratePPT(string input, string instruction, string savePath, string key)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    options.TimeoutMs = 1000000;
    using (Presentation ppt = new Presentation())
    {
        AIDocumentProcessor processor = ppt.AI(options);
        return processor.GeneratePresentation(input, instruction, savePath);
    }
}

Generate PPT from a PDF document


Generate PPT from a Markdown Document

Automatically summarize the content of a Markdown-format data source and generate a tech-style PPT.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Presentation;

// Source data document
string inputPath = @"Management.md";
// Result document path
string savePath = @"SupplyChainManagement.pptx";
// SpireToken Key
string key = "sk-TF***************************r";
// Natural language instruction
string instruction = "Generate a PPT based on 'Management.md'. Requirements: 1. Adopt a tech/style; 2. Use light blue as the primary color scheme; 3. Ensure the core content is complete, with clear hierarchy and neat layout. Key data should be presented visually through charts and graphs.";
// AI generation
PPTGenerationResult result = GeneratePPT(inputPath, instruction, savePath, key);


// AI-assisted PPT generation
static PPTGenerationResult GeneratePPT(string input, string instruction, string savePath, string key)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    options.TimeoutMs = 1000000;
    using (Presentation ppt = new Presentation())
    {
        AIDocumentProcessor processor = ppt.AI(options);
        return processor.GeneratePresentation(input, instruction, savePath);
    }
}

Generate PPT from a Markdown document


Generate PPT from an Excel Document

Automatically summarize the content of an Excel-format data source and generate a tech-style PPT.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Presentation;

// Source data document
string inputPath = @"data.xlsx";
// Result document path
string savePath = @"out.pptx";
// SpireToken Key
string key = "sk-TF***************************r";
// Natural language instruction
string instruction = "Generate a PPT based on data
.xlsx, 1. Ensure proper layout and formatting 2. Use a minimalist style with a light red theme 3. Ensure chart visual effects 4.Generate 15 pages";
// AI generation
PPTGenerationResult result = GeneratePPT(inputPath, instruction, savePath, key);


// AI-assisted PPT generation
static PPTGenerationResult GeneratePPT(string input, string instruction, string savePath, string key)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    options.TimeoutMs = 1000000;
    using (Presentation ppt = new Presentation())
    {
        AIDocumentProcessor processor = ppt.AI(options);
        return processor.GeneratePresentation(input, instruction, savePath);
    }
}

Generate PPT from an Excel document


FAQ

The number of generated PPT pages does not match the expectation

Cause: If the data source contains a large amount of content, the AI analysis will take more time. The default timeout of AIOptions.TimeoutMs is 5 minutes; if the analysis exceeds it, the AI analysis is interrupted.

Solution: Set AIOptions.TimeoutMs to a sufficiently large value, and also specify a page range in the instruction, e.g. "Keep the final PPT to 8-12 pages".

The key content extracted by AI is not accurate enough

Cause: The source document has a complex structure, and the AI may not have fully understood the hierarchy.

Solution: Explicitly specify the type of content to extract in the instruction, e.g. "Focus on extracting the data from the table in Chapter 2".


Get Your SpireToken Key

Configure it in code:

AIProcessorOptions options = new AIProcessorOptions();
options.SpireToken = key;

Word templates are the foundation of enterprise business workflows. HR needs standard employment contracts and offer letters, sales teams need professional quotation and report templates, and administration needs unified meeting notices and certification documents. With the Word AI capabilities of Spire.Agent.Office, you simply describe the desired template style and content structure in natural language — for example, "Create a contract template with mail merge fields for 'Name, Position, Department, Salary, Start Date, End Date, Contract Type, Probation Period (months), Location'" and AI delivers the template directly.

Comparison with Traditional SDK API Approach

Traditional Spire.Office for .NET API Spire.Agent.Office
Development Approach Call APIs to build document structure line by line, paragraph by paragraph Describe template style and structure in natural language; AI automatically composes and generates the complete template document
Code Volume Hundreds of lines of document-building code per template Just 1 natural language instruction
Style Adjustment Font, color, border, and other styles require complex code-based formatting Simply describe in natural language
Template Flexibility Template structure changes require rewriting underlying document-building logic — high maintenance cost Adjust the instruction description, AI regenerates — flexibly responds to changing requirements

Several typical business scenario Word template examples:

For product installation and SpireToken configuration, please refer to Integrating Spire.Agent.Office in a .NET Project. The examples below assume Spire.Agent.Office is already installed and SpireToken is configured.


Word Employment Contract Template

The most commonly used employment contracts in HR departments all share a relatively fixed structure: title, party information, main body clauses, signature section, etc.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;

string inputPath = @"";
// Result document path
string savePath = @"employmentContract.docx"; ;
// SpireToken Key
string key = "s******************************r";
// Natural language instruction
string instruction =
    "Generate a Word employment contract template. " +
    "The main title is 'Employment Contract', in No. 2 font size, bold, and centered. " +
    "The body text uses Arial font throughout, in Small No. 4 font size (12pt), with a first-line indent of 2 characters per paragraph. " +
    "Add a light blue watermark with the text 'E-iceblue' throughout the entire document. " +
    "Include the following fields as mail merge fields: Name, Position/Department, Salary, Start Date, End Date, Contract Type, Probation Period (months), and Location. " +
    "The overall style should be formal and professional, suitable for legal document scenarios.";
// AI generation
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);

// Word AI processing
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
    // Create AI processor options instance
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    // Create Word document object
    using (Document doc = new Document())  
    {
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);  
        }
        // Create AI document processor instance
         AIDocumentProcessor processor = doc.AI(options);  

        // Process the document according to the instruction and save the result to the specified path
        return processor.ExecuteInstruction(doc, instruction, savePath);
    }
}

Word employment Contract Template


Word Quotation Template

The most commonly used quotation templates in sales and business departments all share a relatively fixed structure: title, company information, client information, product quotation table, amount summary, quotation terms, signature section, etc.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;

string inputPath = @"";
// Result document path
string savePath = @"QuotationTemplate.docx"; ;
// SpireToken Key
string key = "s******************************r";
// Natural language instruction
string instruction =
    "Generate a professional quotation template with the following styling requirements: " +
    "Main title: 'Quotation' , font size equivalent to  26pt, bold, centered, using 'Arial' font. " +
    "Body text: Calibri font, size 12pt , with 1.5× line spacing. " +
    "Template structure must include: Company logo placeholder area, company information (address, phone number, email), client information (client name, contact person), product quotation table (including Serial Number, Product Name, Specifications, Quantity, Unit Price, Subtotal, Remarks), total price (in words + in digits), quotation validity period, company stamp/seal area. \n" +
    "Use {{ }} as placeholder markers throughout the template, for example: {{Company Name}}, {{Client Name}}, {{Product Name}}, {{Unit Price}}, {{Quantity}}, {{Subtotal}}, {{Total Price in Words}}, {{Total Price in Digits}}."; 

// AI generation
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);

// Word AI processing
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
    // Create AI processor options instance
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    // Create Word document object
    using (Document doc = new Document())  
    {
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);  
        }
        // Create AI document processor instance
         AIDocumentProcessor processor = doc.AI(options);  

        // Process the document according to the instruction and save the result to the specified path
        return processor.ExecuteInstruction(doc, instruction, savePath);
    }
}

Word Quotation Template


Word Certificate Template

Certificate templates are widely used in scenarios such as training certification, commendation and awards, event participation, etc. Their core structure typically includes: certificate title (e.g., "Certificate of Honor", "Certificate of Completion"), certificate number, etc.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;

string inputPath = @"";
// Result document path
string savePath = @"WordCertificateTemplate.docx"; ;
// SpireToken Key
string key = "s******************************r";
// Natural language instruction
string instruction =
"Generate a one-page honor certificate template with the following style requirements: " +
"Overall classical and solemn style, with a gold double-line border, using Times New Roman font." +
"Centered at the top: certificate title 'CERTIFICATE OF HONOR' — 24pt, bold, gold color." +
"Center-aligned body layout with the following structure:" +
"  Line 1: 'This is to certify that';" +
"  Line 2: '{{Full Name}}' — bold, red color;" +
"  Line 3: 'has demonstrated outstanding performance during the {{Year}} work year and is hereby awarded:';" +
"  Line 4: '{{Honor Title}}' — bold, gold color;" +
"  Line 5: 'This certificate is presented in recognition of this achievement.'." +
"Signatory area: bottom right, two lines right-aligned: '{{Issuing Authority}}' and '{{Date}}'." +
"Bottom left: certificate number displayed as 'No.: {{Certificate Number}}'." +
"Overall style: formal, solemn, and dignified, suitable for government or corporate honorary certificate presentations.";

// AI generation
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);

// Word AI processing
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
    // Create AI processor options instance
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    // Create Word document object
    using (Document doc = new Document())  
    {
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);  
        }
        // Create AI document processor instance
         AIDocumentProcessor processor = doc.AI(options);  

        // Process the document according to the instruction and save the result to the specified path
        return processor.ExecuteInstruction(doc, instruction, savePath);
    }
}

Word Certificate Template


Budget Report Template

Budget report templates are commonly used document tools in enterprises or organizations for financial planning, project proposals, and annual planning. Their core structure typically includes: report title (e.g., "XX Annual Budget Report", "XX Project Budget Plan"), preparing unit and date, budget preparation notes, etc.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;

string inputPath = @"";
// Result document path
string savePath = @"BudgetReportTemplate.docx"; ;
// SpireToken Key
string key = "s******************************r";
// Natural language instruction
string instruction =
"Generate a professional budget report template with the following style requirements:" +
"Main title: '{{Year}} Annual Budget Report' — font size No.1 (approx. 26pt), bold, centered, using Arial." +
"Add a subtitle below the title: 'Prepared by: {{Department Name}} | Date: {{Preparation Date}}', font size No.4 small (approx. 12pt), centered." +
"The body is divided into four sections:\n" +
"  Section 1 (Budget Overview): At the top, display four key metrics in a card-style horizontal layout with light background shading — 'Annual Budget Total: {{Total Budget}} ten-thousand yuan', 'Amount Executed: {{Executed Amount}} ten-thousand yuan', 'Execution Rate: {{Execution Rate}}%', 'Remaining Budget: {{Remaining Budget}} ten-thousand yuan'. The four data cards are placed side by side with numeric values bolded and enlarged.\n" +
"  Section 2 (Detailed Budget Table): A detailed budget table with columns — Account Code, Account Name, Annual Budget (ten-thousand yuan), Q1 Execution, Q2 Execution, Q3 Execution, Q4 Execution, Total Executed, Execution Rate (%), Remaining Budget (ten-thousand yuan). Table header: dark green background (#1E5631), white bold font; all numeric columns: retain two decimal places; data rows: alternating row colors.\n" +
"  Section 4 (Budget Notes): At the bottom of the page, add a 'Budget Notes' section — '{{Budget Preparation Notes}}'." +
"Overall style: formal, professional, and elegant — suitable for a formal budget report presented to management.";

// AI generation
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);

// Word AI processing
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
    // Create AI processor options instance
    AIOptions options = new AIOptions();
    options.SpireToken = key;
    // Create Word document object
    using (Document doc = new Document())  
    {
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);  
        }
        // Create AI document processor instance
         AIDocumentProcessor processor = doc.AI(options);  

        // Process the document according to the instruction and save the result to the specified path
        return processor.ExecuteInstruction(doc, instruction, savePath);
    }
}

Budget Report Template


Frequently Asked Questions

Generated template style does not fully match expectations

Cause: The style description in the instruction is not specific enough.

Solution: Specify details such as font name explicitly in the instruction.

Already generated template needs modification

Cause: Business requirements have changed, requiring template adjustments.

Solution: Directly describe the modifications in the instruction and regenerate, or use the current document as input for AI secondary processing.

Generated template shows garbled Chinese characters or incorrect fonts

Cause: The font specified in the instruction is not installed on the system.

Solution: Ensure the font mentioned in the instruction is installed on the system, or use common system fonts in the instruction.


Getting a SpireToken Key

Configure in code:

AIOptions options = new AIOptions();
options.SpireToken = key;

In enterprise HR scenarios, batch contract generation is one of the most common document processing needs — monthly new employee onboarding, contract renewals, labor agreement changes often involve processing dozens or even hundreds of contracts at once. Each contract needs personalized information such as employee name, position, salary, and contract term.

Comparison with Traditional SDK API Processing

Traditional Spire.Office for .NET API Spire.Agent.Office
Approach Write code for traditional API processing: load template → get fields → read data → fill row by row → save, every step requires code control Describe the goal in natural language, AI automatically orchestrates and completes all processing steps
Code Volume Requires dozens of lines of code for data reading, field mapping, loop writing, and format control Only configuration code + 1 natural language instruction
Field Mapping Hard-code the mapping between merge fields and Excel columns; data source changes require code updates AI automatically understands semantic correspondence between column names and template fields; data source changes require no code changes
Flexibility Template field changes require code changes → compilation → redeployment Just adjust the template or data source; existing instructions are reusable
Maintainability Relies on development team to maintain code Templates and data sources can be maintained directly by business users

This article introduces how to use Spire.Agent.Office Word AI capabilities to automatically write Excel employee data into Word templates and generate contracts in PDF format in batches, using both mail merge and placeholder replacement approaches. You are also free to save as DOCX, DOC, HTML, OFD, Markdown, XPS, and other formats to meet different archiving needs.

For product installation and SpireToken configuration, please refer to Integrating Spire.Agent.Office in a .NET Project. The following examples assume Spire.Agent.Office is already installed and SpireToken is configured.


Mail Merge Approach

Mail merge is the standard solution for batch Word document generation and the most commonly used pattern in HR scenarios. The core idea is: a contract template Word document with merge fields and a data source, letting AI complete the data-to-template merge.

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;

// Multiple document paths (data source files)
string[] attachmentPaths = new string[] { @"E:\data.xlsx" };

// Word template file path
string inputPath = @"E:\template-mailmerge.docx";  
// Result document path (null here — will use the output folder path set below)
string savePath = null;  
// Output directory
string OutDir = @"E:\output";  
// SpireToken Key
string key = "**************************";  
// Natural language instruction
string instruction =
      "Execute mail merge: populate employee data from the attachment 'data.xlsx' into the merge fields of the contract template row by row; " +
      "preserve the original document layout and styling after merging; " +
      "generate one independent contract document per employee and save the output in PDF format"; 

// Call the Word document processing function
AIResult result = ExecuteDemoWord(instruction, inputPath, savePath, key, OutDir, attachmentPaths);

// Record processing log
WriteLog(result, "word", @"E:\log\");


// Execute Word document AI processing
static AIResult ExecuteDemoWord(string instruction, string inputPath, string savePath, string key, string output, string[] attachmentPaths)
{
    // Create AIOptions configuration object
    AIOptions options = new AIOptions();
    // Set working directory to output directory
    options.WorkDir = output; 
    // Set SpireToken Key
    options.SpireToken = key;  

    // Use Document object to process Word document
    using (Document doc = new Document())
    {
        // Load Word template from file
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);  
        }
        // Create AI document processor
        AIDocumentProcessor processor = doc.AI(options);
    
        // Execute AI instruction
        return processor.ExecuteInstruction(doc, instruction, savePath, attachmentPaths);
    }
}

Original Word template (with mail merge fields) and Excel data Original Word template and Excel data Output generated via mail merge Mail merge batch contract generation

Each generated contract fully preserves the template's formatting, table styles, and font settings, with all merge fields replaced by the corresponding employee data. If 50 new employees are being onboarded, just one template + one Excel file + one instruction is all it takes to generate all contracts.


Placeholder Replacement Approach

The placeholder replacement approach does not require predefining mail merge fields in the template. Instead, it uses custom placeholder markers (such as {{Name}}, {{Salary}}) directly in the document, which the AI agent identifies and replaces.

// Multiple document paths (data source files)
string[] attachmentPaths = new string[] { @"E:\data.xlsx" };

// Contract template file path
string inputPath = @"E:\template.docx";  
// Save path (null here — will use the output folder path set below)
string savePath = null;  
// Output directory
string OutDir = @"E:\output"; 
// SpireToken Key
string key = "**************************";  

// Natural language instruction
string instruction =
    "Read employee data from 'data.xlsx' and replace the corresponding placeholders in the contract template row by row" +  
    "Highlight the replaced field content, preserve the original document layout, styling, and fonts after replacement," +  
    "Generate one independent contract document per employee and save the output in PDF format"; 

// Call the AI Word document processing method
AIResult result = ExecuteDemoWord1(instruction, inputPath, savePath, key, OutDir, attachmentPaths);

// Record processing log
WriteLog(result, "word", @"E:\log\");


// Execute Word document AI processing
static AIResult ExecuteDemoWord(string instruction, string inputPath, string savePath, string key, string output, string[] attachmentPaths)
{
    // Create AIOptions configuration object
    AIOptions options = new AIOptions();
    // Set working directory to output directory
    options.WorkDir = output;  
    // Set SpireToken Key
    options.SpireToken = key; 

    // Use Document object to process Word document
    using (Document doc = new Document())
    {
        // Load Word template from file
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);  
        }
        // Create AI document processor
        AIDocumentProcessor processor = doc.AI(options);
    
        // Execute AI instruction
        return processor.ExecuteInstruction(doc, instruction, savePath, attachmentPaths);
    }
}

Original Word template (with {{}} placeholders) and Excel data Original Word template and Excel data Output generated via placeholder replacement Placeholder replacement contract generation


Two Approaches Compared

Mail Merge Approach Placeholder Replacement Approach
Template Creation Requires inserting mail merge fields Directly type {{}} placeholders
Learning Curve Requires knowledge of Word mail merge functionality Nearly zero learning cost
Flexibility Fixed one-to-one field mapping Supports dynamic calculation and formatting during replacement
Data Source Requires structured data Supports structured data, can also be defined in the instruction

For creating Word templates with Spire.Agent.Office, please refer to the article "Creating Various Word Templates with Spire.Agent.Office".

Frequently Asked Questions

Generated document style changed

Cause: The AI model may modify or add content during processing.

Solution: Add a description like "preserve the original document layout, styling, and fonts" to the instruction.

Number of generated documents does not match the number of data rows after mail merge

Cause: Empty rows or merged cells in the data source Excel file, causing inaccurate row counting.

Solution: Ensure the first row of the data source contains column headers, with each subsequent row corresponding to one employee record and no empty rows in between. If the issue persists, add a sequence number column to the data source for validation.


Obtaining a SpireToken Key

Configure it in code:

AIOptions options = new AIOptions();
options.SpireToken = key;

Traditional Spire.Office for .NET workflows often require developers to have in-depth API knowledge and write extensive boilerplate code for tasks like formatting, extraction, and conversion. Spire.Agent.Office introduces an AI layer that abstracts this complexity, enabling you to accomplish these tasks using plain natural language instructions.

This tutorial walks you through integrating Spire.Agent.Office into a .NET 10 project, enabling natural-language-powered document processing with minimal code.


Why Choose Spire.Agent.Office

Spire.Agent.Office is an AI agent built on top of the traditional Spire.Office for .NET document engine. The core differences are:

Traditional Spire.Office for .NET Spire.Agent.Office
Operation Manual coding (calling APIs, iterating document data, processing, saving results) Natural language instructions (e.g., "Review this contract")
Low Learning Curve Requires detailed API knowledge and object structure Simply describe the requirements, AI executes automatically
Flexibility API code may not suit all documents Universal AI instructions handle all documents

How It Works

Natural Language Instruction → Spire.Agent.Office AI Layer → Spire.Office Document Engine → Output File

Spire.Agent.Office parses your natural language instructions, converts them into internal calls to the Spire.Office document engine for processing, and ultimately generates the desired document. It supports processing and conversion of Word, Excel, PowerPoint, PDF, and other document formats.

Core Advantages

Advantage Description
AI-Native Experience Replace complex API call chains with natural language for direct document processing
Stability and Reliability Built on the mature Spire.Office document engine, ensuring reliable document processing
Seamless Integration Cross-platform support, easy integration, flexible adaptation to business logic
Flexible AI Model Support Compatible with mainstream AI infrastructure, ensuring accurate AI code generation
Accelerated Delivery Reduces development time for document processing tasks

Typical Use Cases

  • Automated internal report generation and formatting
  • Batch contract processing and data extraction
  • Intelligent multi-format document conversion and distribution
  • Automated meeting slide layout and export

Project Setup and Library Reference

Creating a .NET 10 Project

Create .NET 10 Project

Installing Spire.Agent.Office via NuGet

After installing Spire.Agent.Office via NuGet, dependencies are installed automatically.

NuGet Install Spire.Agent.Office

Importing Spire.Agent.Office Assemblies Locally

Download Spire.Agent.Office from the website, extract it to a local directory, and import it into the project.

Local Assembly Import

When adding via local DLLs, the following dependencies are also required for optimal performance:

Dependency Package Minimum Version
Microsoft.Win32.Registry >= 5.0.0
System.Drawing.Common >= 10.0.0
System.Text.Encoding.CodePages >= 10.0.0
HarfBuzzSharp >= 8.3.0.1
coverlet.collector >= 6.0.2
Microsoft.Extensions.DependencyInjection >= 10.0.3
Microsoft.Extensions.DependencyInjection.Abstractions >= 10.0.3
Microsoft.Extensions.Logging >= 10.0.3
Microsoft.Extensions.Logging.Abstractions >= 10.0.3
Microsoft.Extensions.Logging.Console >= 10.0.3
Microsoft.Extensions.Options >= 10.0.3
Microsoft.Extensions.Hosting >= 10.0.3
Microsoft.Extensions.Caching.Memory >= 10.0.3
Microsoft.Extensions.Http >= 10.0.3
Microsoft.Extensions.Http.Polly >= 10.0.3
Microsoft.DotNet.Interactive >= 1.0.0-beta.23403.1
Microsoft.DotNet.Interactive.CSharp >= 1.0.0-beta.23403.1
Microsoft.CodeAnalysis.CSharp >= 4.5.0
Microsoft.CodeAnalysis.CSharp.Workspaces >= 4.5.0
Microsoft.CodeAnalysis.CSharp.Scripting >= 4.5.0
Microsoft.CodeAnalysis.Workspaces.MSBuild >= 4.5.0
Microsoft.Extensions.Configuration.EnvironmentVariables >= 10.0.8
Microsoft.Extensions.Configuration.Json >= 10.0.8
Microsoft.NET.Test.Sdk >= 17.12.0
Polly >= 8.5.0
Polly.Extensions.Http >= 3.0.0
Serilog >= 4.2.0
Serilog.Sinks.File >= 7.0.0
Serilog.Extensions.Logging >= 10.0.0
Microsoft.Data.Sqlite >= 8.0.0
Dapper >= 2.1.35
Microsoft.ML.OnnxRuntime >= 1.17.3
SkiaSharp >= 3.116.1
System.Text.Json >= 10.0.0
xunit >= 2.9.2
xunit.runner.visualstudio >= 2.8.2
FluentAssertions >= 7.1.0
Spire.Doc for.NETStandard >= 14.6.13
Spire.PDF for.NETStandard >= 12.6.9
Spire.Presentation for.NETStandard >= 16.6.3
Spire.XLS for.NETStandard >= 11.6.11

AI-Powered Document Processing

Core Workflow

Document AI processing follows this pattern:

  1. Create a document object (Workbook / Document / PdfDocument / Presentation)
  2. Load a preset document (optional; can start with an empty document)
  3. Configure AIOptions (set SpireToken)
  4. Call .AI(options) to obtain an AIDocumentProcessor
  5. Execute AI instructions and monitor execution status:
    • Processing existing documents: Call AIDocumentProcessor.ExecuteInstruction(), returns AIResult
    • Generating PPT documents: Call AIDocumentProcessor.GeneratePresentation(), returns GenerationResult

Core Code

using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Pdf;
using Spire.Doc;
using Spire.Presentation;
using Spire.Xls;

// Excel Processing
static AIResult ExecuteDemoXls(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;

    using (Workbook workbook = new Workbook())
    {
        // Load the document if the input path exists and the file is accessible
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            workbook.LoadFromFile(inputPath);
        }
        // Otherwise, use an empty Workbook
        AIDocumentProcessor processor = workbook.AI(options);
        return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
    }
}

// Word Processing
static AIResult ExecuteDemoWord(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;

    using (Document doc = new Document())
    {
        // Load the document if the input path exists and the file is accessible
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            doc.LoadFromFile(inputPath);
        }
        // Otherwise, use an empty Document
        AIDocumentProcessor processor = doc.AI(options);
        return processor.ExecuteInstruction(doc, instruction, savePath, attachmentPaths);
    }
}

// PDF Processing
static AIResult ExecuteDemoPDF(string instruction, string inputPath, string savePath, string key, string[] attachmentPaths)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;

    using (PdfDocument pdf = new PdfDocument())
    {
        // Load the document if the input path exists and the file is accessible
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            pdf.LoadFromFile(inputPath);
        }
        // Otherwise, use an empty PdfDocument
        AIDocumentProcessor processor = pdf.AI(options);
        return processor.ExecuteInstruction(pdf, instruction, savePath, attachmentPaths);
    }
}

// PPT Generation
static PPTGenerationResult GeneratPPT(string input, string instruction, string savePath, string key)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;

    using (Presentation ppt = new Presentation())
    {
        AIDocumentProcessor processor = ppt.AI(options);
        return processor.GeneratePresentation(input, instruction, savePath);
    }
}

// Based on existing PPT processing
static AIResult ExecuteDemoPPT(string inputPath, string instruction, string savePath, string key, string[] attachmentPaths)
{
    AIOptions options = new AIOptions();
    options.SpireToken = key;

    using (Presentation ppt = new Presentation())
    {
        // Load the document if the input path exists and the file is accessible
        if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
        {
            ppt.LoadFromFile(inputPath);
        }
        // Otherwise, use an empty Presentation
        AIDocumentProcessor processor = ppt.AI(options);
        return processor.ExecuteInstruction(ppt, instruction, savePath, attachmentPaths);
    }
}

// Write execution log
static void WriteLog(dynamic? aiResult, string taskName, string basePath)
{
    string logFilePath = Path.Combine(basePath, $"{taskName}.txt");
    string? logDir = Path.GetDirectoryName(logFilePath);
    if (!string.IsNullOrEmpty(logDir) && !Directory.Exists(logDir))
        Directory.CreateDirectory(logDir);

    var logBuilder = new System.Text.StringBuilder();

    // Determine execution status: Success/Failure/Skipped
    string status = aiResult == null ? "SKIPPED" :
        aiResult.Success ? "SUCCESS" : $"FAILED: {aiResult.ErrorMessage}";

    logBuilder.AppendLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{taskName}] {status}");

    if (aiResult != null)
    {
        // Log execution duration
        logBuilder.AppendLine($" | Duration: {aiResult.Duration.TotalSeconds:F2}s");

        // Log token usage statistics
        var tu = aiResult.TokenUsage;
        if (tu != null)
        {
            logBuilder.Append($" | In: {tu.InputTokens:N0}");           // Input tokens
            logBuilder.Append($" | Out: {tu.OutputTokens:N0}");         // Output tokens
            logBuilder.Append($" | CacheR: {tu.CacheReadTokens:N0}");   // Cache read tokens
            logBuilder.Append($" | CacheW: {tu.CacheWriteTokens:N0}");  // Cache write tokens
            logBuilder.Append($" | CacheT: {tu.TotalCacheTokens:N0}");  // Total cache tokens
            logBuilder.Append($" | Total: {tu.TotalTokens:N0}");        // Total tokens
        }
    }

    logBuilder.AppendLine();
    File.AppendAllText(logFilePath, logBuilder.ToString());
}

Calling AI Processing

The following examples demonstrate using natural language interaction to leverage the system's powerful document processing capabilities for various complex document tasks.

// Multiple document paths
string[] attachmentPaths = new string[] { };

// Word Processing
string inputPath = @"in.docx";
string savePath = @"out.pdf";
string key = "SpireToken key";
string instruction = "Find '****' and highlight it, save result to PDF";
AIResult result = ExecuteDemoWord(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "word", @"log\");

// PPT Processing
string inputPath = @"in.pptx";
string savePath = @"out.pptx";
string key = "SpireToken key";
string instruction = "Add notes description to each slide";
AIResult result = ExecuteDemoPPT(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "ppt", @"log\");

// PPT Generation
string inputPath = @"AI.md";
string savePath = @"out.pptx";
string key = "SpireToken key";
string instruction = "Generate a PPT based on AI.md";
PPTGenerationResult result = GeneratPPT(inputPath, instruction, savePath, key);
WriteLog(result, "ppt", @"log\");

// PDF Processing
string inputPath = @"in.pdf";
string savePath = @"out.md";
string key = "SpireToken key";
string instruction = "Extract table data and save as standard markdown format";
AIResult result = ExecuteDemoPDF(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "pdf", @"log\");

// Excel Processing
string inputPath = @"in.xlsx";
string savePath = @"out.pdf";
string key = "SpireToken key";
string instruction = "Delete empty rows in the document";
AIResult result = ExecuteDemoXls(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "xls", @"log\");

Frequently Asked Questions

SpireToken Key Not Configured Properly

If the SpireToken Key is not configured, is incorrect, or has expired, Spire.Agent.Office will throw an exception and the program will abort. Ensure the SpireToken Key is valid before proceeding.

AI Instruction Execution Failed

The AIResult returned by ExecuteInstruction may contain failure information. Check the Success property.

AIResult result = processor.ExecuteInstruction(doc, instruction, outputPath);

if (result == null || !result.Success)
{
    throw new InvalidOperationException(
        $"AI instruction failed: {result?.ErrorMessage ?? "Unknown error"}");
}

Incorrect Document Path

If processing an existing document, an incorrect file path will cause document loading to fail:

  • Ensure the document path is correct
  • For multi-document operations (e.g., document merging), additional documents can be defined in attachmentPaths

Apply for SpireToken Key

Spire.Agent.Office requires a valid SpireToken Key to experience full functionality:

Configure it in your code:

AIOptions options = new AIOptions();
options.SpireToken = key;

Copying worksheets is one of the most common and efficient operations in everyday Excel document processing — whether you are quickly creating similar reports from a template or consolidating data across multiple documents. Spire.XLS for JavaScript handles this entirely in the browser via WebAssembly, using a virtual file system (VFS) to manage input and output files — no backend server required.

This article covers three core features:

For installation and project setup, refer to Integrating Spire.XLS for JavaScript in a React Project. The examples below assume Spire.XLS is installed and the WebAssembly module is initialized.


Copy a Worksheet Within the Same Workbook

Duplicating a worksheet within the same workbook is a frequent development task — for example, quickly creating next month's report copy from a monthly template. Spire.XLS for JavaScript provides the CopyFrom method to duplicate a worksheet. The copied sheet retains all content from the source worksheet, including data, styles, fonts, colors, borders, column widths, and row heights.

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

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

    // Load fonts and the Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'Sample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first worksheet
    let sheet = workbook.Worksheets.get(0);

    // Add a new worksheet
    let sheet1 = workbook.Worksheets.Add("MySheet");

    // Copy the first worksheet into the newly added sheet
    sheet1.CopyFrom(sheet);

    const outputFileName = "CopySheetWithinWorkbook_output.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Release the workbook object to free resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger download
    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>Copy Worksheet Within Workbook</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

When using CopyFrom, data, styles, fonts, colors, borders, and column widths from the source worksheet are fully preserved in the new sheet.

Copying a worksheet within the same workbook


Copy a Worksheet Across Workbooks

In real-world scenarios, data from multiple Excel files often needs to be consolidated into a single workbook — for example, extracting specific sheets from departmental reports and merging them into a master sheet. The AddCopy method lets you copy a worksheet from the source workbook into the target workbook with all its content intact.

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

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

    // Load fonts and the Excel files into VFS
    await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const sourceFileName = 'ReadImages.xlsx';
    const targetFileName = 'Sample.xlsx';
    await window.spire.FetchFileToVFS(sourceFileName, '', `${process.env.PUBLIC_URL}data/`);
    await window.spire.FetchFileToVFS(targetFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the source workbook
    const sourceWorkbook = new xlsModule.Workbook();
    sourceWorkbook.LoadFromFile({ fileName: sourceFileName });

    // Get the first worksheet of the source workbook
    const srcWorksheet = sourceWorkbook.Worksheets.get(0);

    // Load the target workbook
    const targetWorkbook = new xlsModule.Workbook();
    targetWorkbook.LoadFromFile({ fileName: targetFileName });

    // Add a new worksheet in the target workbook and copy the source sheet into it
    targetWorkbook.Worksheets.AddCopy({ sheet: srcWorksheet });

    // Save the target workbook
    const outputFileName = "CopyAcrossWorkbooks_output.xlsx";
    targetWorkbook.SaveToFile({ fileName: outputFileName });

    // Release resources
    sourceWorkbook.Dispose();
    targetWorkbook.Dispose();

    // Read the converted file from VFS and trigger download
    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>Copy Worksheet Across Workbooks</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

When copying across workbooks, all data and styles from the source worksheet are preserved — AddCopy copies the complete worksheet content into the target workbook.

Copying a worksheet across workbooks


Copy a Selected Cell Range

Sometimes you do not need to copy an entire worksheet — you only need to copy a specific cell range (such as a particular data table or summary result) to a target location. Spire.XLS for JavaScript provides the Copy method, which copies data, styles, and formatting from the source range to the starting position of the target range.

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

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

    // Load the source Excel file into VFS
    await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
    const inputFileName = 'Sample.xlsx';
    await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);

    // Load the workbook
    const workbook = new xlsModule.Workbook();
    workbook.LoadFromFile({ fileName: inputFileName });

    // Get the first row of the first worksheet as the source range
    const sheet = workbook.Worksheets.get(0);
    const sourceRange = sheet.Range.get("A1:E1");

    // Add a new worksheet
    let sheet1 = workbook.Worksheets.Add("AddSheet");

    // Copy the source range to the starting position of the target worksheet
    sheet.Copy(sourceRange, sheet1, sheet.FirstRow, sheet.FirstColumn, true);

    // Save the workbook
    const outputFileName = "CopyRange_output22.xlsx";
    workbook.SaveToFile({ fileName: outputFileName });

    // Release resources
    workbook.Dispose();

    // Read the converted file from VFS and trigger download
    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>Copy Range</h1>
      <button onClick={sheetToSVG}>
        Start
      </button>
    </div>
  );
}

export default App;

The Copy method transfers data, styles, and formatting from the source range to the target range — ideal for lightweight scenarios where only partial data extraction is needed.

Copying a selected cell range


FAQ

Column width differs after copying

Cause: Font mismatch between the source and target workbooks.

Solution: Ensure all required font files are loaded into the VFS environment of the target workbook before copying across workbooks:

await window.spire.FetchFileToVFS(
  'arial.ttf', '/Library/Fonts/', '/'
);

Range content is pasted at the wrong position

Cause: Incorrect destRow and destColumn parameters in the Copy method, causing data to be pasted at an unexpected location.

Solution: Confirm that the destination row and column indices start from 1 (not 0), and verify the row and column range of the target worksheet before copying.


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.

Page 1 of 2