Knowledgebase (2609)
Children categories
Combining PDF files is a common requirement in document management applications. For example, a React application may need to assemble invoices, reports, contracts, or scanned pages into a single PDF before the file is archived or shared. When the source documents do not need to be uploaded to a server, performing the operation in the browser can also simplify the workflow.
In this tutorial, you will learn how to merge PDF documents in a React application using Spire.PDF for JavaScript. The first example combines several complete PDF files in one operation. The second example provides more precise control by taking selected pages from different PDFs and adding them to a new document.
On this page:
- Install Spire.PDF for JavaScript in a React Project
- Merge Multiple PDF Documents in React
- Merge Selected Pages from Different PDF Documents in React
- Important Implementation Notes
- Conclusion
Install Spire.PDF for JavaScript in a React Project
Open a terminal in the root directory of your React project and install the spire.office package:
npm i spire.office
After the installation is complete, copy the following runtime files and folder from the installed package to the React project's public folder:
public/
├── _framework/
├── spire.pdf.js
├── Spire.Pdf.Wasm.zip
├── spire.common.js
└── Spire.Common.Wasm.zip
The JavaScript loader, WebAssembly resources, and supporting framework files must remain accessible as static assets when the application runs. For detailed setup instructions and the exact integration process, see How to Integrate Spire.PDF for JavaScript in a React Project.
For the examples in this article, also place the input PDF files in the public folder so that the application can retrieve them with fetch():
public/
├── input_1.pdf
├── input_2.pdf
├── input_3.pdf
└── ...
Merge Multiple PDF Documents in React
If every page in every source file should appear in the result, the most direct approach is to use the PdfMerger.Merge() method. It accepts an array of input file paths, merges the files in the order in which they appear in the array, and writes the result to the WebAssembly virtual file system.
The following React component merges input_1.pdf, input_2.pdf, and input_3.pdf into a single document named MergedPdf.pdf:
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
const [isGenerating, setIsGenerating] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.pdf.js`);
const rawModule = spireModule.default || spireModule;
window.wasmModule = typeof rawModule === 'function'
? await rawModule({ locateFile: p => p.endsWith('.wasm') ? `${publicUrl}/${p}` : p })
: rawModule;
setWasmModule(window.wasmModule);
} catch (error) {
console.error('Failed to load spire.pdf.js:', error);
}
})();
}, []);
const loadPdfToVfs = async (fileName) => {
const publicUrl = process.env.PUBLIC_URL || '';
const response = await fetch(`${publicUrl}/${fileName}`);
if (!response.ok) {
throw new Error(`Failed to load ${fileName}: ${response.status} ${response.statusText}`);
}
const fileBytes = new Uint8Array(await response.arrayBuffer());
const pdfHeader = String.fromCharCode(...fileBytes.slice(0, 4));
if (pdfHeader !== '%PDF') {
throw new Error(`${fileName} was loaded, but it is not a valid PDF file.`);
}
window.dotnetRuntime.Module.FS.writeFile(fileName, fileBytes, { flags: 'w+' });
return fileName;
};
const MergePdfs = async () => {
const wasmModule = window.wasmModule?.spirepdf;
if (!wasmModule || isGenerating) {
return;
}
setIsGenerating(true);
setErrorMessage('');
try {
const inputFiles = await Promise.all([
loadPdfToVfs('input_1.pdf'),
loadPdfToVfs('input_2.pdf'),
loadPdfToVfs('input_3.pdf'),
]);
const outputFileName = 'MergedPdf.pdf';
const mergeOp = new wasmModule.MergerOptions();
wasmModule.PdfMerger.Merge({
inputFiles,
outputFile: outputFileName,
pdfMergeOptions: mergeOp
});
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(modifiedFile);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (error) {
console.error('Failed to merge PDFs:', error);
setErrorMessage(error.message || 'Failed to merge PDFs.');
} finally {
setIsGenerating(false);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Merge PDF Documents in React</h1>
<button onClick={MergePdfs} disabled={!wasmModule || isGenerating}>
{isGenerating ? 'Generating...' : 'Generate'}
</button>
{errorMessage && <p style={{ color: 'crimson' }}>{errorMessage}</p>}
</div>
);
}
export default App;
Output:

How the Code Works
The component first loads spire.pdf.js inside useEffect(). Because the module is initialized asynchronously, the Generate button remains disabled until the runtime is ready.
The loadPdfToVfs() function then performs three tasks for each source document:
- It retrieves the PDF from the
publicdirectory withfetch(). - It checks the first four bytes for the
%PDFsignature to help catch missing files or non-PDF responses. - It writes the file bytes to the WebAssembly virtual file system, where Spire.PDF can access them.
After all three files have been loaded, PdfMerger.Merge() combines them in the order specified by inputFiles. The output is read from the virtual file system, converted to a PDF Blob, and downloaded through a temporary object URL.
To change the merge order, simply rearrange the entries in the array. For example, the following order would place input_3.pdf first:
const inputFiles = await Promise.all([
loadPdfToVfs('input_3.pdf'),
loadPdfToVfs('input_1.pdf'),
loadPdfToVfs('input_2.pdf'),
]);
Merge Selected Pages from Different PDF Documents in React
Merging complete documents is not always necessary. You may instead need to create a new PDF from a cover page in one file and a page range in another file. In this situation, load the source files as PdfDocument objects and use InsertPage() and InsertPageRange() to construct the output document.
The following example takes the first page from input_1.pdf, appends every page from input_2.pdf, and saves the selected content as MergedPdf.pdf:
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
const [isGenerating, setIsGenerating] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.pdf.js`);
const rawModule = spireModule.default || spireModule;
window.wasmModule = typeof rawModule === 'function'
? await rawModule({ locateFile: p => p.endsWith('.wasm') ? `${publicUrl}/${p}` : p })
: rawModule;
setWasmModule(window.wasmModule);
} catch (error) {
console.error('Failed to load spire.pdf.js:', error);
}
})();
}, []);
const loadPdfToVfs = async (fileName) => {
const publicUrl = process.env.PUBLIC_URL || '';
const response = await fetch(`${publicUrl}/${fileName}`);
if (!response.ok) {
throw new Error(`Failed to load ${fileName}: ${response.status} ${response.statusText}`);
}
const fileBytes = new Uint8Array(await response.arrayBuffer());
const pdfHeader = String.fromCharCode(...fileBytes.slice(0, 4));
if (pdfHeader !== '%PDF') {
throw new Error(`${fileName} was loaded, but it is not a valid PDF file.`);
}
window.dotnetRuntime.Module.FS.writeFile(fileName, fileBytes, { flags: 'w+' });
return fileName;
};
const MergePdfs = async () => {
const wasmModule = window.wasmModule?.spirepdf;
if (!wasmModule || isGenerating) {
return;
}
setIsGenerating(true);
setErrorMessage('');
try {
const [firstInputFile, secondInputFile] = await Promise.all([
loadPdfToVfs('input_1.pdf'),
loadPdfToVfs('input_2.pdf'),
]);
const outputFileName = 'MergedPdf.pdf';
const firstDocument = new wasmModule.PdfDocument();
const secondDocument = new wasmModule.PdfDocument();
const mergedDocument = new wasmModule.PdfDocument();
firstDocument.LoadFromFile({ fileName: firstInputFile });
secondDocument.LoadFromFile({ fileName: secondInputFile });
if (firstDocument.Pages.Count < 1) {
throw new Error('The first PDF does not contain any pages.');
}
if (secondDocument.Pages.Count < 1) {
throw new Error('The second PDF does not contain any pages.');
}
mergedDocument.InsertPage({ ldDoc: firstDocument, pageIndex: 0 });
mergedDocument.InsertPageRange(secondDocument, 0, secondDocument.Pages.Count - 1);
mergedDocument.SaveToFile({ fileName: outputFileName });
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(modifiedFile);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} catch (error) {
console.error('Failed to merge PDFs:', error);
setErrorMessage(error.message || 'Failed to merge PDFs.');
} finally {
setIsGenerating(false);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Merge PDF Documents in React</h1>
<button onClick={MergePdfs} disabled={!wasmModule || isGenerating}>
{isGenerating ? 'Generating...' : 'Generate'}
</button>
{errorMessage && <p style={{ color: 'crimson' }}>{errorMessage}</p>}
</div>
);
}
export default App;
Output:

