Word模板是企业业务流转的底座,HR 需要标准的劳动合同和录用通知书,销售需要专业的报价单和报告模板,行政需要统一的会议通知和证明文件。Spire.Agent.Office 的 Word AI 能力只需用自然语言描述想要的模板样式和内容结构,比如“包含‘姓名 职位部门 薪资 开始日期 结束日期 合同类型 试用期月份 地点’字段的邮件合并域的合同模板”,AI 即可直接制作交付。
| 传统 Spire.Office for .NET API | Spire.Agent.Office | |
|---|---|---|
| 开发方式 | 调用 API 逐行逐段构建文档结构 | 使用自然语言描述模板样式和结构,AI 自动编排并生成完整模板文档 |
| 代码量 | 每个模板需编写数百行文档构建代码 | 仅需 1 条自然语言指令 |
| 样式调整 | 字体、颜色、边框等样式,通过代设置排版非常复杂 | 直接自然指令描述即可 |
| 模板灵活性 | 模板结构变更需重写底层文档构建逻辑,维护成本高 | 调整指令描述,AI 即可重新生成,灵活响应需求变化 |
几类典型业务场景的Word 模板制作:
有关产品安装和 SpireToken 配置,请参考 在 .NET 项目中集成 Spire.Agent.Office。以下示例默认已安装 Spire.Agent.Office 并完成 SpireToken 配置。
人力资源部门最常用的劳动合同都有相对固定的结构:标题、当事人信息、正文条款、签署栏等。
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;
string inputPath = @"";
// 结果文档路径
string savePath = @"合并模板.docx"; ;
// SpireToken Key
string key = "s******************************r";
// 自然语言指令
string instruction =
"生成一份Word劳动合同模板。" +
"主标题为'劳动合同',二号字,加粗,居中。" +
"正文全部使用仿宋字体,小四号(12pt),段落首行缩进2字符。" +
"整篇文档添加'E-iceblue'淡蓝色水印字样。" +
"包含以下字段的邮件合并域:姓名、职位部门、薪资、开始日期、结束日期、合同类型、试用期月份、地点。" +
"整体风格正式专业,符合法律文书场景。";
// AI 生成
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);
// Word AI 处理
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
// 创建 AI 处理器选项实例
AIOptions options = new AIOptions();
options.SpireToken = key;
// 创建 Word 文档对象
using (Document doc = new Document())
{
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
doc.LoadFromFile(inputPath);
}
// 创建 AI 文档处理器实例
AIDocumentProcessor processor = doc.AI(options);
// 根据指令处理文档,并保存结果到指定路径
return processor.ExecuteInstruction(doc, instruction, savePath);
}
}

销售与商务部门最常用的报价单都有相对固定的结构:标题、公司信息、客户信息、产品报价表格、金额汇总、报价条款、签署栏等。
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;
string inputPath = @"";
// 结果文档路径
string savePath = @"报价单模板.docx"; ;
// SpireToken Key
string key = "s******************************r";
// 自然语言指令
string instruction =
"生成一份专业的报价单模板,样式要求如下:" +
"主标题为'报价单',一号字,加粗,居中,使用微软雅黑字体。" +
"正文使用宋体,小四号(12pt),1.5倍行距。" + "模板结构包含:公司Logo占位区、公司信息(地址、电话、邮箱)、客户信息(客户名称、联系人)、产品报价表格(包含序号、产品名称、规格、数量、单价、小计、备注)、总价(大写+小写)、报价有效期、公司签章区。\n" +
"在模板中使用{{}}作为占位符标记,例如:{{公司名称}}、{{客户名称}}、{{产品名称}}、{{单价}}、{{数量}}、{{小计}}、{{总价大写}}、{{总价小写}}。";
// AI 生成
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);
// Word AI 处理
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
// 创建 AI 处理器选项实例
AIOptions options = new AIOptions();
options.SpireToken = key;
// 创建 Word 文档对象
using (Document doc = new Document())
{
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
doc.LoadFromFile(inputPath);
}
// 创建 AI 文档处理器实例
AIDocumentProcessor processor = doc.AI(options);
// 根据指令处理文档,并保存结果到指定路径
return processor.ExecuteInstruction(doc, instruction, savePath);
}
}

