Spire.Office for Python 11.7.0 已正式发布。该版本带来了多项强大功能提升:Spire.Doc 支持通过环境变量配置许可证;Spire.XLS 新增数据模拟分析、切片器及 Excel 转 JSON 支持;Spire.PDF 支持签名域中文本自动适配;Spire.Presentation 支持 License 环境变量配置。
除了这些新功能外,本版本还修复了大量与 Word、Excel、PDF 和 PowerPoint 文件的转换、处理及保存相关的已知问题,提供了更加稳定可靠的使用体验。更多详细信息请见下文。
https://www.e-iceblue.cn/Downloads/Spire-Office-Python.html
新功能:
SPIRE_OFFICE_LICENSE_KEY
SPIRE_DOC_LICENSE_KEY
SPIRE_LICENSE_KEY
新功能:
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
currentChangePercentage_Values = [0.23, 0.8, 1.1, 0.5, 0.35, 0.2]
increasedChangePercentage_Values = [0.45, 0.56, 0.9, 0.5, 0.58, 0.43]
decreasedChangePercentage_Values = [0.3, 0.2, 0.5, 0.3, 0.5, 0.23]
currentQuantity_Values = [1500, 3000, 5000, 4000, 500, 4000]
increasedQuantity_Values = [1000, 5000, 4500, 3900, 10000, 8900]
decreasedQuantity_Values = [1000, 2000, 3000, 3000, 300, 4000]
scenarios.Add("Current % of Change", worksheet.Range["F5:F10"], currentChangePercentage_Values)
scenarios.Add("Increased % of Change", worksheet.Range["F5:F10"], increasedChangePercentage_Values)
scenarios.Add("Decreased % of Change", worksheet.Range["F5:F10"], decreasedChangePercentage_Values)
scenarios.Add("Current Quantity", worksheet.Range["D5:D10"], currentQuantity_Values)
scenarios.Add("Increased Quantity", worksheet.Range["D5:D10"], increasedQuantity_Values)
scenarios.Add("Decreased Quantity", worksheet.Range["D5:D10"], decreasedQuantity_Values)
wb.SaveToFile(outputFile, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
currentChangePercentage_Values = [0.23, 0.8, 1.1, 0.5, 0.35, 0.2]
increasedChangePercentage_Values = [0.45, 0.56, 0.9, 0.5, 0.58, 0.43]
decreasedChangePercentage_Values = [0.3, 0.2, 0.5, 0.3, 0.5, 0.23]
currentQuantity_Values = [1500, 3000, 5000, 4000, 500, 4000]
increasedQuantity_Values = [1000, 5000, 4500, 3900, 10000, 8900]
decreasedQuantity_Values = [1000, 2000, 3000, 3000, 300, 4000]
scenarios.Add("Current % of Change", worksheet.Range["F5:F10"], currentChangePercentage_Values)
scenarios.Add("Increased % of Change", worksheet.Range["F5:F10"], increasedChangePercentage_Values)
scenarios.Add("Decreased % of Change", worksheet.Range["F5:F10"], decreasedChangePercentage_Values)
scenarios.Add("Current Quantity", worksheet.Range["D5:D10"], currentQuantity_Values)
scenarios.Add("Increased Quantity", worksheet.Range["D5:D10"], increasedQuantity_Values)
scenarios.Add("Decreased Quantity", worksheet.Range["D5:D10"], decreasedQuantity_Values)
worksheet.Scenarios.Summary(worksheet.Range["L7"])
wb.SaveToFile(outputFile, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
scenario1 = scenarios[0]
scenario2 = scenarios[1]
scenario1.SetVariableCells(worksheet.Range["A1:A5"], scenario2.Values)
sourceCell = worksheet.Range["B1:B5"]
scenario2.SetVariableCells(sourceCell, scenario2.Values)
scenario1.Show()
scenario2.Show()
self.get_content(scenario1, outputFile_TXT)
wb.SaveToFile(outputFile, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
scenarios.RemoveScenarioAt(0)
scenarios.RemoveScenarioByName("two")
content = ""
content += "Count:" + str(scenarios.Count) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("two")) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("one")) + "\n"
with open(outputFile, 'w') as f:
f.write(content)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
scenarios = worksheet.Scenarios
scenarios.RemoveScenarioAt(0)
scenarios.RemoveScenarioByName("two")
content = ""
content += "Count:" + str(scenarios.Count) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("two")) + "\n"
content += "ContainsScenario:" + str(scenarios.ContainsScenario("one")) + "\n"
with open(outputFile, 'w') as f:
f.write(content)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
slicers = worksheet.Slicers
table = worksheet.ListObjects.Create("Super Table", worksheet.Range["A1:C9"])
count = 3
for type in SlicerStyleType.__dict__.values():
if isinstance(type, SlicerStyleType):
count += 5
rangeStr = "E" + str(count)
index = slicers.Add(table, rangeStr, 0)
xlsSlicer = slicers[index]
xlsSlicer.Name = "slicers_" + str(count)
xlsSlicer.StyleType = type
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
pt = sheet.PivotTables[0]
slicers = worksheet.Slicers
index = slicers.Add(pt, "E12", 0)
xlsSlicer = slicers[index]
xlsSlicer.Name = "test_xlsSlicer"
xlsSlicer.Width = 100
xlsSlicer.Height = 120
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleLight2
xlsSlicer.PositionLocked = True
slicerCache = xlsSlicer.SlicerCache
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData
slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems
xlsSlicerCacheItem = slicerCacheItems[0]
xlsSlicerCacheItem.Selected = False
slicers_2 = worksheet.Slicers
r1 = pt.PivotFields["year"]
index_2 = slicers_2.Add(pt, "I12", r1)
xlsSlicer_2 = slicers[index_2]
xlsSlicer_2.RowHeight = 40
xlsSlicer_2.StyleType = SlicerStyleType.SlicerStyleLight3
xlsSlicer_2.PositionLocked = False
slicerCache_2 = xlsSlicer_2.SlicerCache
slicerCache_2.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithDataAtTop
slicerCacheItems_2 = xlsSlicer_2.SlicerCache.SlicerCacheItems
xlsSlicerCacheItem_2 = slicerCacheItems_2[1]
xlsSlicerCacheItem_2.Selected = False
pt.CalculateData()
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb.Dispose()
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet_1 = wb.Worksheets[0]
slicers = worksheet_1.Slicers
slicers.RemoveAt(0)
slicer = worksheet_1.Slicers[1]
worksheet_1.Slicers.Remove(slicer)
worksheet_2 = wb.Worksheets[2]
worksheet_2.Slicers.Clear()
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
slicers = worksheet.Slicers
xlsSlicer = slicers[0]
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleDark4
xlsSlicer.Caption = "Slicer"
xlsSlicer.PositionLocked = True
slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems
xlsSlicerCacheItem = slicerCacheItems[0]
xlsSlicerCacheItem.Selected = False
displayValue = xlsSlicerCacheItem.DisplayValue
slicerCache = xlsSlicer.SlicerCache
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData
wb.SaveToFile(outputFile_xlsx, ExcelVersion.Version2013)
wb = Workbook()
wb.LoadFromFile(inputFile)
worksheet = wb.Worksheets[0]
slicers = worksheet.Slicers
content = ""
content += "slicers.Count:" + str(slicers.Count) + "\n"
xlsSlicer = slicers[1]
content += "xlsSlicer.Name:" + xlsSlicer.Name + "\n"
content += "xlsSlicer.Caption:" + xlsSlicer.Caption + "\n"
content += "xlsSlicer.NumberOfColumns:" + str(xlsSlicer.NumberOfColumns) + "\n"
content += "xlsSlicer.ColumnWidth:" + str(xlsSlicer.ColumnWidth) + "\n"
content += "xlsSlicer.RowHeight:" + str(xlsSlicer.RowHeight) + "\n"
content += "xlsSlicer.ShowCaption:" + str(xlsSlicer.ShowCaption) + "\n"
content += "xlsSlicer.PositionLocked:" + str(xlsSlicer.PositionLocked) + "\n"
content += "xlsSlicer.Width:" + str(xlsSlicer.Width) + "\n"
content += "xlsSlicer.Height:" + str(xlsSlicer.Height) + "\n"
slicerCache = xlsSlicer.SlicerCache
content += "slicerCache.SourceName:" + slicerCache.SourceName + "\n"
content += "slicerCache.IsTabular:" + str(slicerCache.IsTabular) + "\n"
content += "slicerCache.Name:" + slicerCache.Name + "\n"
slicerCacheItems = slicerCache.SlicerCacheItems
xlsSlicerCacheItem = slicerCacheItems[1]
content += "xlsSlicerCacheItem.Selected:" + str(xlsSlicerCacheItem.Selected) + "\n"
with open(outputFile_T, 'w') as f:
f.write(content)
wb.Dispose()
workbook = Workbook()
workbook.LoadFromFile(inputFile)
workbook.SaveToFile(outputFile, FileFormat.Json)
workbook.Dispose()
新功能:
SPIRE_OFFICE_LICENSE_KEY
SPIRE_PPT_LICENSE_KEY
SPIRE_LICENSE_KEY
优化:
问题修复:
新功能:
# 初始化 PDF 文档对象
doc = PdfDocument()
# 加载需要签名的 PDF 文件
doc.LoadFromFile(inputFile)
# 指定 PFX 证书文件的密码
pfxPassword = "e-iceblue"
# 获取文档的第一页
page = doc.Pages.get_Item(0)
# 使用证书文件创建普通签名制作器
signatureMaker = PdfOrdinarySignatureMaker(doc, inputFile_pfx, pfxPassword)
# 设置签名验证层(False 表示显示有效性符号)
signatureMaker.SetAcro6Layers(False)
# 获取签名对象并配置签署人的基本信息
signature = signatureMaker.Signature
signature.Name = "Gary" # 签署人姓名
signature.ContactInfo = "028-81705109" # 联系方式
signature.Location = "Chengdu" # 签署地点
signature.Reason = "The certificate of this document" # 签署原因
# 创建自定义签名外观对象
appearance = PdfSignatureAppearance(signature)
appearance.NameLabel = "Signer: " # 姓名标签
appearance.ContactInfoLabel = "ContactInfo: " # 联系方式标签
appearance.LocationLabel = "Location: " # 地点标签
appearance.ReasonLabel = "Reaseon: " # 原因标签(保留原文拼写)
appearance.SignatureImage = PdfImage.FromFile(inputFile_image) # 加载签名图片
appearance.GraphicMode = GraphicMode.SignImageAndSignDetail # 同时显示签名图片和详细信息
signature.DocumentPermissions = PdfCertificationFlags.ForbidChanges # 禁止更改文档
appearance.SignImageLayout = SignImageLayout.Stretch # 签名图片拉伸布局
appearance.AutoFontSize = True # 启用自动调整字体大小
# 在页面指定位置生成并应用签名(参数顺序:签名字段名、页对象、X坐标、Y坐标、宽度、高度、外观对象)
signatureMaker.MakeSignature("signName", page, 54.0, page.Size.Height - 300.0, 40.0, 40.0, appearance)
# 保存已签名的 PDF 文档
doc.SaveToFile(outputFile)
# 关闭文档并释放资源
doc.Close()
问题修复:
Spire.Office for C++ 11.7.0 现已发布。在该版本中,Spire.Doc for C++ 支持转换 Word 到 Excel;Spire.PDF for C++ 增强了从 XPS 到 PDF 的转换功能;Spire.Presentation for C++ 增强 PowerPoint 到 PDF 转换功能。此外,该版本还修复了许多已知问题。详情如下。
https://www.e-iceblue.cn/Downloads/Spire-Office-CPP.html
新功能:
intrusive_ptr<Document> doc = new Document();
doc->LoadFromFile(inputFile.c_str());
doc->SaveToFile(outputFile.c_str(), FileFormat::XLSX);
doc->Close();
问题修复:
问题修复:
问题修复:
我们很高兴地宣布 Spire.PDF for Java 12.8.1 版本正式发布。本次更新主要修复了 PDF 转 Word 和 Markdown 过程中出现的问题,同时解决了一个与数字签名相关的缺陷。详细内容如下。
问题修复:
配置页面设置对于准备打印或导出为PDF的Excel文档至关重要。Spire.XLS for JavaScript 通过WebAssembly完全在浏览器中运行,使用虚拟文件系统(VFS)管理输入和输出文件——无需后端服务器。它通过 PageSetup 对象提供全面的页面设置功能,使您能够控制页边距、方向、纸张大小、打印区域、缩放比例和适应页面选项。
Spire.XLS中的 PageSetup 对象提供了丰富的属性,用于控制工作表的打印或显示方式。关键属性包括:
| 属性 | 描述 |
|---|---|
| TopMargin / BottomMargin / LeftMargin / RightMargin | 设置页面边距 |
| Orientation | 设置页面方向(纵向或横向) |
| PaperSize | 设置纸张大小(A4、Letter等) |
| PrintArea | 指定要打印的单元格区域 |
| Zoom | 设置工作表缩放百分比 |
| FitToPagesTall / FitToPagesWide | 将工作表缩放以适应指定的页数 |
本文涵盖六个核心功能:
有关安装和项目设置,请参阅React 项目中集成 Spire.XLS for JavaScript。以下示例假定Spire.XLS已安装且WebAssembly模块已初始化。
页边距定义了打印工作表边缘周围的空白区域。操作步骤如下:
new xlsModule.Workbook() 创建 Workbook 对象。workbook.Worksheets.get(index) 方法获取默认工作表。sheet.PageSetup 访问 PageSetup 对象。pageSetup.TopMargin、pageSetup.BottomMargin、pageSetup.LeftMargin 和 pageSetup.RightMargin 属性设置页边距。workbook.SaveToFile() 方法将工作簿保存为 Excel 文件。以下是在React中调整页边距的完整代码示例:
function App() {
const adjustPageMargins = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建工作簿并加载已有文件
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: 'Sample.xlsx' });
const sheet = workbook.Worksheets.get(0);
// 获取 PageSetup 对象
const pageSetup = sheet.PageSetup;
// 设置工作表的上、下、左、右、页眉、页脚页边距
pageSetup.TopMargin = 1;
pageSetup.BottomMargin = 1;
pageSetup.LeftMargin = 0.75;
pageSetup.RightMargin = 0.75;
// 保存工作簿
const outputFileName = 'AdjustMargins.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>Adjust Page Margins</h1>
<button onClick={adjustPageMargins}>
Generate
</button>
</div>
);
}
export default App;
使用Spire.XLS for JavaScript调整页边距

页面方向决定了工作表是以纵向(垂直)还是横向(水平)布局打印。横向布局尤其适用于包含多列的宽表格。操作步骤如下:
new xlsModule.Workbook() 创建 Workbook 对象。workbook.Worksheets.get(index) 方法获取默认工作表。sheet.PageSetup 访问 PageSetup 对象。pageSetup.Orientation 属性设置页面方向。workbook.SaveToFile() 方法将工作簿保存为 Excel 文件。以下是在React中将页面方向设置为横向的完整代码示例:
function App() {
const setPageOrientation = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建工作簿并加载已有文件
// 将示例文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: 'Sample.xlsx' });
const sheet = workbook.Worksheets.get(0);
// 将页面方向设置为横向
sheet.PageSetup.Orientation = xlsModule.PageOrientationType.Landscape;
// 保存工作簿
const outputFileName = 'SetOrientation.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>Set Page Orientation</h1>
<button onClick={setPageOrientation}>
Generate
</button>
</div>
);
}
export default App;
使用Spire.XLS for JavaScript将页面方向设置为横向

不同的打印机和地区使用不同的标准纸张大小。Spire.XLS for JavaScript通过 PaperSizeType 枚举支持多种纸张大小,包括A4、Letter、A3等。操作步骤如下:
new xlsModule.Workbook() 创建 Workbook 对象。workbook.Worksheets.get(index) 方法获取默认工作表。sheet.PageSetup 访问 PageSetup 对象。pageSetup.PaperSize 属性设置纸张大小。workbook.SaveToFile() 方法将工作簿保存为 Excel 文件。以下是在React中将纸张大小设置为A3的完整代码示例:
function App() {
const setPaperSize = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建工作簿并加载已有文件
// 将示例文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: 'Sample.xlsx' });
const sheet = workbook.Worksheets.get(0);
// 获取 PageSetup 对象
const pageSetup = sheet.PageSetup;
// 将纸张大小设置为 A3
pageSetup.PaperSize = xlsModule.PaperSizeType.PaperA3;
// 保存工作簿
const outputFileName = 'SetPaperSize.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>Set Paper Size</h1>
<button onClick={setPaperSize}>
Generate
</button>
</div>
);
}
export default App;
使用Spire.XLS for JavaScript将纸张大小设置为A3

打印区域定义了工作表中将被打印的部分。操作步骤如下:
new xlsModule.Workbook() 创建 Workbook 对象。workbook.Worksheets.get(index) 方法获取默认工作表。sheet.Range 属性填入示例数据。sheet.PageSetup 访问 PageSetup 对象。pageSetup.PrintArea 属性设置打印区域。workbook.SaveToFile() 方法将工作簿保存为 Excel 文件。以下是在React中设置打印区域的完整代码示例:
function App() {
const setPrintArea = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建工作簿并加载已有文件
// 将示例文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: 'Sample.xlsx' });
const sheet = workbook.Worksheets.get(0);
// 将打印区域设置为 A1:E3
sheet.PageSetup.PrintArea = "A1:E3";
// 保存工作簿
const outputFileName = 'SetPrintArea.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>Set Print Area</h1>
<button onClick={setPrintArea}>
Generate
</button>
</div>
);
}
export default App;
使用Spire.XLS for JavaScript设置打印区域

缩放比例控制工作表在屏幕上显示的放大级别。取值范围为10到400,表示正常大小的百分比。操作步骤如下:
new xlsModule.Workbook() 创建 Workbook 对象。workbook.Worksheets.get(index) 方法获取默认工作表。sheet.Zoom 属性设置缩放比例。workbook.SaveToFile() 方法将工作簿保存为 Excel 文件。以下是在React中设置缩放比例的完整代码示例:
function App() {
const setZoomScale = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建工作簿并加载已有文件
// 将示例文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: 'Sample.xlsx' });
const sheet = workbook.Worksheets.get(0);
// 将缩放比例设置为 85%
const pageSetup = sheet.PageSetup;
pageSetup.Zoom=85;
// 保存工作簿
const outputFileName = 'SetZoomScale.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>Set Zoom Scale</h1>
<button onClick={setZoomScale}>
Generate
</button>
</div>
);
}
export default App;
使用Spire.XLS for JavaScript将缩放比例设置为85%

当打印大型工作表时,内容可能会跨越多页,导致阅读困难。操作步骤如下:
new xlsModule.Workbook() 创建 Workbook 对象。workbook.Worksheets.get(index) 方法获取默认工作表。sheet.Range 属性填入大量数据。sheet.PageSetup 访问 PageSetup 对象。pageSetup.FitToPagesTall 和 pageSetup.FitToPagesWide 属性设置页面缩放。workbook.SaveToFile() 方法将工作簿保存为 Excel 文件。以下是在React中将工作表适配到一页的完整代码示例:
function App() {
const fitToPage = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建工作簿并加载已有文件
// 将示例文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: 'Sample.xlsx' });
const sheet = workbook.Worksheets.get(0);
// 将工作表内容缩放至一页
const pageSetup = sheet.PageSetup;
pageSetup.FitToPagesTall = 1;
pageSetup.FitToPagesWide = 1;
// 保存工作簿
const outputFileName = 'FitToPage.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>Fit Worksheet to 1 Page</h1>
<button onClick={fitToPage}>
Generate
</button>
</div>
);
}
export default App;
使用Spire.XLS for JavaScript将工作表缩放至一页

原因:默认情况下,打印工作表时不显示网格线以及行号和列标,影响数据可读性。
解决方案:使用 PageSetup 对象的 IsPrintGridlines 和 IsPrintHeadings 属性:
pageSetup.IsPrintGridlines = true;
pageSetup.IsPrintHeadings = true;
原因:需要了解当前页面设置的纸张实际宽高,以便调整内容布局。
解决方案:通过 PageSetup 对象的 PageWidth 和 PageHeight 属性获取:
var pageWidth = pageSetup.PageWidth;
var pageHeight = pageSetup.PageHeight;
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
在 Excel 文件中添加图表是 Web 应用中常见的数据可视化需求。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成图表创建,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。它支持创建多种图表类型,包括柱状图、饼状图、环形图、折线图、散点图等。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
柱状图是最常用的图表类型之一,用于比较不同类别之间的数据值。使用 Spire.XLS for JavaScript,您可以先在工作表中填充数据,然后添加图表对象,将图表类型设置为 ColumnClustered,并配置图表标题、坐标轴和数据标签来创建簇状柱形图。具体操作步骤如下:
Workbook 对象并获取默认工作表。sheet.Charts.Add() 添加图表。DataRange 数据区域,将图表类型指定为ExcelChartType.ColumnClustered。SaveToFile() 保存工作簿为 Excel 文件。下面是一个完整的代码示例,展示了在 React 中创建簇状柱形图:
function App() {
const createColumnChart = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建新工作簿并获取默认工作表
const workbook = new xlsModule.Workbook();
const sheet = workbook.Worksheets.get(0);
sheet.Name = "ClusteredColumn";
// 填入图表数据
sheet.Range.get("A1").Value = "Country";
sheet.Range.get("A2").Value = "Cuba";
sheet.Range.get("A3").Value = "Mexico";
sheet.Range.get("A4").Value = "France";
sheet.Range.get("A5").Value = "German";
sheet.Range.get("B1").Value = "Jun";
sheet.Range.get("B2").NumberValue = 6000;
sheet.Range.get("B3").NumberValue = 8000;
sheet.Range.get("B4").NumberValue = 9000;
sheet.Range.get("B5").NumberValue = 8500;
sheet.Range.get("C1").Value = "Aug";
sheet.Range.get("C2").NumberValue = 3000;
sheet.Range.get("C3").NumberValue = 2000;
sheet.Range.get("C4").NumberValue = 2300;
sheet.Range.get("C5").NumberValue = 4200;
// 添加图表并设置数据区域
const chart = sheet.Charts.Add();
chart.DataRange = sheet.Range.get("A1:C5");
chart.SeriesDataFromRange = false;
// 设置图表位置
chart.LeftColumn = 1;
chart.TopRow = 6;
chart.RightColumn = 11;
chart.BottomRow = 29;
// 设置图表类型为簇状柱形图
chart.ChartType = xlsModule.ExcelChartType.ColumnClustered;
// 配置图表标题
chart.ChartTitle = "Sales market by country";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
// 配置坐标轴标题
chart.PrimaryCategoryAxis.Title = "Country";
chart.PrimaryCategoryAxis.Font.IsBold = true;
chart.PrimaryCategoryAxis.TitleArea.IsBold = true;
chart.PrimaryValueAxis.Title = "Sales(in Dollars)";
chart.PrimaryValueAxis.HasMajorGridLines = false;
chart.PrimaryValueAxis.MinValue = 1000;
chart.PrimaryValueAxis.TitleArea.IsBold = true;
chart.PrimaryValueAxis.TitleArea.TextRotationAngle = 90;
// 配置数据标签:在每个数据点上显示数值
for (let i = 0; i < chart.Series.Length; i++) {
let cs = chart.Series.get(i);
cs.Format.Options.IsVaryColor = true;
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = true;
}
// 设置图例位置
chart.Legend.Position = xlsModule.LegendPositionType.Top;
// 保存工作簿
const outputFileName = 'ClusteredColumn.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 Clustered Column Chart</h1>
<button onClick={createColumnChart}>
Generate
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 创建的簇状柱形图

饼状图非常适合展示数据在各类别之间的比例分布。使用 Spire.XLS for JavaScript,您可以在添加图表时指定图表类型为 Pie,然后绑定分类标签和数据值来创建饼图。具体操作步骤如下:
Workbook 对象并获取默认工作表。sheet.Charts.Add() 添加类型为 ExcelChartType.Pie 的图表。SaveToFile() 保存工作簿为 Excel 文件。下面是一个完整的代码示例,展示了在 React 中创建饼状图:
function App() {
const createPieChart = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建新工作簿并获取默认工作表
const workbook = new xlsModule.Workbook();
let sheet = workbook.Worksheets.get(0);
sheet.Name = "Pie Chart";
// 填入图表数据
sheet.Range.get("A1").Value = "Year";
sheet.Range.get("A2").Value = "2002";
sheet.Range.get("A3").Value = "2003";
sheet.Range.get("A4").Value = "2004";
sheet.Range.get("A5").Value = "2005";
sheet.Range.get("B1").Value = "Sales";
sheet.Range.get("B2").NumberValue = 4000;
sheet.Range.get("B3").NumberValue = 6000;
sheet.Range.get("B4").NumberValue = 7000;
sheet.Range.get("B5").NumberValue = 8500;
// 添加饼图
let chart = sheet.Charts.Add({ chartType: xlsModule.ExcelChartType.Pie });
chart.DataRange = sheet.Range.get("B2:B5");
chart.SeriesDataFromRange = false;
// 设置图表位置
chart.LeftColumn = 1;
chart.TopRow = 6;
chart.RightColumn = 9;
chart.BottomRow = 25;
// 配置图表标题
chart.ChartTitle = "Sales by year";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
// 绑定分类标签和数值
let cs = chart.Series.get(0);
cs.CategoryLabels = sheet.Range.get("A2:A5");
cs.Values = sheet.Range.get("B2:B5");
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = true; // 显示数值标签
chart.PlotArea.Fill.Visible = false;
// 保存工作簿
const outputFileName = 'Pie.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 Pie Chart</h1>
<button onClick={createPieChart}>
Generate
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 创建的饼状图

环形图与饼图类似,但中间为空心,可以显示多个数据系列。使用 Spire.XLS for JavaScript,您可以将图表类型设置为 Doughnut,并配置百分比数据标签来创建环形图。具体操作步骤如下:
Workbook 对象并获取默认工作表。ChartType 设置为 ExcelChartType.Doughnut。SaveToFile() 保存工作簿为 Excel 文件。下面是一个完整的代码示例,展示了在 React 中创建环形图:
function App() {
const createDoughnutChart = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 创建新工作簿并获取默认工作表
const workbook = new xlsModule.Workbook();
let sheet = workbook.Worksheets.get(0);
// 填入图表数据
sheet.Range.get("A1").Value = "Country";
sheet.Range.get("A1").Style.Font.IsBold = true;
sheet.Range.get("A2").Value = "Cuba";
sheet.Range.get("A3").Value = "Mexico";
sheet.Range.get("A4").Value = "France";
sheet.Range.get("A5").Value = "German";
sheet.Range.get("B1").Value = "Sales";
sheet.Range.get("B1").Style.Font.IsBold = true;
sheet.Range.get("B2").NumberValue = 6000;
sheet.Range.get("B3").NumberValue = 8000;
sheet.Range.get("B4").NumberValue = 9000;
sheet.Range.get("B5").NumberValue = 8500;
// 添加环形图
let chart = sheet.Charts.Add();
chart.ChartType = xlsModule.ExcelChartType.Doughnut;
chart.DataRange = sheet.Range.get("A1:B5");
chart.SeriesDataFromRange = false;
// 设置图表位置
chart.LeftColumn = 4;
chart.TopRow = 2;
chart.RightColumn = 12;
chart.BottomRow = 22;
// 配置图表标题
chart.ChartTitle = "Market share by country";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
// 显示百分比数据标签
for (let i = 0; i < chart.Series.Count; i++) {
chart.Series.get(i).DataPoints.DefaultDataPoint.DataLabels.HasPercentage = true;
}
// 设置图例位置
chart.Legend.Position = xlsModule.LegendPositionType.Top;
// 保存工作簿
const outputFileName = 'CreateDoughnutChart.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 Doughnut Chart</h1>
<button onClick={createDoughnutChart}>
Generate
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 创建的环形图

上文中介绍了柱状图、饼状图和环形图的创建方法。除此之外,Spire.XLS 组件还支持 Excel 自带的各种图表类型,这些图表类型被定义在枚举 Spire.Xls.ExcelChartType 中,完整的 81 种图表类型如下:
| 图表类型 | 描述 |
|---|---|
| 1. ColumnClustered | 表示簇状柱形图 |
| 2. ColumnStacked | 表示堆积柱形图 |
| 3. Column100PercentStacked | 表示百分比堆积柱形图 |
| 4. Column3DClustered | 表示三维簇状柱形图 |
| 5. Column3DStacked | 表示三维堆积柱形图 |
| 6. Column3D100PercentStacked | 表示三维百分比堆积柱形图 |
| 7. Column3D | 表示三维柱形图 |
| 8. BarClustered | 表示簇状条形图 |
| 9. BarStacked | 表示堆积条形图 |
| 10. Bar100PercentStacked | 表示百分比堆积条形图 |
| 11. Bar3DClustered | 表示三维簇状条形图 |
| 12. Bar3DStacked | 表示三维堆积条形图 |
| 13. Bar3D100PercentStacked | 表示三维百分比堆积条形图 |
| 14. Line | 表示折线图 |
| 15. LineStacked | 表示堆积折线图 |
| 16. Line100PercentStacked | 表示百分比堆积折线图 |
| 17. LineMarkers | 表示数据点折线图 |
| 18. LineMarkersStacked | 表示堆积数据点折线图 |
| 19. LineMarkers100PercentStacked | 表示百分比堆积数据点折线图 |
| 20. Line3D | 表示三维折线图 |
| 21. Pie | 表示饼图 |
| 22. Pie3D = 21 | 表示三维饼图 |
| 23. PieOfPie | 表示复合饼图 |
| 24. PieExploded | 表示分离型饼图 |
| 25. Pie3DExploded | 表示三维分离型饼图 |
| 26. PieBar | 表示条形饼图 |
| 27. ScatterMarkers | 表示散点图 |
| 28. ScatterSmoothedLineMarkers | 表示平滑线散点图 |
| 29. ScatterSmoothedLine | 表示平滑线散点图 |
| 30. ScatterLineMarkers | 表示折线散点图 |
| 31. ScatterLine | 表示折线散点图 |
| 32. Area | 表示面积图 |
| 33. AreaStacked | 表示堆积面积图 |
| 34. Area100PercentStacked | 表示百分比堆积面积图 |
| 35. Area3D | 表示三维面积图 |
| 36. Area3DStacked | 表示三维堆积面积图 |
| 37. Area3D100PercentStacked | 表示三维百分比堆积面积图 |
| 38. Doughnut | 表示圆环图 |
| 39. DoughnutExploded | 表示分离型圆环图 |
| 40. Radar | 表示雷达图 |
| 41. RadarMarkers | 表示数据点雷达图 |
| 42. RadarFilled | 表示填充雷达图 |
| 43. Surface3D | 表示三维曲面图 |
| 44. Surface3DNoColor | 表示三维曲面图(无色) |
| 45. SurfaceContour | 表示等高线图 |
| 46. SurfaceContourNoColor | 表示等高线图(无色) |
| 47. Bubble | 表示气泡图 |
| 48. Bubble3D | 表示三维气泡图 |
| 49. StockHighLowClose | 表示盘高-盘低-收盘图 |
| 50. StockOpenHighLowClose | 表示开盘-盘高-盘低-收盘图 |
| 51. StockVolumeHighLowClose | 表示成交量-盘高-盘低-收盘图 |
| 52. StockVolumeOpenHighLowClose | 表示成交量-开盘-盘高-盘低-收盘图 |
| 53. CylinderClustered | 表示簇状圆柱图 |
| 54. CylinderStacked | 表示堆积圆柱图 |
| 55. Cylinder100PercentStacked | 表示百分比堆积圆柱图 |
| 56. CylinderBarClustered | 表示簇状条形圆柱图 |
| 57. CylinderBarStacked | 表示堆积条形圆柱图 |
| 58. CylinderBar100PercentStacked | 表示百分比堆积条形圆柱图 |
| 59. Cylinder3DClustered | 表示三维簇状圆柱图 |
| 60. ConeClustered | 表示簇状圆锥图 |
| 61. ConeStacked | 表示堆积圆锥图 |
| 62. Cone100PercentStacked | 表示百分比堆积圆锥图 |
| 63. ConeBarClustered | 表示簇状条形圆锥图 |
| 64. ConeBarStacked | 表示堆积条形圆锥图 |
| 65. ConeBar100PercentStacked | 表示百分比堆积条形圆锥图 |
| 66. Cone3DClustered | 表示三维簇状圆锥图 |
| 67. PyramidClustered | 表示簇状棱锥图 |
| 68. PyramidStacked | 表示堆积棱锥图 |
| 69. Pyramid100PercentStacked | 表示百分比堆积棱锥图 |
| 70. PyramidBarClustered | 表示簇状条形棱锥图 |
| 71. PyramidBarStacked | 表示堆积条形棱锥图 |
| 72. PyramidBar100PercentStacked | 表示百分比堆积条形棱锥图 |
| 73. Pyramid3DClustered | 表示三维簇状棱锥图 |
| 74. CombinationChart | 表示组合图 |
| 75. Funnel | 表示漏斗图 |
| 76. WaterFall | 表示瀑布图 |
| 77. BoxAndWhisker | 表示盒须图 |
| 78. Histogram | 表示直方图 |
| 79. Pareto | 表示帕累托图 |
| 80. TreeMap | 表示树状图 |
| 81. SunBurst | 表示旭日图 |
解决:根据需求选择对应的标签属性:
// 显示数值标签
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = true;
// 或显示百分比标签
cs.DataPoints.DefaultDataPoint.DataLabels.HasPercentage = true;
原因:图表区域过小,无法完整容纳所有图例项,或图例位置设置导致与图表数据区域重叠。
解决:增加图表的垂直范围,或调整图例位置:
// 增加图表高度
chart.BottomRow = 35;
// 或调整图例位置
chart.Legend.Position = xlsModule.LegendPositionType.Bottom;
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
数字签名是确保 Excel 文件来源可信、内容未被篡改的重要手段。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成数字签名检测与删除操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
在处理已签名的 Excel 文件前,先检测其签名状态可以避免误操作。Spire.XLS 通过 IsDigitallySigned 属性判断工作簿是否包含数字签名:首先通过 FetchFileToVFS 将字体文件和目标 Excel 文件载入 WASM 虚拟文件系统;然后实例化 Workbook 加载文件;最后通过 IsDigitallySigned 属性获取签名状态。
下面是一个完整的代码示例,展示了检测 Excel 文件是否包含数字签名:
function App() {
const detectDigitalSignature = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体和 Excel 文件载入 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/`);
// 加载工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 检测是否包含数字签名
const isSigned = workbook.IsDigitallySigned;
// 释放资源
workbook.Dispose();
// 弹出检测结果
alert(isSigned ? '文件已签名' : '文件未签名');
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Detect Digital Signature</h1>
<button onClick={detectDigitalSignature}>
Detect
</button>
</div>
);
}
export default App;
检测结果弹窗提示文件是否已签名

当需要更新签名信息、更换证书或取消文档的数字认证时,需从 Excel 文件中移除现有的数字签名。使用 Spire.XLS 时,核心流程分为三个阶段:首先通过 FetchFileToVFS 将字体文件和已签名的 Excel 文件载入 WASM 虚拟文件系统;然后实例化 Workbook 加载该文件,调用 RemoveAllDigitalSignatures 方法一次性移除工作簿中的所有数字签名;最后通过 SaveToFile 保存移除签名后的工作簿文件。
下面是一个完整的代码示例,展示了删除 Excel 文件中的所有数字签名:
function App() {
const removeDigitalSignatures = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体和 Excel 文件载入 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/`);
// 加载已签名的工作簿
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
// 移除所有数字签名
workbook.RemoveAllDigitalSignatures();
// 保存移除签名后的工作簿
const outputFileName = 'SignatureRemoved.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>Remove Digital Signatures</h1>
<button onClick={removeDigitalSignatures}>
Remove Signatures
</button>
</div>
);
}
export default App;
删除数字签名后的输出文档

原因:数字签名是应用于整个工作簿的,而非单个工作表。
解决:数字签名作用于整个工作簿级别,无法针对单个工作表检测或删除签名。IsDigitallySigned 和 RemoveAllDigitalSignatures 都是工作簿级别的方法。
原因:实际项目中经常需要处理大量文件,手动逐个操作效率低。
解决:可以使用循环批量处理:
const files = ['report1.xlsx', 'report2.xlsx', 'report3.xlsx'];
for (const file of files) {
await window.spire.FetchFileToVFS(file, '', dataPath);
const wb = new xlsModule.Workbook();
wb.LoadFromFile({ fileName: file });
if (wb.IsDigitallySigned) {
wb.RemoveAllDigitalSignatures();
}
wb.SaveToFile({ fileName: `unsigned_${file}`, version: xlsModule.ExcelVersion.Version2016 });
wb.Dispose();
}
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.Doc for C++ 14.7.2 现已正式发布。该版本新增支持将 Word 文档转换为 Excel 文件,进一步扩展了文档格式转换能力。详情如下。
新功能:
intrusive_ptr<Document> doc = new Document();
doc->LoadFromFile(inputFile.c_str());
doc->SaveToFile(outputFile.c_str(), FileFormat::XLSX);
doc->Close();
Spire.XLS for Java 16.7.3 现已正式发布。该版本新增单元格区域转 HTML 功能,支持在单元格中嵌入复选框控件,以及支持转换 Excel 到 JSON 数据。同时,一些在加载 Excel 文档、拷贝单元格范围或工作表、获取打印区域时出现的问题也得以成功被修复。更多详情如下。
新功能:
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
HTMLOptions.Default.isSaveFreezedPanes(true);
wb.saveToFile(outputFile, FileFormat.HTML);
wb.dispose();
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
MarkdownOptions markdownOptions = new MarkdownOptions();
markdownOptions.isSavePicInRelativePath(true);
wb.saveToMarkdown(outputFile, markdownOptions);
wb.dispose();
sheet.getRange().get("G7").setFormula("=BYROW(B7:F7, LAMBDA(row, AVERAGE(row)))");
sheet.getRange().get("B8").setFormula("=BYCOL(B2:B7, LAMBDA(col, AVERAGE(col)))");
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
MarkdownOptions markdownOptions = new MarkdownOptions();
markdownOptions.isSaveHyperlinkAsRef(true);
wb.saveToMarkdown(outputFile, markdownOptions);
wb.dispose();
StringBuilder sb = new StringBuilder();
Workbook workbook = new Workbook();
workbook.loadFromFile(inputFile);
Worksheet sheet = workbook.getWorksheets().get(0);
CellRange cell = sheet.getRange().get("A1:B3");
sb.append(cell.getHtmlString());
sheet.getRange().get("C4").setFormula("=XMATCH(\"王五\", A2:A5)");
Workbook workbook = new Workbook();
workbook.loadFromFile(inputFile);
Worksheet sheet = workbook.getWorksheets().get(0);
EnumSet<CopyRangeOptions> options = EnumSet.of(CopyRangeOptions.Transpose, CopyRangeOptions.All);
sheet.getRange().get("D1").setText("A1:C4置换到D2:G3:");
sheet.getRange().get("A1:C4").copy(sheet.getRange().get("D2:G3"), options);
sheet.getRange().get("D4").setText("A1:B5置换到D5:");
sheet.getRange().get("A1:B5").copy(sheet.getRange().get("D5"), options);
options = EnumSet.of(CopyRangeOptions.Transpose, CopyRangeOptions.CopyStyles);
sheet.getRange().get("D9").setText("A10置换到D10:");
sheet.getRange().get("A10").copy(sheet.getRange().get("D10"), options);
sheet.getRange().get("D11").setText("A11:B11置换到D12:");
sheet.getRange().get("A11:B11").copy(sheet.getRange().get("D12"), options);
options = EnumSet.of(CopyRangeOptions.Transpose, CopyRangeOptions.CopyConditionalFormats);
sheet.getRange().get("D16").setText("B17:B20置换到D17:");
sheet.getRange().get("B17:B20").copy(sheet.getRange().get("D17"), options);
options = EnumSet.of(CopyRangeOptions.Transpose, CopyRangeOptions.CopyStyles);
sheet.getRange().get("D19").setText("B17:B20置换到D20:");
sheet.getRange().get("B17:B20").copy(sheet.getRange().get("D20"), options);
options = EnumSet.of(CopyRangeOptions.Transpose);
sheet.getRange().get("D22").setText("B17:B20置换到D23:");
sheet.getRange().get("B17:B20").copy(sheet.getRange().get("D23"), options);
workbook.saveToFile(outputFile);
sheet.dispose();
workbook.dispose();
Workbook workbook = new Workbook();
Worksheet sheet = workbook.getWorksheets().get(0);
XlsRange range = (XlsRange)sheet.getRange().get("A1");
range.insertEmbedCheckBox();
range.setEmbedCheckBoxCheckState(true);
workbook.saveToFile(outputFile);
workbook.dispose();
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
Worksheet worksheet = wb.getWorksheets().get(0);
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.getScenarios();
//Initialize list objects with different values for scenarios
List<Object> currentChangePercentage_Values = new ArrayList<Object>() {{ add(0.23); add(0.8); add(1.1); add(0.5); add(0.35); add(0.2); }};
List<Object> increasedChangePercentage_Values = new ArrayList<Object>() {{ add(0.45); add(0.56); add(0.9); add(0.5); add(0.58); add(0.43); }};
List<Object> decreasedChangePercentage_Values = new ArrayList<Object>() {{ add(0.3); add(0.2); add(0.5); add(0.3); add(0.5); add(0.23); }};
List<Object> currentQuantity_Values = new ArrayList<Object>() {{ add(1500); add(3000); add(5000); add(4000); add(500); add(4000); }};
List<Object> increasedQuantity_Values = new ArrayList<Object>() {{ add(1000); add(5000); add(4500); add(3900); add(10000); add(8900); }};
List<Object> decreasedQuantity_Values = new ArrayList<Object>() {{ add(1000); add(2000); add(3000); add(3000); add(300); add(4000); }};
//Add scenarios in the worksheet with different values for the same cells
scenarios.add("Current % of Change", worksheet.getRange().get("F5:F10"), currentChangePercentage_Values);
scenarios.add("Increased % of Change", worksheet.getRange().get("F5:F10"), increasedChangePercentage_Values);
scenarios.add("Decreased % of Change", worksheet.getRange().get("F5:F10"), decreasedChangePercentage_Values);
scenarios.add("Current Quantity", worksheet.getRange().get("D5:D10"), currentQuantity_Values);
scenarios.add("Increased Quantity", worksheet.getRange().get("D5:D10"), increasedQuantity_Values);
scenarios.add("Decreased Quantity", worksheet.getRange().get("D5:D10"), decreasedQuantity_Values);
//Saving the workbook
wb.saveToFile(outputFile, ExcelVersion.Version2013);
wb.dispose();
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
Worksheet worksheet = wb.getWorksheets().get(0);
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.getScenarios();
XlsScenario scenario1 = scenarios.get(0);
XlsScenario scenario2 = scenarios.get(1);
//Modify the scenario
scenario1.setVariableCells(worksheet.getRange().get("A1:A5"), scenario2.getValues());
CellRange sourceCell = worksheet.getRange().get("B1:B5");
scenario2.setVariableCells(sourceCell, scenario2.getValues());
scenario1.show();
scenario2.show();
//Saving the workbook
wb.saveToFile(outputFile, ExcelVersion.Version2013);
wb.dispose();
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
Worksheet worksheet = wb.getWorksheets().get(0);
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.getScenarios();
//delete the scenario
scenarios.removeScenarioAt(0);
scenarios.removeScenarioByName("two");
String content = "";
content += "Count:" + scenarios.getCount() + "\n";
content += "ContainsScenario:" + scenarios.containsScenario("two") + "\n";
content += "ContainsScenario:" + scenarios.containsScenario("one") + "\n";
TestUtil.writeAllText(outputFile, content);
//Saving the workbook
wb.dispose();
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
Worksheet worksheet = wb.getWorksheets().get(0);
// Access the collection of scenarios in the worksheet
XlsScenarioCollection scenarios = worksheet.getScenarios();
//Initialize list objects with different values for scenarios
List<Object> currentChangePercentage_Values = new ArrayList<Object>() {{ add(0.23); add(0.8); add(1.1); add(0.5); add(0.35); add(0.2); }};
List<Object> increasedChangePercentage_Values = new ArrayList<Object>() {{ add(0.45); add(0.56); add(0.9); add(0.5); add(0.58); add(0.43); }};
List<Object> decreasedChangePercentage_Values = new ArrayList<Object>() {{ add(0.3); add(0.2); add(0.5); add(0.3); add(0.5); add(0.23); }};
List<Object> currentQuantity_Values = new ArrayList<Object>() {{ add(1500); add(3000); add(5000); add(4000); add(500); add(4000); }};
List<Object> increasedQuantity_Values = new ArrayList<Object>() {{ add(1000); add(5000); add(4500); add(3900); add(10000); add(8900); }};
List<Object> decreasedQuantity_Values = new ArrayList<Object>() {{ add(1000); add(2000); add(3000); add(3000); add(300); add(4000); }};
//Add scenarios in the worksheet with different values for the same cells
scenarios.add("Current % of Change", worksheet.getRange().get("F5:F10"), currentChangePercentage_Values);
scenarios.add("Increased % of Change", worksheet.getRange().get("F5:F10"), increasedChangePercentage_Values);
scenarios.add("Decreased % of Change", worksheet.getRange().get("F5:F10"), decreasedChangePercentage_Values);
scenarios.add("Current Quantity", worksheet.getRange().get("D5:D10"), currentQuantity_Values);
scenarios.add("Increased Quantity", worksheet.getRange().get("D5:D10"), increasedQuantity_Values);
scenarios.add("Decreased Quantity", worksheet.getRange().get("D5:D10"), decreasedQuantity_Values);
//Create Summary
worksheet.getScenarios().summary(worksheet.getRange().get("L7"));
//Saving the workbook
wb.saveToFile(outputFile, ExcelVersion.Version2013);
wb.dispose();
Workbook wb = new Workbook();
wb.loadFromFile(inputFile);
Worksheet worksheet1 = wb.getWorksheets().get(0);
Worksheet worksheet2 = wb.getWorksheets().get(1);
//Merge the scenario
worksheet1.getScenarios().merge(worksheet2);
//Saving the workbook
wb.saveToFile(outputFile, ExcelVersion.Version2013);
wb.dispose();
Workbook workbook = new Workbook();
workbook.loadFromFile(inputFile);
workbook.saveToFile(outputFile, FileFormat.Json);
workbook.dispose();
问题修复:
Spire.Presentation 11.7.6 现已发布。该版本新增支持保存宏文件以及管理 VBA 模块,包括添加和删除 VBA 模块。同时,修复了应用多个许可证不生效的问题。详情如下。
新功能:
Presentation ppt = new Presentation();
//添加VBA项目到文档
IVbaProject vbaProject = ppt.VbaProject;
vbaProject.Name = "SampleVBAMacro";
vbaProject.CodePage = 936; //设置编码,支持中文
IVbaModule vbaModule = vbaProject.Modules.Add("SampleModule", VbaModuleType.Module);
vbaModule.SourceCode = @"
Sub ExampleMacro()
' 声明变量
Dim pptPres As Object
Dim pptSlide As Object
Dim pptShape As Object
' 设置引用到当前演示文稿
Set pptPres = ActivePresentation
' 遍历所有幻灯片
Dim i As Integer
For i = 1 To pptPres.Slides.Count
Set pptSlide = pptPres.Slides(i)
' 为每张幻灯片添加标题文本 (msoTextOrientationHorizontal = 1)
Set pptShape = pptSlide.Shapes.AddTextbox(1, 50, 50, 600, 50)
pptShape.TextFrame.TextRange.Text = ""幻灯片 "" & i & "" - 由宏自动生成""
With pptShape.TextFrame.TextRange.Font
.Bold = -1 ' msoTrue = -1
.Size = 24
.Color.RGB = RGB(0, 102, 204)
End With
Next i
' 显示完成消息
MsgBox ""宏执行完成!已处理 "" & pptPres.Slides.Count & "" 张幻灯片。"", vbInformation, ""操作提示""
End Sub";
ppt.SaveToFile("result.pptm", FileFormat.Pptm);
ppt.Dispose();
//按名称移除模块
Presentation ppt1 = new Presentation();
ppt1.LoadFromFile(inputFile);
IVbaModule firstModule = ppt1.VbaProject.Modules[0];
sb.AppendLine("【按名称移除】");
sb.AppendLine("模块名称:" + firstModule.Name);
sb.AppendLine("模块类型:" + firstModule.Type);
sb.AppendLine("删除前模块数量:" + ppt1.VbaProject.Modules.Count);
ppt1.VbaProject.Modules.Remove(firstModule.Name);
sb.AppendLine("删除后模块数量:" + ppt1.VbaProject.Modules.Count);
ppt1.SaveToFile("result1.pptm", FileFormat.Pptm);
ppt1.Dispose();
//按索引移除模块
Presentation ppt2 = new Presentation();
ppt2.LoadFromFile(inputFile);
sb.AppendLine("【按索引移除(0)】");
sb.AppendLine("删除前模块数量:" + ppt2.VbaProject.Modules.Count);
ppt2.VbaProject.Modules.RemoveAt(0);
sb.AppendLine("删除后模块数量:" + ppt2.VbaProject.Modules.Count);
ppt2.SaveToFile("result2.pptm", FileFormat.Pptm);
ppt2.Dispose();
//按VbaModule对象移除模块(强制转换为具体类型)
Presentation ppt3 = new Presentation();
ppt3.LoadFromFile(inputFile);
IVbaModule moduleObj = ppt3.VbaProject.Modules[4];
VbaModule vbaModule = (VbaModule)moduleObj;
sb.AppendLine("【按对象移除】");
sb.AppendLine("模块名称:" + vbaModule.Name);
sb.AppendLine("模块类型:" + vbaModule.Type);
sb.AppendLine("删除前模块数量:" + ppt3.VbaProject.Modules.Count);
ppt3.VbaProject.Modules.Remove(vbaModule);
sb.AppendLine("删除后模块数量:" + ppt3.VbaProject.Modules.Count);
ppt3.SaveToFile("result3.pptm", FileFormat.Pptm);
ppt3.Dispose();
//清空所有模块
Presentation ppt4 = new Presentation();
ppt4.LoadFromFile(inputFile);
sb.AppendLine("【清空Clear】");
sb.AppendLine("删除前模块数量:" + ppt4.VbaProject.Modules.Count);
ppt4.VbaProject.Modules.Clear();
sb.AppendLine("删除后模块数量:" + ppt4.VbaProject.Modules.Count);
ppt4.SaveToFile("result4.pptm", FileFormat.Pptm);
问题修复:
https://www.e-iceblue.cn/Downloads/Spire-Presentation-NET.html
我们很高兴宣布 Spire.XLS 16.7.2 正式发布。此版本新增了 ValidateHeaderFooterLength 属性,用于在 Excel 转 PDF 过程中,防止因页眉或页脚文本过长而引发异常。此外,还修复了若干已知问题。具体更新内容如下。
新功能:
workbook.ConverterSetting.ValidateHeaderFooterLength = false;
问题修复: