Generate Various Word Templates with Spire.Agent.Office
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:
- Word Employment Contract Template
- Word Quotation Template
- Word Certificate Template
- Budget Report Template
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 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 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);
}
}

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);
}
}

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
- Contact sales@e-iceblue.com or visit https://www.e-iceblue.com/TemLicense.html to obtain a trial/commercial API key
Configure in code:
AIOptions options = new AIOptions();
options.SpireToken = key;
Batch Contract Generation with Spire.Agent.Office
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
Output generated via mail merge 
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
Output generated via placeholder replacement 
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
- Contact sales@e-iceblue.com or visit https://www.e-iceblue.com/TemLicense.html to obtain a trial or commercial API key.
Configure it in code:
AIOptions options = new AIOptions();
options.SpireToken = key;
Integrate Spire.Agent.Office in .NET Project
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(The product is based on NET Standard 2.1, compatible .NET 5/6/7/8 and other platforms, not limited to NET 10), enabling natural-language-powered document processing with minimal code.
- Why Choose Spire.Agent.Office
- Project Setup and Library Reference
- AI-Powered Document Processing
- Frequently Asked Questions
- Apply for SpireToken Key
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

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

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.

When adding via local DLLs, the following dependencies are also required for optimal performance:
| Dependency Package | Minimum Version |
|---|---|
| coverlet.collector | >= 6.0.4 |
| Microsoft.CodeAnalysis | >= 4.5.0 |
| Microsoft.Data.Sqlite | >= 8.0.0 |
| Microsoft.Extensions.Caching.Memory | >= 8.0.0 |
| Microsoft.Extensions.Configuration | >= 8.0.0 |
| Microsoft.Extensions.Configuration.Abstractions | >= 8.0.0 |
| Microsoft.Extensions.Configuration.EnvironmentVariables | >= 8.0.0 |
| Microsoft.Extensions.Configuration.Json | >= 8.0.0 |
| Microsoft.Extensions.DependencyInjection | >= 8.0.0 |
| Microsoft.Extensions.Hosting.Abstractions | >= 8.0.0 |
| Microsoft.Extensions.Http | >= 8.0.0 |
| Microsoft.Extensions.Http.Polly | >= 8.0.0 |
| Microsoft.Extensions.Logging | >= 8.0.0 |
| Microsoft.Extensions.Logging.Abstractions | >= 8.0.0 |
| Microsoft.Extensions.Logging.Console | >= 8.0.0 |
| Microsoft.Extensions.Options | >= 8.0.0 |
| Microsoft.ML.OnnxRuntime | >= 1.16.1 |
| Microsoft.NET.Test.Sdk | >= 17.12.0 |
| Polly | >= 8.0.0 |
| Polly.Extensions.Http | >= 3.0.0 |
| PolySharp | >= 1.4.0 |
| Serilog | >= 4.3.0 |
| Serilog.Extensions.Logging | >= 7.0.0 |
| Serilog.Sinks.File | >= 6.0.0 |
| SkiaSharp | >= 3.116.1 |
| Spire.Docfor.NETStandard | >= 14.8.0 |
| Spire.PDFfor.NETStandard | >= 12.8.3 |
| Spire.Presentationfor.NETStandard | >= 11.8.2 |
| Spire.XLSfor.NETStandard | >= 16.8.2 |
| System.Text.Json | >= 10.0.10 |
| xunit | >= 2.9.2 |
| xunit.runner.visualstudio | >= 2.8.2 |
AI-Powered Document Processing
Core Workflow
Document AI processing follows this pattern:
- Create a document object (Workbook / Document / PdfDocument / Presentation)
- Load a preset document (optional; can start with an empty document)
- Configure AIOptions (set SpireToken)
- Call
.AI(options)to obtain an AIDocumentProcessor - Execute AI instructions and monitor execution status:
- Processing existing documents: Call
AIDocumentProcessor.ExecuteInstruction(), returnsAIResult - Generating PPT documents: Call
AIDocumentProcessor.GeneratePresentation(), returnsGenerationResult
- Processing existing documents: Call
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:
- Contact sales@e-iceblue.com or visit https://www.e-iceblue.com/TemLicense.html to obtain a trial or commercial API key
Configure it in your code:
AIOptions options = new AIOptions();
options.SpireToken = key;
Copy Excel Worksheets with JavaScript in React
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:
- Copy a worksheet within the same workbook
- Copy a worksheet across workbooks
- Copy a selected cell range
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.

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.

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.

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.
Add, Remove, and Move Excel Worksheets with JavaScript in React
Managing worksheets — adding, removing, and reordering them — is one of the most fundamental and frequently used operations in Excel document processing. Spire.XLS for JavaScript handles these operations 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.
Add Worksheet
Adding new worksheets to a workbook is a common requirement in daily development. Spire.XLS for JavaScript provides the Add method to create a new worksheet and give it a name. After adding, you can write data to the new sheet's cells and save the workbook.
function App() {
const startProcessing = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
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 = 'AddWorksheet.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// Create a workbook instance and load the file
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// Add a new worksheet named "NewSheet"
const sheet = workbook.Worksheets.Add("NewSheet");
sheet.Range.get("C5").Text = "This is an inserted sheet.";
// Auto-fit columns
sheet.AllocatedRange.AutoFitColumns();
// Save the workbook
const outputFileName = "AddWorksheet_output.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the output file from VFS, wrap it as a Blob, and trigger download
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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 Worksheet</h1>
<button onClick={startProcessing}>
Start
</button>
</div>
);
}
export default App;
Adding a new worksheet after the existing ones via the Add method.