Understanding the Page Selection Logic
The three PdfDocument instances have different roles:
firstDocumentrepresentsinput_1.pdf.secondDocumentrepresentsinput_2.pdf.mergedDocumentis the new PDF that receives the selected pages.
PDF page indexes are zero-based in this example. Therefore, pageIndex: 0 refers to the first page:
mergedDocument.InsertPage({ ldDoc: firstDocument, pageIndex: 0 });
The following statement inserts a continuous range from secondDocument. Its start index is 0, while its end index is secondDocument.Pages.Count - 1, so the complete document is appended:
mergedDocument.InsertPageRange(
secondDocument,
0,
secondDocument.Pages.Count - 1
);
You can change these indexes to merge only the pages required by your application. For instance, this statement inserts pages 2 through 5 from secondDocument because their zero-based indexes are 1 through 4:
mergedDocument.InsertPageRange(secondDocument, 1, 4);
Before using fixed page indexes, make sure the source document contains enough pages. The sample already checks for empty PDFs, but a production application should also validate user-supplied start and end indexes against Pages.Count.
Important Implementation Notes
Keep Runtime and Input Paths Correct
Files stored in the React public directory are requested by URL at runtime. The code uses process.env.PUBLIC_URL so it can construct paths correctly when the application is deployed under a non-root public path. A missing or incorrect file path may return an HTML error page instead of a PDF, which is why the sample verifies the %PDF header before writing the data to the virtual file system.
Wait for WebAssembly Initialization
Spire.PDF cannot process a document until its runtime has finished loading. The wasmModule state controls the button's disabled status, while isGenerating prevents the same operation from being started repeatedly before the current merge has finished.
Validate Page Ranges
When pages are chosen dynamically, check that the start and end indexes are non-negative, that the start index does not exceed the end index, and that both values fall within the source document's page count. This avoids invalid range errors and makes it easier to show a useful message in the React interface.
Release the Download URL
URL.createObjectURL() creates a temporary URL for the generated Blob. Calling URL.revokeObjectURL(url) after the download starts releases that URL and prevents it from remaining in browser memory longer than necessary.
Conclusion
Spire.PDF for JavaScript enables React applications to combine PDF content through a WebAssembly-based workflow. When all pages are required, PdfMerger.Merge() provides a concise way to merge several complete documents in a defined order. When the output must contain only specific content, PdfDocument, InsertPage(), and InsertPageRange() provide page-level control over the result.
With the runtime files configured in the public directory, these techniques can be integrated into document portals, reporting tools, contract workflows, and other React applications that need to assemble PDFs directly in the browser.
In cross-industry data processing scenarios, importing data from CSV and PDF files into Excel is one of the most common and error-prone tasks — finance teams reconcile CSV bank statements, e-commerce teams organize order files exported from multiple platforms, and administrative staff handle PDF statements from suppliers. These files come in all shapes and formats: inconsistent CSV delimiters, fields containing commas, dates appearing in various forms, phone numbers and ID numbers that start with 0 are treated as numbers and lose their leading zeros; PDF tables cannot be edited directly, and copying them into Excel misaligns rows, columns, and merged cells.
The traditional approach is to split columns manually, set formats column by column, and hunt for erroneous cells by eye. A CSV file with a few hundred rows often takes half an hour of repeated adjustment; PDF tables can only be copied and pasted row by row. Traditional methods are also prone to misaligned columns, misplaced dates, and numbers turning into text. As data volume grows, manual processing becomes nearly impossible.
Take a finance team reconciling bank statements, for example: after receiving a CSV, the usual routine is to confirm the encoding in a text editor first, split the columns in Excel, set date and amount formats column by column, and then hunt for anomalous values by eye. A field containing a comma shifts the whole row, accounts starting with 0 lose their leading zeros, and only after repeated adjustment does the table become usable. PDF statements can only be copied and pasted row by row — rows, columns, and merged cells are almost all misaligned, and reconstructing a single statement often eats up half a day.
Comparison with Traditional SDK API Processing
| Traditional Spire.Office for .NET API | Spire.Agent.Office Processing | |
|---|---|---|
| Driving Method | Write code for column splitting, type conversion, and format checking, controlling every step | Describe the goal in natural language; the AI understands and automatically orchestrates the execution path |
| Code Volume | Data import scenarios typically require 500-1000 lines of C# code (including parsers, type conversion, error detection, etc.) | About 10 lines of calling code + one natural language instruction |
| Delimiters & Quoting | Must hand-write parsing logic for edge cases such as commas inside quotes and escape characters | The AI automatically recognizes delimiters and quoted fields and splits columns intelligently |
| Type Detection | Must hard-code date/number/text recognition rules per column; changing rules requires code changes | The AI understands data type semantics and automatically recognizes dates, numbers, and text |
| Error Detection | Must write regex and conditional checks cell by cell; coverage of error types is incomplete | The AI automatically detects anomalies such as type mismatches and column count mismatches and highlights them in red |
| Requirement Changes | Adding a new CSV variant requires modifying code → compiling → deploying | Modify the description in the instruction; takes effect immediately |
This article introduces how to use the Excel AI capabilities of Spire.Agent.Office to implement CSV smart column splitting import and PDF table import, automatically completing data type detection and highlighting erroneous formats in red, with just a single natural language instruction.
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.
CSV Smart Column Splitting Import
CSV is the most common format for data exchange, yet also the least "controllable": the delimiter may be a comma, a tab, or a semicolon; fields may contain commas or line breaks wrapped in quotes; dates, numbers, and text are mixed in the same table; values starting with 0, such as phone numbers and codes, are treated as numbers by default and lose their leading zeros. Import quality directly determines the accuracy of subsequent analysis and reports.
The following example uses the Spire.Agent.Office agent to automatically import a CSV through natural language instructions, completing smart column splitting, data type detection, and highlighting erroneous formats in red:
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;
// CSV source file to be imported (passed as an attachment)
string[] attachmentPaths = new string[] { @"C:\DataImport\employee_sales_data.csv" };
// Save path of the import result document
string savePath = @"C:\DataImport\ToXLSX.xlsx";
// SpireToken Key (apply on the official website)
string key = "sk-TF***************************r";
// Natural language instruction
string instruction = "Process as follows:\n" +
"1. Convert the attached CSV file to an Excel document and apply appropriate formatting to improve readability\n" +
"2. Unify the formats of dates/sales amounts/phone numbers in the file\n" +
"3. Mark erroneous and missing data with a red background";
// AI generation
AIResult result = ImportCsvData(instruction, savePath, key, attachmentPaths);
// AI-assisted CSV import
static AIResult ImportCsvData(string instruction, string savePath, string key, string[] attachmentPaths)
{
// Configure the AI processing options
AIOptions options = new AIOptions();
options.SpireToken = key;
using (Workbook wb = new Workbook())
{
AIDocumentProcessor processor = wb.AI(options);
return processor.ExecuteInstruction(wb, instruction, savePath, attachmentPaths);
}
}
Original CSV data and smart column splitting import result