证书模板在培训认证、表彰奖励、活动参与等场景中被广泛使用,其核心结构通常包括:证书标题(如“荣誉证书”“结业证书”等)、证书编号等。
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;
string inputPath = @"";
// 结果文档路径
string savePath = @"Word证书模板.docx"; ;
// SpireToken Key
string key = "s******************************r";
// 自然语言指令
string instruction =
"生成一页的荣誉证书模板,样式要求如下:" +
"整体采用古典庄重风格,添加金色双线边框,使用华文中宋字体" +
"顶部居中放置证书标题:'荣誉证书'——初号字,加粗,金色" +
"正文区域居中布局,内容结构为:" +
" 第一行:'兹证明';" +
" 第二行:'{{姓名}}'字体加粗,红色;" +
" 第三行:'在{{年份}}年度工作中表现优异,被评为:'" +
" 第四行:'{{荣誉称号}}'字体加粗,金色" +
" 第五行:'特发此证,以资鼓励。'。" +
"落款区域:右下角分两行显示'{{颁发单位}}'和'{{日期}}',右对齐。" +
"左下角添加证书编号:'编号:{{证书编号}}'。" +
"整体风格正式、庄重、大气,适合政府或企业颁发的荣誉证书场景。";
// AI 生成
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);
// Word AI 处理
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
// 创建 AI 处理器选项实例
AIOptions options = new AIOptions();
options.SpireToken = key;
// 创建 Word 文档对象
using (Document doc = new Document())
{
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
doc.LoadFromFile(inputPath);
}
// 创建 AI 文档处理器实例
AIDocumentProcessor processor = doc.AI(options);
// 根据指令处理文档,并保存结果到指定路径
return processor.ExecuteInstruction(doc, instruction, savePath);
}
}

预算报告模板是企业或组织在进行财务规划、项目申报、年度计划时常用的文档工具,其核心结构通常包括:报告标题(如“××年度预算报告”“××项目预算方案”)、编制单位与日期、预算编制说明等。
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Doc;
string inputPath = @"";
// 结果文档路径
string savePath = @"预算报告模板.docx"; ;
// SpireToken Key
string key = "s******************************r";
// 自然语言指令
string instruction =
"生成一份专业的预算报告模板,样式要求如下:" +
"主标题'{{年度}}年度预算报告'——一号字,加粗,居中,使用微软雅黑。" +
"标题下方添加副标题:'编制单位:{{部门名称}} | 编制日期:{{编制日期}}',小四号,居中。" +
"正文部分分为四个区域:\n" +
" 区域一(预算总览):顶部用卡片式布局展示四项关键指标——'年度预算总额:{{预算总额}}万元'、'已执行金额:{{已执行}}万元'、'执行率:{{执行率}}%'、'剩余预算:{{剩余预算}}万元',四个数据用浅色底纹框并列显示,数字加粗放大。\n" +
" 区域二(预算明细表):详细预算表,包含列——科目编码、科目名称、年度预算(万元)、Q1执行、Q2执行、Q3执行、Q4执行、已执行合计、执行率(%)、剩余预算(万元)。表头背景深绿色(#1E5631),白色加粗字体;数字列保留两位小数;数据行交替颜色。\n" +
" 区域四(预算说明):页面底部添加'预算说明'区域——'{{预算编制说明}}'。\n" +
"整体风格规范大气,适合向管理层汇报的正式预算报告场景。";
// AI 生成
AIResult result = ExecuteAIWord(instruction, inputPath, savePath, key);
// Word AI 处理
static AIResult ExecuteAIWord(string instruction, string inputPath, string savePath, string key)
{
// 创建 AI 处理器选项实例
AIOptions options = new AIOptions();
options.SpireToken = key;
// 创建 Word 文档对象
using (Document doc = new Document())
{
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
doc.LoadFromFile(inputPath);
}
// 创建 AI 文档处理器实例
AIDocumentProcessor processor = doc.AI(options);
// 根据指令处理文档,并保存结果到指定路径
return processor.ExecuteInstruction(doc, instruction, savePath);
}
}