Remove Worksheet
When you need to clean up unwanted worksheets from a workbook, you can remove them directly by name. Spire.XLS for JavaScript's Remove method precisely locates and removes the target worksheet.
function App() {
const startProcessing = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
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 = 'RemoveWorksheet.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// Create a workbook instance and load the file
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// Remove a worksheet by name
const sheet = workbook.Worksheets.get("Sheet2");
workbook.Worksheets.Remove(sheet);
// Remove by index
//workbook.Worksheets.RemoveAt(1);
// Save the workbook
const outputFileName = "RemoveWorksheet_output.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the output file from VFS, wrap it as a Blob, and trigger download
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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 Worksheet</h1>
<button onClick={startProcessing}>
Start
</button>
</div>
);
}
export default App;
Using Remove to delete a worksheet by name.

Move and Reorder Worksheets
Reordering worksheets is a common task when organizing an Excel document. With Spire.XLS for JavaScript's MoveWorksheet method, you can move a worksheet to a target index position, effectively reordering the sheets within the workbook.
function App() {
const startProcessing = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
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/`);
// Create a workbook instance and load the file
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// Get the first worksheet and move it to index 1
const sheet = workbook.Worksheets.get(0);
sheet.MoveWorksheet(1);
// Save the workbook
const outputFileName = "MoveWorksheet_output.xlsx";
workbook.SaveToFile({ fileName: outputFileName });
// Release resources
workbook.Dispose();
// Read the output file from VFS, wrap it as a Blob, and trigger download
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], { 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>Move Worksheet</h1>
<button onClick={startProcessing}>
Start
</button>
</div>
);
}
export default App;
Moving the first worksheet to the second sheet position via the MoveWorksheet method.

FAQ
Index out of range when operating on worksheets
Cause: The index parameter is outside the range of the current worksheet collection in the workbook.
Solution: Verify the total number of worksheets before performing the operation, ensuring the index is within 0 to worksheets.Count-1. Use workbook.Worksheets.Count to get the current total:
const count = workbook.Worksheets.Count;
Worksheet not found when removing by name
Cause: The specified worksheet name does not exactly match the actual name in the workbook.
Solution: Iterate through the worksheet names to confirm before removal:
for (let i = 0; i < workbook.Worksheets.Count; i++) {
let name = workbook.Worksheets.get(i).Name;
console.log(name);
}
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.