PDF Table Import to Excel
PDF is the universal format for distribution and archiving, but the table data inside it cannot be edited directly: copying it into Excel misaligns rows and columns, loses merged cells, and turns numbers and dates into text. When suppliers, banks, or government agencies deliver reports in PDF, accurately restoring the table data into editable Excel is an essential step in moving from fixed-layout documents to electronic processing.
The following example uses the Spire.Agent.Office agent to automatically extract table data from a PDF and write it into Excel through natural language instructions:
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;
// PDF source file to be imported (passed as an attachment)
string[] attachmentPaths = new string[] { @"C:\DataImport\PurchaseOrder.pdf" };
// Save path of the import result document
string savePath = @"C:\DataImport\PurchaseOrderData.xlsx";
// SpireToken Key
string key = "sk-TF***************************r";
// Natural language instruction
string instruction =
"Process as follows:\n" +
"1. Convert the attached PDF file to an Excel document and apply appropriate formatting to improve readability\n" +
"2. Unify the formats of dates/sales amounts/phone numbers in the file\n" +
"3. Mark erroneous and missing data with a red background";
// AI generation
AIResult result = ImportPdfData(instruction, savePath, key, attachmentPaths);
// AI-assisted PDF import
static AIResult ImportPdfData(string instruction, string savePath, string key, string[] attachmentPaths)
{
// Configure the AI processing options
AIOptions options = new AIOptions();
options.SpireToken = key;
using (Workbook wb = new Workbook())
{
AIDocumentProcessor processor = wb.AI(options);
return processor.ExecuteInstruction(wb, instruction, savePath, attachmentPaths);
}
}
Original PDF data and table data extracted into Excel

Frequently Asked Questions
Inconsistent CSV delimiters / commas within fields cause column misalignment
Cause: The CSV delimiter may be a semicolon or a tab, or a field may contain a quoted comma or newline, which causes the whole row to shift when columns are split automatically.
Solution: Specify the delimiter in the instruction, or let the AI identify it automatically and correctly handle the quoted fields.
Numbers starting with 0 lose their leading zeros
Cause: Values starting with 0, such as phone numbers, ID numbers, and account numbers, are imported as numeric values, and the leading zeros are dropped.
Solution: Specify the relevant columns as text type in the instruction, such as "set the phone number and ID number columns to text format and preserve the leading zeros".
Obtaining 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 it in code:
AIOptions options = new AIOptions();
options.SpireToken = key;
Automatically Extract Invoice Information with Spire.Agent.Office
2026-08-18 02:59:56 Written by zaki zakiIn finance and tax scenarios, invoice data entry is one of the most common and time-consuming tasks. The invoice number, date, amount, tax amount and buyer on every invoice must be manually checked and entered into Excel or a financial system one by one. During mid-month reconciliation, month-end tax filing or reimbursement peak periods, the backlog of invoices often numbers in the hundreds, and manual entry speed becomes the bottleneck. The traditional approach is to open each invoice PDF page by page, find the corresponding fields, copy and paste — which is not only inefficient but also highly prone to omissions, misalignments and mistyped amounts. Any single error directly affects the accuracy of reconciliation and tax filing. Invoice layouts also vary widely, with fields in all sorts of positions, further increasing the risk of errors in manual processing. Automating the repetitive work of "reading each invoice and copying its fields" is therefore one of the pain points financial teams most urgently want to solve.
Traditional SDK API vs. Spire.Agent.Office
For "extracting fields from a PDF invoice and exporting to Excel", the traditional SDK and Spire.Agent.Office take two completely different paths. With the traditional approach, you must first figure out the field positions and page structure of every invoice, then write locating and extraction code for each field — change the layout and you must change the code. With the agent approach, you only need to describe in natural language "what to extract and what to export as"; the AI understands and orchestrates the rest:
| Traditional Spire.Office for .NET API | Spire.Agent.Office | |
|---|---|---|
| Driving approach | Write loops + conditionals + exception-handling code, controlling every step of document processing | Describe the goal in natural language; the AI understands and orchestrates the execution path |
| Code volume | Page-by-page parsing usually needs 300-600 lines of C# (page traversal, field locating, data export, etc.) | ~10 lines of calling code + 1 natural language instruction |
| Field recognition | Hard-code the page position and format of each field; layout changes require code changes | AI automatically understands the invoice layout and locates fields such as invoice number, date, amount |
| Page handling | Manually traverse every page and extract each one | AI automatically extracts page by page and aggregates |
| Data export | Manually write Excel writing logic and column layout | AI automatically generates a structured Excel with aligned fields |
| Requirement changes | Change extracted fields → change code → compile → redeploy | Modify the instruction; takes effect immediately |
From the comparison, when invoice layouts, extracted fields or export structures change frequently, the agent only needs a change of one sentence, while the traditional approach requires changing code and redeploying.
This article explains how to use the Spire.Agent.Office PDF AI capability to automatically extract the invoice number, date, amount, tax amount and buyer name from each page of a PDF invoice and export them to Excel, digitalizing your financial documents in one step.
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 installed and SpireToken is configured.
Automatic Invoice Information Extraction
The core idea of automatic invoice information extraction is: pass multiple invoice PDFs to the AI agent as attachments; the agent reads each invoice, understands the layout page by page, recognizes fields such as invoice number, issue date, amount, tax ID, tax amount, buyer name and title, and aggregates them into a structured Excel. The whole process is roughly divided into three steps — first the agent reads each invoice PDF and locates the invoice fields on every page; second, it aligns the fields recognized on each page by semantics; finally, it aggregates the results into Excel and beautifies them as requested (auto-fitting column widths, adding borders, keeping numeric values with two decimal places and right-aligned). The whole "page-by-page parsing → field recognition → aggregation & beautification" process is completed automatically by the AI from a natural language instruction, without writing a separate parsing routine for each invoice or worrying about layout differences between suppliers.
For invoice PDFs with dozens or hundreds of pages, the traditional approach requires a set of locating rules for each layout, whereas with the agent approach you always maintain just one natural language instruction no matter how the invoice source or layout changes. Requirements such as the amount basis (tax-inclusive vs. tax-exclusive), column order, or whether to flag anomalies can also be written directly into the instruction and take effect immediately.
The following example uses the Spire.Agent.Office agent to automatically extract invoice information from each page of PDFs and export it to Excel through a natural language instruction:
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Pdf;
// PDF processing configuration
string key = "**************************"; // Apply for a SpireToken Key on the official website
string inputDir = @"E:\invoices"; // Directory containing invoice PDFs (multiple allowed)
string[] pdfFiles = Directory.GetFiles(inputDir, "*.pdf", SearchOption.TopDirectoryOnly);
string savePath = @"E:\output\merged.xlsx"; // Output file path (null -> auto-generated to the output directory)
string instruction =
"Read the attachment files and identify the information of each invoice, extracting the invoice number, issue date, amount, tax ID, tax amount, buyer name and title.\n" +
"Put each invoice as one row and summarize them into a single Excel table.\n" +
"When exporting to Excel, please beautify the table appropriately:\n" +
"auto-fit the column widths so that text is fully displayed; add borders to the whole data area to make rows and columns clear and readable;\n" +
"keep numeric columns such as amount and tax amount with two decimal places and right-aligned. Finally save as a well-formatted, easy-to-read Excel file.";
// Call the PDF processing function (attachments are the invoice PDFs)
AIResult result = ExecuteDemoPDF(instruction, savePath, key, pdfFiles);
// Execute PDF document AI processing
static AIResult ExecuteDemoPDF(string instruction, string savePath, string key, string[] attachments)
{
// Create an AIOptions configuration object
AIOptions options = new AIOptions();
options.SpireToken = key; // Set SpireToken Key
// Process the PDF document with a PdfDocument object
using (PdfDocument pdf = new PdfDocument())
{
// Create the AI document processor; attachments are the invoice PDFs
AIDocumentProcessor processor = pdf.AI(options);
return processor.ExecuteInstruction(pdf, instruction, savePath, attachments);
}
}
Original invoice PDF
Extracted and exported Excel 
FAQ
The extracted amount or tax amount is incorrect
Reason: The invoice amount has both uppercase and lowercase forms, or the tax-inclusive/tax-exclusive basis is inconsistent.
Solution: Specify the extraction basis clearly in the instruction (e.g., "extract the total amount including tax", "extract the amount excluding tax"); the AI agent will extract according to the specified basis. If the invoice has two forms of amount, it is also recommended to state which one takes precedence to avoid ambiguity.
How are invoices with different layouts recognized?
Reason: Invoices from different suppliers have different layouts and field positions.
Solution: The AI agent can automatically understand the invoice layout and locate fields; for unusual layouts, you can add field hints in the instruction (e.g., "the invoice number is located in the upper-right corner") to help the agent locate more accurately.
The column order / field names of the result don't match expectations
Reason: By default the AI outputs fields in the order it recognizes them.
Solution: Specify the field names and order clearly in the instruction (e.g., "export in the order: invoice number, date, amount, tax amount, buyer"), and the agent will arrange the output columns as requested.
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 it in code:
AIOptions options = new AIOptions();
options.SpireToken = key;