原因:指令中的样式描述不够具体。
解决:在指令中明确指定字体名称等细节。
原因:业务需求变化导致模板需要调整。
解决:直接在指令中描述修改内容重新生成,或者将当前文档作为输入文件,使用AI二次操作。
原因:系统中缺少指令中指定的字体。
解决:确保系统安装了指令中提到的字体。或在指令中使用常见系统字体。
在代码中配置:
AIOptions options = new AIOptions();
options.SpireToken = key;
数据透视图是以图形方式直观展示数据透视表汇总结果的图表,它让数据比较与趋势一目了然,是进行数据分析与报表展示的重要工具。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成对 Excel 数据透视图的创建、字段按钮控制与系列格式设置,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。它提供了完整的 API 用于创建基于数据透视表的数据透视图、控制数据透视图字段按钮的显示与隐藏,以及自定义数据透视图系列的外观格式。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
数据透视图必须基于数据透视表来创建。Spire.XLS for JavaScript 支持在工作表中先创建数据透视表,再通过 Charts.Add() 方法指定 pivotChartType 和 pivotTable 参数,基于该数据透视表直接生成对应的数据透视图。具体操作步骤如下:
Workbook 对象并获取默认工作表。PivotCaches.Add() 创建数据透视表缓存。PivotTables.Add() 添加数据透视表,并将字段拖至行区域和数据区域。sheet.Charts.Add() 添加图表,并通过 pivotChartType 和 pivotTable 参数基于数据透视表创建数据透视图。SaveToFile() 保存工作簿为 Excel 文件。下面是一个完整的代码示例,展示了在 React 中基于数据透视表创建数据透视图:
function App() {
const createPivotChart = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将中文字体加载到虚拟文件系统(VFS)
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// 创建新工作簿并获取默认工作表
const workbook = new xlsModule.Workbook();
let sheet = workbook.Worksheets.get(0);
// 填入数据透视表的源数据
sheet.Range.get('A1').Value = '产品';
sheet.Range.get('B1').Value = '月份';
sheet.Range.get('C1').Value = '销量';
sheet.Range.get('A2').Value = '苹果';
sheet.Range.get('A3').Value = '苹果';
sheet.Range.get('A4').Value = '香蕉';
sheet.Range.get('A5').Value = '苹果';
sheet.Range.get('A6').Value = '香蕉';
sheet.Range.get('A7').Value = '香蕉';
sheet.Range.get('B2').Value = '一月';
sheet.Range.get('B3').Value = '二月';
sheet.Range.get('B4').Value = '一月';
sheet.Range.get('B5').Value = '一月';
sheet.Range.get('B6').Value = '二月';
sheet.Range.get('B7').Value = '二月';
sheet.Range.get('C2').Value = '10';
sheet.Range.get('C3').Value = '15';
sheet.Range.get('C4').Value = '9';
sheet.Range.get('C5').Value = '7';
sheet.Range.get('C6').Value = '8';
sheet.Range.get('C7').Value = '10';
// 创建数据透视表
let dataRange = sheet.Range.get('A1:C7');
let cache = workbook.PivotCaches.Add({ range: dataRange });
let pivotTable = sheet.PivotTables.Add('数据透视表', sheet.Range.get({ row: 1, column: 5 }), cache);
// 将字段拖到行区域
let pf = pivotTable.PivotFields.get_Item('产品');
pf.Axis = xlsModule.AxisTypes.Row;
let pf2 = pivotTable.PivotFields.get_Item('月份');
pf2.Axis = xlsModule.AxisTypes.Row;
// 将字段拖到数据区域
pivotTable.DataFields.Add(pivotTable.PivotFields.get_Item('销量'), '求和项:销量', xlsModule.SubtotalTypes.Sum);
// 设置数据透视表样式并计算结果
pivotTable.BuiltInStyle = xlsModule.PivotBuiltInStyles.PivotStyleMedium12;
pivotTable.CalculateData();
// 基于数据透视表创建簇状柱形图
let chart = sheet.Charts.Add({ pivotChartType: xlsModule.ExcelChartType.ColumnClustered, pivotTable: pivotTable });
// 设置数据透视图位置
chart.TopRow = 9;
chart.LeftColumn = 1;
chart.RightColumn = 9;
chart.BottomRow = 25;
// 设置数据透视图标题
chart.ChartTitle = "数据透视图";
// 保存工作簿
const outputFileName = 'PivotChart.xlsx';
workbook.SaveToFile(outputFileName);
workbook.Dispose();
// 从 VFS 读取文件,触发下载
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>Create Pivot Chart</h1>
<button onClick={createPivotChart}>
Generate
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 在 Excel 中创建数据透视图后的效果

默认情况下,数据透视图会显示字段按钮,方便用户交互式地筛选和切换字段数据。在生成报表时,您可能希望隐藏部分或全部字段按钮,使图表更加简洁。Spire.XLS for JavaScript 提供了 DisplayEntireFieldButtons、DisplayValueFieldButtons、DisplayAxisFieldButtons、DisplayLegendFieldButtons 和 ShowReportFilterFieldButtons 等属性,用于灵活控制各类型字段按钮的显示与隐藏。具体操作步骤如下:
Workbook 对象并加载包含数据透视图的已有 Excel 文件。workbook.Worksheets.get() 获取工作表。sheet.Charts.get() 获取数据透视图对象。DisplayEntireFieldButtons 控制是否显示全部字段按钮。DisplayValueFieldButtons、DisplayAxisFieldButtons、DisplayLegendFieldButtons 和 ShowReportFilterFieldButtons 分别控制各类型字段按钮的显示与隐藏。SaveToFile() 保存工作簿为 Excel 文件。下面是一个完整的代码示例,展示了在 React 中显示或隐藏数据透视图的字段按钮(示例加载上一节生成的数据透视图文件 PivotChart.xlsx):
function App() {
const showHideFieldButtons = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将包含数据透视图的示例文件加载到虚拟文件系统(VFS)
let excelFileName = 'PivotChart.xlsx';
await window.spire.FetchFileToVFS(excelFileName, '', `${process.env.PUBLIC_URL}data/`);
// 创建新工作簿并加载已有文件
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: excelFileName });
// 获取第一个工作表
let sheet = workbook.Worksheets.get(0);
// 获取数据透视图
let chart = sheet.Charts.get(0);
// 控制全部字段按钮的显示
chart.DisplayEntireFieldButtons = true;
// 隐藏数值字段按钮
chart.DisplayValueFieldButtons = false;
// 隐藏坐标轴字段按钮
chart.DisplayAxisFieldButtons = false;
// 隐藏图例字段按钮
//chart.DisplayLegendFieldButtons = false;
// 显示报表筛选字段按钮
//chart.ShowReportFilterFieldButtons = true;
// 保存工作簿
const outputFileName = 'PivotChartFieldButtons.xlsx';
workbook.SaveToFile(outputFileName);
workbook.Dispose();
// 从 VFS 读取文件,触发下载
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/Hide PivotChart Field Buttons</h1>
<button onClick={showHideFieldButtons}>
Generate
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 显示或隐藏数据透视图字段按钮后的效果

对数据透视图的系列进行格式化,可以让图表更加美观、层次分明,从而更清晰地传达数据信息。Spire.XLS for JavaScript 支持加载包含数据透视图的 Excel 文件,通过 Charts.get() 方法获取数据透视图,再通过系列的 DataFormat 属性设置填充类型、颜色与边框样式,并通过 GetCommonSerieFormat() 方法返回的格式对象设置数据条宽度等格式。具体操作步骤如下:
Workbook 对象。LoadFromFile() 方法加载包含数据透视图的 Excel 文件。Worksheets.get() 方法获取 Excel 文件中的特定工作表。Charts.get() 方法获取工作表中的数据透视图。Series.get() 方法获取数据透视图的数据系列。DataFormat 属性设置系列的填充类型、颜色与边框样式,并通过 GetCommonSerieFormat() 方法设置数据条宽度等格式。SaveToFile() 方法保存生成的文件。下面是一个完整的代码示例,展示了在 React 中给数据透视图的系列设置格式(示例加载上一节生成的数据透视图文件 PivotChart.xlsx):
function App() {
const formatPivotChartSeries = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将包含数据透视表的示例文件加载到虚拟文件系统(VFS)
let excelFileName = 'PivotChart.xlsx';
await window.spire.FetchFileToVFS(excelFileName, '', `${process.env.PUBLIC_URL}data/`);
// 创建 Workbook 对象
const workbook = new xlsModule.Workbook();
// 加载 Excel 文件
workbook.LoadFromFile({ fileName: excelFileName });
// 获取第一个工作表
let sheet = workbook.Worksheets.get(0);
//获取数据透视图
let chart = sheet.Charts.get(0);
// 设置数据透视图位置
chart.TopRow = 1;
chart.LeftColumn = 8;
chart.RightColumn = 18;
chart.BottomRow = 15;
// 设置图表标题
chart.ChartTitle = "";
// 向数据透视图添加系列
let series = chart.Series.get(0);
// 设置数据条的宽度
series.GetCommonSerieFormat().GapWidth = 10;
// series.GetCommonSerieFormat().Overlap = 100;
// 设置系列的填充类型与前景色、背景色
series.DataFormat.Fill.FillType = xlsModule.ShapeFillType.SolidColor;
series.DataFormat.ForeGroundColor = xlsModule.Color.get_Red();
series.DataFormat.BackGroundColor = xlsModule.Color.get_White();
// 设置系列边框的颜色、线型与线宽
series.DataFormat.LineProperties.Pattern = xlsModule.ChartLinePatternType.Solid;
series.DataFormat.LineProperties.Color = xlsModule.Color.get_Blue();
series.DataFormat.LineProperties.CustomLineWeight = 2.5;
// 为系列添加阴影效果
series.DataFormat.IsShadow = true;
// 保存工作簿
const outputFileName = 'PivotChartSeriesFormat.xlsx';
workbook.SaveToFile(outputFileName);
workbook.Dispose();
// 从 VFS 读取文件,触发下载
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>Format PivotChart Series</h1>
<button onClick={formatPivotChartSeries}>
Generate
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 设置数据透视图系列格式后的效果

原因:数据透视图基于数据透视表创建,修改数据透视表的数据源后,图表不会自动同步更新。
解决:在修改数据源后,通过 Cache.IsRefreshOnLoad 属性让数据透视表在文件打开时自动刷新,从而同步更新数据透视图:
// 获取数据透视表
let pivotTable = sheet.PivotTables.get(0);
// 设置在文件打开时自动刷新数据透视表
pivotTable.Cache.IsRefreshOnLoad = true;
原因:数据透视图的系列来源于数据透视表的汇总结果,如果数据透视表未执行计算,或创建数据透视图时未正确关联数据透视表,图表可能会显示为空白。
解决:创建数据透视表后调用 CalculateData() 方法计算结果,并在创建数据透视图时通过 pivotTable 参数正确关联数据透视表:
// 计算数据透视表的结果
pivotTable.CalculateData();
// 基于数据透视表创建数据透视图
let chart = sheet.Charts.Add({ pivotChartType: xlsModule.ExcelChartType.ColumnClustered, pivotTable: pivotTable });
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
在传统的 Spire.Office for .NET 组件文档处理场景中,开发者需要熟悉产品 API 接口编写大量代码来实现格式设置、数据提取、文档转换等操作。Spire.Agent.Office 通过引入 AI 层使用 自然语言指令 来完成这些任务,告别繁琐的代码编写。
本教程将介绍如何在 .NET 10 项目中集成使用 Spire.Agent.Office 实现文档处理的 AI 化(本产品基于 .NET Standard 2.1 开发,兼容 .NET 5/6/7/8等多个平台,不限于.NET 10)。
Spire.Agent.Office 是基于 Spire.Office for .NET 传统 API 文档引擎之上构建的 AI 智能体,与传统的 Spire.Office for .NET 组件的核心区别在于:
| 传统 Spire.Office for .NET | Spire.Agent.Office | |
|---|---|---|
| 操作方式 | 手写代码(调用 API 接口、遍历文档数据、操作处理、保存结果) | 自然语言指令(如 "合同审查") |
| 使用门槛 | 需要了解详细的 API 和对象结构 | 只需描述需求,AI 自动执行 |
| 灵活性 | API 代码处理可能不适合所有文档 | 通用 AI 指令可以处理所有文档 |
自然语言指令 → Spire.Agent.Office AI 层 → Spire.Office 文档引擎 → 输出文件
Spire.Agent.Office 解析您的自然语言指令,将其转换为 Spire.Office 文档引擎的内部调用处理文档,最终生成预期文档,支持 Word、Excel、PowerPoint、PDF 等多种文档格式处理和转换。
| 优势 | 说明 |
|---|---|
| AI 原生体验 | 告别繁琐的 API 调用链,用自然语言直接实现文档处理 |
| 稳定可靠性 | 基于成熟的 Spire.Office 文档引擎构建,保证文档处理的效果 |
| 无缝集成 | 支持跨平台使用,轻松集成,可灵活对接业务逻辑,实现功能拓展需求 |
| 灵活 AI 模型支持 | 兼容主流 AI 基础设施,保证 AI 代码生成准确率 |
| 加速开发交付 | 缩短文档处理任务开发时间 |

NuGet 安装 Spire.Agent.Office后相应依赖会自动安装

从网站下载 Spire.Agent.Office解压至本地目录后导入项目

通过本地 Dll 添加,需要同时添加以下依赖,以保证更好的运行效果:
| 依赖包 | 最低版本 |
|---|---|
| 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 处理主要遵循以下模式:
.AI(options) 获取 AIDocumentProcessorAIDocumentProcessor.ExecuteInstruction(),返回 AIResultAIDocumentProcessor.GeneratePresentation(),返回 GenerationResultusing Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Pdf;
using Spire.Doc;
using Spire.Presentation;
using Spire.Xls;
// Excel 处理
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())
{
// 如果输入路径存在且文件可访问,则加载文档
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
workbook.LoadFromFile(inputPath);
}
// 否则使用空 Workbook
AIDocumentProcessor processor = workbook.AI(options);
return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
}
}
// Word 处理
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())
{
// 如果输入路径存在且文件可访问,则加载文档
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
doc.LoadFromFile(inputPath);
}
// 否则使用空 Document
AIDocumentProcessor processor = doc.AI(options);
return processor.ExecuteInstruction(doc, instruction, savePath, attachmentPaths);
}
}
// PDF 处理
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())
{
// 如果输入路径存在且文件可访问,则加载文档
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
pdf.LoadFromFile(inputPath);
}
// 否则使用空 PdfDocument
AIDocumentProcessor processor = pdf.AI(options);
return processor.ExecuteInstruction(pdf, instruction, savePath, attachmentPaths);
}
}
// PPT 生成
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);
}
}
// 基于现有 PPT 的处理
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())
{
// 如果输入路径存在且文件可访问,则加载文档
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
ppt.LoadFromFile(inputPath);
}
// 否则使用空 Presentation
AIDocumentProcessor processor = ppt.AI(options);
return processor.ExecuteInstruction(ppt, instruction, savePath, attachmentPaths);
}
}
// 写入日志
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();
// 判断执行状态:成功/失败/跳过
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)
{
// 记录执行耗时
logBuilder.AppendLine($" | Duration: {aiResult.Duration.TotalSeconds:F2}s");
// 记录 Token 使用统计
var tu = aiResult.TokenUsage;
if (tu != null)
{
logBuilder.Append($" | In: {tu.InputTokens:N0}"); // 输入 Token 数
logBuilder.Append($" | Out: {tu.OutputTokens:N0}"); // 输出 Token 数
logBuilder.Append($" | CacheR: {tu.CacheReadTokens:N0}"); // 缓存读取 Token 数
logBuilder.Append($" | CacheW: {tu.CacheWriteTokens:N0}"); // 缓存写入 Token 数
logBuilder.Append($" | CacheT: {tu.TotalCacheTokens:N0}"); // 缓存总 Token 数
logBuilder.Append($" | Total: {tu.TotalTokens:N0}"); // 总 Token 数
}
}
logBuilder.AppendLine();
File.AppendAllText(logFilePath, logBuilder.ToString());
}
如下面示例,以自然语言为交互方式,调用系统强大的文档处理能力,完成各类复杂的文档任务。
// 多个文档路径添加
string[] attachmentPaths = new string[] { };
// 针对 Word 处理
string inputPath = @"in.docx";
string savePath = @"out.pdf";
string key = "SpireToken key";
string instruction = "查找 '****' 进行高亮,结果保存到 PDF";
AIResult result = ExecuteDemoWord(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "word", @"log\");
// 针对 PPT 处理
string inputPath = @"in.pptx";
string savePath = @"out.pptx";
string key = "SpireToken key";
string instruction = "将 PPT 每页添加 notes 描述";
AIResult result = ExecuteDemoPPT(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "ppt", @"log\");
// PPT 生成
string inputPath = @"AI.md";
string savePath = @"out.pptx";
string key = "SpireToken key";
string instruction = "根据 AI.md 生成 PPT 文档";
PPTGenerationResult result = GeneratPPT(inputPath, instruction, savePath, key);
WriteLog(result, "ppt", @"log\");
// 针对 PDF 处理
string inputPath = @"in.pdf";
string savePath = @"out.md";
string key = "SpireToken key";
string instruction = "提取表格数据保存为标准的 markdown 格式";
AIResult result = ExecuteDemoPDF(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "pdf", @"log\");
// Excel 处理
string inputPath = @"in.xlsx";
string savePath = @"out.pdf";
string key = "SpireToken key";
string instruction = "将文档中空行删除";
AIResult result = ExecuteDemoXls(instruction, inputPath, savePath, key, attachmentPaths);
WriteLog(result, "xls", @"log\");
如果未配置 SpireToken Key,配置的 Key 不正确或者 Key 已失效,Spire.Agent.Office 会抛出异常,程序将中止执行。请先确保 SpireToken Key 的正确有效性。
ExecuteInstruction 返回的 AIResult 可能包含失败信息,需要检查 Success 属性。
AIResult result = processor.ExecuteInstruction(doc, instruction, outputPath);
if (result == null || !result.Success)
{
throw new InvalidOperationException(
$"AI instruction failed: {result?.ErrorMessage ?? "Unknown error"}");
}
如果针对已有文档处理,文件路径不正确会导致加载文档失败:
attachmentPaths 中Spire.Agent.Office 需要配置有效的 SpireToken Key 才能体验完整的功能:
在代码中配置:
AIOptions options = new AIOptions();
options.SpireToken = key;
在日常办公自动化场景中,经常需要从 Excel 报表中批量提取产品图片、替换过期 Logo,或对指定图片进行单独导出。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成这些图片操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
批量提取工作表中的所有图片,适用于备份报表中的嵌入图像、迁移产品资料等场景。实现流程分为三个步骤:遍历 Worksheet.Pictures 集合,对每张图片调用 Picture.Save 方法将其保存到 VFS,然后逐一读取并触发浏览器下载。
function App() {
const extractAllImages = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将 Excel 文件载入 VFS
const inputFileName = 'ReadImages.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 遍历工作表中的所有图片并逐个导出
for (let i = 0; i < sheet.Pictures.Count; i++) {
const pic = sheet.Pictures.get(i);
const outputFileName = `Image-${i + 1}.png`;
pic.Picture.Save(outputFileName);
// 从 VFS 读取导出的图片文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: "image/png" });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
}
// 释放资源
workbook.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>提取工作表中的所有图片</h1>
<button onClick={extractAllImages}>
提取全部图片
</button>
</div>
);
}
export default App;
从工作表中批量提取并下载的图片文件

提取工作表中的指定图片有两种常用方式:按索引直接获取,或按图片名称遍历匹配。索引方式适合已知图片位置(如第一张图片)的场景,名称方式则适合预先知道图片标识名的情况。实现流程分为两步:先通过索引或名称定位目标图片,再将其导出为本地文件。
function App() {
const extractImage = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将 Excel 文件载入 VFS
const inputFileName = 'ReadImages.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 方法一:按索引提取(例如提取第二张图片)
const pic = sheet.Pictures.get(1);
const outputFileName = 'ExtractByIndex.png';
// // 方法二:按图片名称遍历匹配
// let pic = null;
// const targetName = 'SpireXLS';
// for (let i = 0; i < sheet.Pictures.Count; i++) {
// if (sheet.Pictures.get(i).Name === targetName) {
// pic = sheet.Pictures.get(i);
// break;
// }
// }
// const outputFileName = 'ExtractByName.png';
// 将图片保存到 VFS 并触发下载
pic.Picture.Save(outputFileName);
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: "image/png" });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
workbook.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>提取指定图片</h1>
<button onClick={extractImage}>
提取图片
</button>
</div>
);
}
export default App;
通过索引或图片名称提取并下载的指定图片

替换工作表中的现有图片是更新报表 Logo、更换产品展示图等场景中的常见需求。实现思路是:先获取目标图片的位置与大小信息,然后通过 XlsShape.Convert 将此图片删除,最后在相同位置插入新图片,并将新图片的大小与偏移设置为与原图片一致。
function App() {
const replaceImage = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将 Excel 文件和新图片载入 VFS
const inputFileName = 'ReadImages.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
const newImageFile = 'Logo.png';
await window.spire.FetchFileToVFS(newImageFile, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 获取第一张图片及其位置、大小信息
const oldPic = sheet.Pictures.get(0);
const topRow = oldPic.TopRow;
const leftColumn = oldPic.LeftColumn;
const leftColumnOffset = oldPic.LeftColumnOffset;
const topRowOffset = oldPic.TopRowOffset;
const width = oldPic.Width;
const height = oldPic.Height;
// 删除原有图片
xlsModule.XlsShape.Convert(oldPic).Remove();
// 在同一位置插入新图片
let picture = sheet.Pictures.Add({ topRow: topRow, leftColumn: leftColumn, fileName: newImageFile });
// 设置新图片大小与偏移,与原图片保持一致
picture.Width = width;
picture.Height = height;
picture.LeftColumnOffset = leftColumnOffset;
picture.TopRowOffset = topRowOffset;
const outputFileName = 'ReplaceImage-out.xlsx';
// 保存修改后的工作簿
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// 释放资源
workbook.Dispose();
// 从 VFS 读取生成的文件,触发下载
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>替换工作表中的图片</h1>
<button onClick={replaceImage}>
替换图片
</button>
</div>
);
}
export default App;
替换图片后的 Excel 工作表效果

原因:图片保存时未指定正确的扩展名,或 MIME 类型与图片格式不匹配。
解决:确保 Picture.Save 方法中使用的文件名扩展名与图片实际格式一致。如果是 PNG 格式,文件扩展名应为 .png;如果是 JPEG 格式,则使用 .jpg。下载时 Blob 的 type 也需相应设置:
// PNG 格式
const blob = new Blob([fileArray], { type: "image/png" });
// JPEG 格式
const blob = new Blob([fileArray], { type: "image/jpeg" });
原因:删除原图片前未记录其位置和大小属性,导致新图片无法精确对齐到原始位置或保持原有大小。
解决:在删除前保存图片的 TopRow、LeftColumn、LeftColumnOffset、TopRowOffset 等位置属性以及 Width、Height 大小属性。插入新图片后,通过设置新图片的这些属性使其与原图片保持一致:
// 插入新图片(指定行列位置)
let picture = sheet.Pictures.Add({ topRow: topRow, leftColumn: leftColumn, fileName: newImageFile });
// 设置大小与偏移,与原图片保持一致
picture.Width = width;
picture.Height = height;
picture.LeftColumnOffset = leftColumnOffset;
picture.TopRowOffset = topRowOffset;
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
我们很高兴宣布发布 Spire.Presentation for .NET 11.8.2。本次更新主要修复了将 PPTX 转换为 PDF 和 SVG 时出现的问题。详情如下。
问题修复:
https://www.e-iceblue.cn/Downloads/Spire-Presentation-NET.html
Spire.PDF for Android via Java 10.8.5 现已正式发布。该版本新增支持使用 SHA-256/SHA-512 算法证书对 PDF 文档进行签名。详情如下。
新功能:
public static void main(String[] args) throws IOException {
// Create pdf document PdfDocument doc = new PdfDocument();
// Load file from disk doc.loadFromFile("Sample.pdf");
// Load the X509 certificate for signature PdfPKCS7Formatter formatter = new PdfPKCS7Formatter(new PdfCertificate("gary.pfx", "e-iceblue"), false);
// Create an instance of PdfOrdinarySignatureMaker using the loaded document and certificate PdfOrdinarySignatureMaker signatureMaker = new PdfOrdinarySignatureMaker(doc, formatter);
// Create an instance of PdfCustomSignatureAppearance as the appearance for the signature IPdfSignatureAppearance signatureAppearance = new PdfCustomSignatureAppearance();
// Make the signature with a specified name and the custom appearance signatureMaker.makeSignature("Signature", signatureAppearance);
// Iterate through all hash algorithm types for (HashAlgorithmType hashAlg : HashAlgorithmType.values()) {
// Skip SM3 (case-insensitive) if ("SM3".equalsIgnoreCase(hashAlg.name())) {
continue;
}
try {
// Set the current hash algorithm formatter.getProperties().setHashAlgorithm(hashAlg);
String filePath = "AddImageSignature_" + hashAlg.name() + ".pdf";
doc.saveToFile(filePath, FileFormat.PDF);
System.out.println("成功:" + hashAlg.name());
} catch (Exception ex) {
System.out.println("失败,报错的 HashAlgorithmType:" + hashAlg.name());
System.out.println("错误详情:" + ex.getMessage());
}
}
// Close the document doc.close();
}
// Custom signature appearance implementation public static class PdfCustomSignatureAppearance implements IPdfSignatureAppearance {
@Override
public void generate(PdfCanvas pdfCanvas) {
// Set font size int fontSize = 10;
// Create Arial font PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", Font.PLAIN, fontSize), true);
// Set line height float lineHeight = fontSize;
// Draw text string pdfCanvas.drawString("AAAAAAAAAAA", font, PdfBrushes.getRed(), new Point.Float(0, 0));
// Draw image at specified position pdfCanvas.drawImage(PdfImage.fromFile("E-iceblue logo.png"), new Point.Float(20, 0));
}
}
https://www.e-iceblue.cn/Downloads/pdf-for-android-via-java.html
对许多 Web 应用程序而言,文档处理能力直接关系到用户的工作效率,尤其在报告生成和数据整理等场景中。React 依托其基于组件的设计理念,为前端开发提供了理想的支撑。通过集成 Spire.PDF for JavaScript,您可以在 React 应用程序中轻松创建和管理 PDF 文档。
本指南将逐步介绍如何将 Spire.PDF for JavaScript 集成到您的 React 项目中,涵盖环境搭建和使用示例。
React 以组件化方式构建用户界面,是现代 Web 开发的主流选择。Spire.PDF for JavaScript 为 Web 应用提供开箱即用的 PDF 处理能力,两者的结合让您在浏览器中即可完成文档的创建、编辑与导出。
将 Spire.PDF for JavaScript 集成到 React 项目中,可以:
步骤 1. 安装 React 和 npm
从官方网站下载并安装 Node.js。请确保选择与您的操作系统相匹配的版本。
安装完成后,您可以在终端中运行以下命令来验证 Node.js 和 npm 是否正常工作:

步骤 2. 创建一个新的 React 项目
在终端中使用 Create React App 创建一个名为 my-app 的新 React 项目:
npx create-react-app my-app

如果您的 React 项目编译成功,应用程序将在 http://localhost:3000 上运行,您可以在浏览器中查看和测试您的应用程序。

要直观地浏览和管理项目中的文件,您可以使用 VS Code 打开该项目。

从我们的网站下载 Spire.PDF for JavaScript,并将其解压到磁盘上的某个位置。下载的产品包集成了 Spire.Doc for JavaScript、Spire.XLS for JavaScript、Spire.PDF for JavaScript 和 Spire.Presentation for JavaScript。要使用 Spire.PDF for JavaScript 的功能,您需要将相应的文件(spire.pdf.js、Spire.Pdf.Wasm.zip、spire.common.js、Spire.Common.Wasm.zip 以及 _framework 文件夹)复制到项目的 public 文件夹中。

您也可以使用 npm 进行安装。在 VS Code 的终端中运行以下命令:
npm i spire.office
安装完成后,产品包文件将保存在项目的 node_modules/spire.office 路径中。将上面提到的 5 个文件复制到 React 项目的 "public" 文件夹中。
为了确保文本正确渲染,您可以通过自定义路径添加相关的字体文件。在以下示例中,字体被添加到路径:public\。

修改 App.js 文件中的代码,使用 WebAssembly(WASM)模块生成 PDF 文件。文档的创建与导出操作由 Spire.PDF for JavaScript 库完成。

以下是完整代码:
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.PDF
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('加载 spire.pdf.js WASM 模块失败:', error);
}
})();
}, []);
// 生成 PDF 文件的函数
const createPdf = async () => {
const pdfModule = window.wasmModule?.spirepdf;
if (pdfModule) {
// 将 arial.ttf 字体文件加载到虚拟文件系统(VFS)中
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/`);
// 指定输出文件名
const outputFileName = 'HelloWorld.pdf';
// 创建一个新的 PDF 文档
const doc = new pdfModule.PdfDocument();
// 添加一页
let page = doc.Pages.Add();
// 创建字体和画刷
let font = new pdfModule.PdfTrueTypeFont({
fontFamily: 'Arial',
size: 12,
style: pdfModule.PdfFontStyle.Regular,
unicode:true
});
let brush = new pdfModule.PdfSolidBrush({pdfRGBColor: new pdfModule.PdfRGBColor({color: pdfModule.Color.get_Blue()})});
// 在页面的指定位置绘制文本
page.Canvas.DrawString({ s: "Hello World!", font: font, brush: brush, x: 20, y: 30 });
// 将文档保存为 PDF 文件
doc.SaveToFile({ fileName: outputFileName, fileFormat: pdfModule.FileFormat.PDF });
// 读取保存的文件并将其转换为 Blob 对象
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/pdf' });
// 为 Blob 创建 URL 并启动下载
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);
// 清理资源
doc.Close();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在 React 中使用 JavaScript 创建 PDF 文件</h1>
<button onClick={createPdf} disabled={!wasmModule}>
生成
</button>
</div>
);
}
export default App;
通过在 VS Code 的终端中输入以下命令来启动开发服务器:
npm start
React 应用程序编译成功后,它将在您的默认浏览器中打开,通常地址为 http://localhost:3000。点击"生成"按钮即可创建并下载 "HelloWorld.pdf" 文件。

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.Barcode 7.5.4 现已发布。该版本同步了 BarcodeSettings 枚举设置到 NETStandard 平台,并且还提升优化了条码识别准确度。详情请查阅以下内容。
新功能:
setting.BorderDashStyle = Spire.Barcode.Publics.Drawing.DashStyle.DashDotDot;
Spire.Barcode.Publics.Drawing.StringAlignment.Center;
问题修复:
Spire.PDF 12.8.0 现已正式发布。该版本成功修复了添加附件失败、PdfGrayConverter.ToGrayPdf() 效果不正确以及提取图片效果不正确的问题。更多详情如下。
问题修复:
Spire.Doc 14.8.0 现已发布。该版本增强了 Word 到 PDF 的转换功能,并修复了获取段落布局元素时抛出“NullReferenceException”异常的问题。详情如下。
问题修复: