Spire.Doc 13.3.5 现已正式发布,最新版本支持写出为 MHTML 格式文件。此外,最新版本还进行了一些升级,比如缩短了从 Uri 下载图片的等待时间。更多详情请查阅以下内容。
新功能:
升级:
HarfBuzzSharp -> 8.3.0.1, SkiaSharp -> 3.116.1<PackageReference Include="HarfBuzzSharp" Version="8.3.0.1" />
<PackageReference Include="SkiaSharp" Version="3.116.1" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.5.0" />
<PackageReference Include="System.Security.Cryptography.Xml" Version="4.7.1" />
<PackageReference Include="System.Security.Permissions" Version="4.5.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />Spire.XLS for Java 15.3.1 现已发布。该版本增强了 Excel 到 HTML 的转换,并且还修复了两个在设置单元格字体大小和加载 Excel 文档时出现的问题。详情查看下文。
问题修复:
在电子文档处理中,数字签名是一种重要的安全措施,可用于验证 PDF 文件的真实性和完整性。通过验证数字签名,可以确认签名是否有效,以及文档是否被篡改。此外,提取数字签名信息如签名图片,可用于进一步分析或存档。了解如何验证和提取PDF中的数字签名,有助于确保文件的安全性和合规性。在本文中,我们将介绍如何使用 Spire.PDF for Python 在 Python 中验证和提取 PDF 中的数字签名。
本教程需要用到 Spire.PDF for Python 和 plum-dispatch v1.7.4。可以通过以下 pip 命令将它们轻松安装到 Windows 中。
pip install Spire.PDF
如果您不清楚如何安装,请参考此教程: 如何在 Windows 中安装 Spire.PDF for Python
Spire.PDF for Python 提供了 PdfDocument.VerifySignature(signName: str) 方法,用于检查 PDF 文档中数字签名的有效性。具体步骤如下:
from spire.pdf.common import *
from spire.pdf import *
# 加载PDF文档
doc = PdfDocument()
doc.LoadFromFile("签名.pdf")
# 访问文档中的表单
pdfform = doc.Form
formWidget = PdfFormWidget(pdfform)
# 检查表单中是否有域
if formWidget.FieldsWidget.Count > 0:
# 遍历表单中的所有域
for i in range(formWidget.FieldsWidget.Count):
field = formWidget.FieldsWidget.get_Item(i)
# 检查域是否为PdfSignatureFieldWidget
if isinstance(field, PdfSignatureFieldWidget):
# 将域转换为PdfSignatureFieldWidget实例
signatureField = PdfSignatureFieldWidget(field)
# 获取签名域的完整名称
fullName = signatureField.FullName
# 验证签名
valid = doc.VerifySignature(fullName)
# 根据验证结果确定签名状态
if valid:
print("签名有效")
else:
print("签名无效")
doc.Close()

要确定 PDF 文档在签署后是否被修改,可以使用 Security_PdfSignature.VerifyDocModified() 方法。此方法返回布尔值:True 表示文档已被修改,签名无效;False 表示文档自签署以来未被修改。具体步骤如下:
from spire.pdf.common import *
from spire.pdf import *
# 加载PDF文档
doc = PdfDocument()
doc.LoadFromFile("签名.pdf")
# 访问文档中的表单
pdfform = doc.Form
formWidget = PdfFormWidget(pdfform)
# 检查表单中是否有域
if formWidget.FieldsWidget.Count > 0:
# 遍历表单中的所有域
for i in range(formWidget.FieldsWidget.Count):
field = formWidget.FieldsWidget.get_Item(i)
# 检查域是否为PdfSignatureFieldWidget
if isinstance(field, PdfSignatureFieldWidget):
# 将域转换为PdfSignatureFieldWidget实例
signatureField = PdfSignatureFieldWidget(field)
# 获取签名
signature = signatureField.Signature
# 验证文档自签署以来是否已被修改
modified = signature.VerifyDocModified()
# 根据验证结果确定文档状态
if modified:
print("文档已被修改")
else:
print("文档未被修改")
doc.Close()

Spire.PDF for Python 还提供了 PdfFormWidget.ExtractSignatureAsImages 属性,支持提取 PDF 文档中的所有签名图片。具体步骤如下:
from spire.pdf.common import *
from spire.pdf import *
# 加载PDF文档
doc = PdfDocument()
doc.LoadFromFile("签名.pdf")
# 访问文档中的表单
pdfform = doc.Form
formWidget = PdfFormWidget(pdfform)
i = 0
# 从表单中提取签名图片并保存为文件
for image in formWidget.ExtractSignatureAsImages:
filename = "Signature/" + f"Signature-{i}.png"
# 将图片保存为文件
image.Save(filename)
i = i + 1
doc.Close()

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.Doc for Java 13.3.0 现已正式发布。该版本支持设置默认的替换字体,还修复了一些在 转换 Word 到 PDF、Word 到 HTML,以及添加目录时出现的问题。 更多详情如下。
新功能:
doc.setDefaultSubstitutionFontName("simsun");问题修复:
在数据可视化应用中,将 Excel 工作簿中的图表和形状导出为独立图像是提升跨平台兼容性的关键。通过将动态生成的图表、形状转换为 PNG/JPG 等通用图像格式,开发者可确保数据可视化内容在网页、移动端等非 Office 环境中正确展示,同时简化报告生成和演示文稿更新的工作流程。借助 Spire.XLS for JavaScript 库,开发人员能够在 React 程序中轻松实现 Excel 图表和形状的导出功能。
本文将介绍如何使用 Spire.XLS for JavaScript 在 React 中通过 JavaScript 代码将 Excel 工作簿中的图表和形状保存为图像,提供详细的步骤介绍和代码示例。
要在 React 应用中实现 Excel 图表和形状的导出,首先需要下载 Spire.XLS for JavaScript,或者通过 npm 进行安装:
npm i spire.office
下载的产品包整合了Spire.Doc for JavaScript,Spire.XLS for JavaScript,Spire.PDF for JavaScript,Spire.Presentation for JavaScript,使用Spire.XLS for JavaScript的功能需将相应( spire.xls.js,Spire.Xls.Wasm.zip,spire.common.js,Spire.Common.Wasm.zip,_framework 文件复制到项目的 public 文件夹中。同时为了确保文本渲染,相关使用字体文件可自定义路径添加。以下示例中,字体添加路径为:public\static\font。
详细的安装和配置步骤,请参考此教程:如何在 React 项目中集成 Spire.XLS for JavaScript
借助 Spire.XLS for JavaScript 的 WebAssembly 模块,开发人员可以使用 Workbook.SaveChartAsImage() 方法将 Excel 工作表中的特定图表保存为图像,并存储到虚拟文件系统(VFS)中。保存的图像可以下载或用于进一步处理。
具体步骤如下:
import React, { useState, useEffect } from 'react';
import JSZip from 'jszip';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.XLS
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.xls.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.xls.js WASM module:', error);
}
})();
}, []);
// 将图表转换为图片的函数
const SaveExcelChartAsImage = async () => {
const wasmModule = window.wasmModule.spirexls;
if (wasmModule) {
// 将字体加载到虚拟文件系统(VFS)中
await window.spire.FetchFileToVFS('Arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
// 将 Excel 文件加载到虚拟文件系统 (VFS)
const inputFileName = '示例.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);
// 在VFS中创建图像文件夹
const imageFolderName = `Images`;
window.dotnetRuntime.Module.FS.mkdirTree(imageFolderName);
// 创建一个新的工作簿
const workbook = new wasmModule.Workbook();
// 从虚拟文件系统加载 Excel 文件
workbook.LoadFromFile(inputFileName);
// 遍历工作簿中的每个工作表
for (let i = 0; i < workbook.Worksheets.Count; i++) {
// 获取当前工作表
const sheet = workbook.Worksheets.get(i);
// 遍历工作表中的每个图表
for (let j = 0; j < sheet.Charts.Count; j++) {
// 将当前图表保存为图像
let image = workbook.SaveChartAsImage({ worksheet: sheet, chartIndex: j })
let filePath = `${imageFolderName}/${sheet.Name}_Chart-${j}.png`;
image.Save(filePath);
}
}
// 递归函数,将目录及其内容添加到ZIP中
const addFilesToZip = (folderPath, zipFolder) => {
const items = window.dotnetRuntime.Module.FS.readdir(folderPath);
items.filter(item => item !== "." && item !== "..").forEach((item) => {
const itemPath = `${folderPath}/${item}`;
try {
// 尝试读取文件数据
const fileData = window.dotnetRuntime.Module.FS.readFile(itemPath);
zipFolder.file(item, fileData);
} catch (error) {
if (error.code === 'EISDIR') {
// 如果是目录,则在ZIP中创建新文件夹,并递归进入它
const zipSubFolder = zipFolder.folder(item);
addFilesToZip(itemPath, zipSubFolder);
} else {
// 处理其他错误
console.error(`处理${itemPath}时出错:`, error);
}
}
});
};
// 将图像文件夹打包成ZIP文件
const zip = new JSZip();
addFilesToZip(imageFolderName, zip);
// 从结果ZIP文件生成Blob并触发下载
zip.generateAsync({type:"blob"})
.then(function(content) {
const link = document.createElement('a');
link.href = URL.createObjectURL(content);
link.download = 'img.zip';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
}).catch(function(err) {
console.error("生成ZIP文件时出错:", err);
});
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>React中使用JavaScript将Excel图表保存为图像</h1>
<button onClick={SaveExcelChartAsImage} disabled={!wasmModule}>
导出图表
</button>
</div>
);
}
export default App;

开发者可以使用 Worksheet.PrstGeomShapes.get() 方法从 Excel 工作表中获取形状,并使用 shape.SaveToImage() 方法将其保存为图像。保存的图像可存储在虚拟文件系统(VFS)中,并可下载或用于进一步处理。
具体步骤如下:
import React, { useState, useEffect } from 'react';
import JSZip from 'jszip';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.XLS
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.xls.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.xls.js WASM module:', error);
}
})();
}, []);
// 将形状转换为图像的函数
const SaveExcelShapeAsImage = async () => {
const wasmModule = window.wasmModule.spirexls;
if (wasmModule) {
// 将字体加载到虚拟文件系统(VFS)中
await window.spire.FetchFileToVFS('Arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
// 将 Excel 文件加载到虚拟文件系统 (VFS)
const inputFileName = 'Shape.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);
// 在VFS中创建图像文件夹
const imageFolderName = `Images`;
window.dotnetRuntime.Module.FS.mkdirTree(imageFolderName);
// 创建一个新的工作簿
const workbook = new wasmModule.Workbook();
// 从虚拟文件系统加载 Excel 文件
workbook.LoadFromFile(inputFileName);
// 遍历工作簿中的每个工作表
for (let i = 0; i < workbook.Worksheets.Count; i++) {
// 获取当前工作表
const sheet = workbook.Worksheets.get(i);
// 遍历工作表中的每个形状
for (let j = 0; j < sheet.PrstGeomShapes.Count; j++) {
console.log(sheet.PrstGeomShapes.Count);
// 获取当前形状
const shape = sheet.PrstGeomShapes.get(j);
// 将形状保存为图像
const image = shape.SaveToImage();
// 将图像保存到VFS
let filePath = `${imageFolderName}/${sheet.Name}_shape-${j}.png`;
image.Save(filePath);
}
}
// 递归函数,将目录及其内容添加到ZIP中
const addFilesToZip = (folderPath, zipFolder) => {
const items = window.dotnetRuntime.Module.FS.readdir(folderPath);
items.filter(item => item !== "." && item !== "..").forEach((item) => {
const itemPath = `${folderPath}/${item}`;
try {
// 尝试读取文件数据
const fileData = window.dotnetRuntime.Module.FS.readFile(itemPath);
zipFolder.file(item, fileData);
} catch (error) {
if (error.code === 'EISDIR') {
// 如果是目录,则在ZIP中创建新文件夹,并递归进入它
const zipSubFolder = zipFolder.folder(item);
addFilesToZip(itemPath, zipSubFolder);
} else {
// 处理其他错误
console.error(`处理${itemPath}时出错:`, error);
}
}
});
};
// 将图像文件夹打包成ZIP文件
const zip = new JSZip();
addFilesToZip(imageFolderName, zip);
// 从结果ZIP文件生成Blob并触发下载
zip.generateAsync({ type: "blob" })
.then(function (content) {
const link = document.createElement('a');
link.href = URL.createObjectURL(content);
link.download = 'shapeToimg.zip';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(link.href);
}).catch(function (err) {
console.error("生成ZIP文件时出错:", err);
});
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在React中用JavaScript将Excel形状保存为图像</h1>
<button onClick={SaveExcelShapeAsImage} disabled={!wasmModule}>
导出形状
</button>
</div>
);
}
export default App;

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
在使用 Excel 时,有时需要保护关键数据,同时允许用户对其他部分进行编辑。尤其当某些公式、标题或参考值必须保持不变以确保数据完整性时,保护数据变得尤为重要。通过锁定特定区域,可以有效防止意外修改,确保数据一致性,并控制对电子表格中关键内容的编辑权限。本文将介绍如何在 React 中使用 JavaScript 和 Spire.XLS for JavaScript 库锁定 Excel 中的单元格、行和列。
要在 React 应用程序中实现锁定Excel单元格、行和列,首先需要下载 Spire.XLS for JavaScript,或者通过 npm 进行安装:
npm i spire.office
下载的产品包整合了Spire.Doc for JavaScript,Spire.XLS for JavaScript,Spire.PDF for JavaScript,Spire.Presentation for JavaScript,使用Spire.XLS for JavaScript的功能需将相应( spire.xls.js,Spire.Xls.Wasm.zip,spire.common.js,Spire.Common.Wasm.zip,_framework 文件复制到项目的 public 文件夹中。同时为了确保文本渲染,相关使用字体文件可自定义路径添加。以下示例中,字体添加路径为:public\static\font。
详细的安装和配置步骤,请参考此教程:如何在 React 项目中集成 Spire.XLS for JavaScript
Spire.XLS for JavaScript 提供了 Worksheet.Range.get().Style.Locked 属性,允许你保护关键数据单元格,同时使工作表的其他部分可以进行编辑。详细步骤如下:
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.XLS
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.xls.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.xls.js WASM module:', error);
}
})();
}, []);
// 锁定Excel中特定单元格的函数
const LockExcelCells = async () => {
const wasmModule = window.wasmModule.spirexls;
if (wasmModule) {
// 将字体加载到虚拟文件系统(VFS)中
await window.spire.FetchFileToVFS('Arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
// 将 Excel 文件加载到虚拟文件系统 (VFS)
const inputFileName = '示例.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);
// 创建一个新的工作簿
const workbook = new wasmModule.Workbook();
// 从虚拟文件系统加载 Excel 文件
workbook.LoadFromFile(inputFileName);
// 获取第一个工作表
let sheet = workbook.Worksheets.get(0);
// 解锁工作表中已使用范围内的所有单元格
sheet.Range.Style.Locked = false;
// 锁定工作表中的特定单元格
sheet.Range.get("A1").Style.Locked = true;
// 锁定工作表中的特定单元格范围
sheet.Range.get("C1:E3").Style.Locked = true;
// 使用密码保护工作表
sheet.Protect({ password: "123", options: wasmModule.SheetProtectionType.All });
let outputFileName = "锁定单元格.xlsx";
workbook.SaveToFile({ fileName: outputFileName, version: wasmModule.ExcelVersion.Version2010 });
// 读取保存的文件并转换为Blob对象
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// 为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);
// 清理工作簿使用的资源
workbook.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在React中使用JavaScript锁定Excel中的特定单元格</h1>
<button onClick={LockExcelCells} disabled={!wasmModule}>
锁定
</button>
</div>
);
}
export default App;
React 应用程序编译成功后,将在默认网页浏览器中打开,通常是 http://localhost:3000。

点击“锁定”就能下载锁定单元格后的结果文件。打开文件并尝试编辑受保护的单元格时,将出现一个对话框,通知你正在修改的单元格位于受保护的工作表上:

如果你需要保护基于行的数据,如标题或汇总,可以使用 Spire.XLS for JavaScript 的 Worksheet.Rows.get().Style.Locked 属性锁定整个行。详细步骤如下:
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.XLS
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.xls.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.xls.js WASM module:', error);
}
})();
}, []);
// 锁定Excel中特定行的函数
const LockExcelRows = async () => {
const wasmModule = window.wasmModule.spirexls;
if (wasmModule) {
// 将字体加载到虚拟文件系统(VFS)中
await window.spire.FetchFileToVFS('Arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
// 将 Excel 文件加载到虚拟文件系统 (VFS)
const inputFileName = '示例.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);
// 创建一个新的工作簿
const workbook = new wasmModule.Workbook();
// 从虚拟文件系统加载 Excel 文件
workbook.LoadFromFile(inputFileName);
// 获取第一个工作表
let sheet = workbook.Worksheets.get(0);
// 解锁工作表中已使用范围内的所有单元格
sheet.Range.Style.Locked = false;
// 锁定工作表中的第三行
sheet.Rows.get(2).Style.Locked = true;
// 使用密码保护工作表
sheet.Protect({ password: "123", options: wasmModule.SheetProtectionType.All });
let outputFileName = "锁定行.xlsx";
workbook.SaveToFile({ fileName: outputFileName, version: wasmModule.ExcelVersion.Version2010 });
// 读取保存的文件并转换为Blob对象
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// 为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);
// 清理工作簿使用的资源
workbook.Dispose();
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在React中使用JavaScript锁定Excel中的特定行</h1>
<button onClick={LockExcelRows} disabled={!wasmModule}>
锁定
</button>
</div>
);
}
export default App;

要维护关键纵向数据的完整性,如固定的标识符或类别标签,可以使用 Spire.XLS for JavaScript 的 Worksheet.Columns.get().Style.Locked 属性锁定整个列。详细步骤如下:
import React, { useState, useEffect } from 'react';
function App() {
const [wasmModule, setWasmModule] = useState(null);
// 加载 Spire.XLS
useEffect(() => {
(async () => {
try {
const publicUrl = process.env.PUBLIC_URL || '';
const spireModule = await import(/* webpackIgnore: true */ `${publicUrl}/spire.xls.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.xls.js WASM module:', error);
}
})();
}, []);
// 锁定Excel中特定列的函数
const LockExcelColumns = async () => {
const wasmModule = window.wasmModule.spirexls;
if (wasmModule) {
// 将字体加载到虚拟文件系统(VFS)中
await window.spire.FetchFileToVFS('Arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/static/font/`);
// 将 Excel 文件加载到虚拟文件系统 (VFS)
const inputFileName = '示例.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/static/data/`);
// 创建一个新的工作簿
const workbook = new wasmModule.Workbook();
// 从虚拟文件系统加载 Excel 文件
workbook.LoadFromFile(inputFileName);
// 获取第一个工作表
let sheet = workbook.Worksheets.get(0);
// 解锁工作表中已使用范围内的所有单元格
sheet.Range.Style.Locked = false;
// 锁定工作表中的第四列
sheet.Columns.get(1).Style.Locked = true;
// 使用密码保护工作表
sheet.Protect({ password: "123", options: wasmModule.SheetProtectionType.All });
let outputFileName = "锁定列.xlsx";
workbook.SaveToFile({ fileName: outputFileName, version: wasmModule.ExcelVersion.Version2010 });
// 读取保存的文件并转换为Blob对象
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const modifiedFile = new Blob([modifiedFileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
// 为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);
// 清理工作簿使用的资源
workbook.Dispose();
}
};
return (<
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>在React中使用JavaScript锁定Excel中的特定列</h1>
<button onClick={LockExcelColumns} disabled={!wasmModule}>
锁定
</button>
</div>
);
}
export default App;

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
Spire.PDF 11.3 现已正式发布。最新版本增强了 PDF 到 A1A 和 A1B 标准的转换功能。此外,一些已知问题也在更新中被成功修复,例如获取不到按钮域的动作的问题。详情请查阅以下内容。
问题修复:
Excel 中的切片器是一种简单易用的工具,可以帮助用户过滤数据,让数据分析变得更加直观,交互性更强。与传统的过滤方式不同,切片器以按钮的形式展示过滤选项,使得用户能够快速、轻松地调整数据视图。无论是在处理大型数据集还是创建动态仪表板,切片器都能通过实时反馈所选的过滤条件,提升用户体验。这篇文章将介绍如何使用 Spire.XLS for .NET 在 C# 中添加、修改和删除 Excel 切片器。
首先,您需要将 Spire.XLS for .NET 包含的 DLL 文件作为引用添加到您的 .NET 项目中。DLL 文件可以从此链接下载,也可以通过 NuGet 安装。
PM> Install-Package Spire.XLS
Spire.XLS for .NET 提供了 Worksheet.Slicers.Add(IListObject table, string destCellName, int index) 方法,用于给 Excel 工作表中的表格添加切片器。具体步骤如下:
using Spire.Xls;
using Spire.Xls.Core;
namespace AddSlicerToTable
{
internal class Program
{
static void Main(string[] args)
{
// 创建 Workbook 类的实例
Workbook workbook = new Workbook();
// 获取工作簿中的第一个工作表
Worksheet worksheet = workbook.Worksheets[0];
// 向工作表中填充数据
worksheet.Range["A1"].Value = "产品";
worksheet.Range["A2"].Value = "葡萄";
worksheet.Range["A3"].Value = "蓝莓";
worksheet.Range["A4"].Value = "猕猴桃";
worksheet.Range["A5"].Value = "樱桃";
worksheet.Range["A6"].Value = "葡萄";
worksheet.Range["A7"].Value = "蓝莓";
worksheet.Range["A8"].Value = "猕猴桃";
worksheet.Range["A9"].Value = "樱桃";
worksheet.Range["B1"].Value = "年份";
worksheet.Range["B2"].Value2 = 2020;
worksheet.Range["B3"].Value2 = 2020;
worksheet.Range["B4"].Value2 = 2020;
worksheet.Range["B5"].Value2 = 2020;
worksheet.Range["B6"].Value2 = 2021;
worksheet.Range["B7"].Value2 = 2021;
worksheet.Range["B8"].Value2 = 2021;
worksheet.Range["B9"].Value2 = 2021;
worksheet.Range["C1"].Value = "销售额";
worksheet.Range["C2"].Value2 = 50;
worksheet.Range["C3"].Value2 = 60;
worksheet.Range["C4"].Value2 = 70;
worksheet.Range["C5"].Value2 = 80;
worksheet.Range["C6"].Value2 = 90;
worksheet.Range["C7"].Value2 = 100;
worksheet.Range["C8"].Value2 = 110;
worksheet.Range["C9"].Value2 = 120;
// 创建一个表格
IListObject table = worksheet.ListObjects.Create("产品销售数据", worksheet.Range["A1:C9"]);
// 在单元格 "A11" 中添加一个切片器,以便根据表格的第一列过滤数据
int index = worksheet.Slicers.Add(table, "A11", 0);
// 设置切片器的名称和样式
worksheet.Slicers[index].Name = "产品";
worksheet.Slicers[index].StyleType = SlicerStyleType.SlicerStyleLight1;
// 将工作簿保存为 Excel 文件
workbook.SaveToFile("表格切片器.xlsx", ExcelVersion.Version2013);
workbook.Dispose();
}
}
}

除了给 Excel 中的表格添加切片器,Spire.XLS for .NET 还提供了 Worksheet.Slicers.Add(IPivotTable pivot, string destCellName, int baseFieldIndex) 方法,支持给数据透视表添加切片器。具体步骤如下:
using Spire.Xls;
using Spire.Xls.Core;
namespace AddSlicerToPivotTable
{
internal class Program
{
static void Main(string[] args)
{
// 创建 Workbook 类的实例
Workbook workbook = new Workbook();
// 获取第一个工作表
Worksheet worksheet = workbook.Worksheets[0];
// 向工作表中添加数据
worksheet.Range["A1"].Value = "产品";
worksheet.Range["A2"].Value = "葡萄";
worksheet.Range["A3"].Value = "蓝莓";
worksheet.Range["A4"].Value = "猕猴桃";
worksheet.Range["A5"].Value = "樱桃";
worksheet.Range["A6"].Value = "葡萄";
worksheet.Range["A7"].Value = "蓝莓";
worksheet.Range["A8"].Value = "猕猴桃";
worksheet.Range["A9"].Value = "樱桃";
worksheet.Range["B1"].Value = "年份";
worksheet.Range["B2"].Value2 = 2020;
worksheet.Range["B3"].Value2 = 2020;
worksheet.Range["B4"].Value2 = 2020;
worksheet.Range["B5"].Value2 = 2020;
worksheet.Range["B6"].Value2 = 2021;
worksheet.Range["B7"].Value2 = 2021;
worksheet.Range["B8"].Value2 = 2021;
worksheet.Range["B9"].Value2 = 2021;
worksheet.Range["C1"].Value = "销售额";
worksheet.Range["C2"].Value2 = 50;
worksheet.Range["C3"].Value2 = 60;
worksheet.Range["C4"].Value2 = 70;
worksheet.Range["C5"].Value2 = 80;
worksheet.Range["C6"].Value2 = 90;
worksheet.Range["C7"].Value2 = 100;
worksheet.Range["C8"].Value2 = 110;
worksheet.Range["C9"].Value2 = 120;
// 从指定的数据范围创建一个数据透视缓存
CellRange dataRange = worksheet.Range["A1:C9"];
PivotCache cache = workbook.PivotCaches.Add(dataRange);
// 从数据透视缓存创建一个数据透视表
PivotTable pt = worksheet.PivotTables.Add("产品销售数据", worksheet.Range["A12"], cache);
// 将字段拖动到行和列区域
PivotField pf = pt.PivotFields["产品"] as PivotField;
pf.Axis = AxisTypes.Row;
PivotField pf2 = pt.PivotFields["年份"] as PivotField;
pf2.Axis = AxisTypes.Column;
// 将字段拖动到数据区域
pt.DataFields.Add(pt.PivotFields["销售额"], "求和项:销售额", SubtotalTypes.Sum);
// 设置数据透视表的样式
pt.BuiltInStyle = PivotBuiltInStyles.PivotStyleMedium10;
// 计算数据透视表数据
pt.CalculateData();
// 向数据透视表添加切片器
int index_1 = worksheet.Slicers.Add(pt, "F12", 0);
// 设置切片器的名称、宽度、高度和样式
worksheet.Slicers[index_1].Name = "产品";
worksheet.Slicers[index_1].Width = 100;
worksheet.Slicers[index_1].Height = 120;
worksheet.Slicers[index_1].StyleType = SlicerStyleType.SlicerStyleLight2;
// 设置切片器的交叉过滤类型
XlsSlicerCache slicerCache = worksheet.Slicers[index_1].SlicerCache;
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData;
// 计算数据透视表数据
pt.CalculateData();
// 保存工作簿为 Excel 文件
workbook.SaveToFile("数据透视表切片器.xlsx", ExcelVersion.Version2013);
workbook.Dispose();
}
}
}

你可以使用 XlsSlicer 类下的对应属性来修改切片器的样式、名称、标题等。具体步骤如下:
using Spire.Xls;
using Spire.Xls.Core;
namespace UpdateSlicer
{
internal class Program
{
static void Main(string[] args)
{
// 创建 Workbook 类的实例
Workbook workbook = new Workbook();
// 加载 Excel 文件
workbook.LoadFromFile("表格切片器.xlsx");
// 获取第一个工作表
Worksheet worksheet = workbook.Worksheets[0];
// 获取工作表中的第一个切片器
XlsSlicer slicer = worksheet.Slicers[0];
// 更改切片器的样式、名称和标题
slicer.StyleType = SlicerStyleType.SlicerStyleDark4;
slicer.Name = "切片器";
slicer.Caption = "切片器";
// 更改切片器的交叉过滤类型
slicer.SlicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithDataAtTop;
// 在切片器中取消选择一个项目
XlsSlicerCacheItemCollection slicerCacheItems = slicer.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[0];
xlsSlicerCacheItem.Selected = false;
// 保存工作簿为 Excel 文件
workbook.SaveToFile("修改切片器.xlsx", ExcelVersion.Version2013);
workbook.Dispose();
}
}
}

你可以使用 Worksheet.Slicers.RemoveAt(index) 方法从 Excel 工作表中删除特定切片器,也可以使用 Worksheet.Slicers.Clear() 方法一次性删除所有切片器。具体步骤如下:
using Spire.Xls;
using Spire.Xls.Core;
namespace RemoveSlicer
{
internal class Program
{
static void Main(string[] args)
{
// 创建 Workbook 类的实例
Workbook workbook = new Workbook();
// 加载 Excel 文件
workbook.LoadFromFile("表格切片器.xlsx");
// 获取第一个工作表
Worksheet worksheet = workbook.Worksheets[0];
// 通过索引删除第一个切片器
worksheet.Slicers.RemoveAt(0);
// 或者删除所有切片器
// worksheet.Slicers.Clear();
// 保存工作簿为 Excel 文件
workbook.SaveToFile("删除切片器.xlsx", ExcelVersion.Version2013);
workbook.Dispose();
}
}
}

如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。
我们很高兴地宣布 Spire.Office 10.2.0 正式发布。在该版本中, Spire.Doc 增加了大量用于自定义图表的 API;Spire.PDF 支持使用 PdfTextReplacer 类替换指定区域的文本;Spire.XLS 支持 MUNIT、FLOOR.PRECISE 和 CSC 等函数;Spire.Presentation 支持将幻灯片母版中的图像保存为 SVG。同时,还修复了大量已知错误。
版本信息如下:
https://www.e-iceblue.cn/Downloads/Spire-Office-NET.html
新功能:
Spire.Doc.Formatting.RowFormat.TablePositioning->Spire.Doc.Formatting.TablePositioning
Spire.Doc.Printing.PagesPreSheet->Spire.Doc.Printing.PagesPerSheet新功能:
Workbook wb = new Workbook();
Worksheet worksheet = wb.Worksheets[0];
worksheet.Range["A1"].Value = "fruit";
worksheet.Range["A2"].Value = "grape";
worksheet.Range["A3"].Value = "blueberry";
worksheet.Range["A4"].Value = "kiwi";
worksheet.Range["A5"].Value = "cherry";
worksheet.Range["A6"].Value = "grape";
worksheet.Range["A7"].Value = "blueberry";
worksheet.Range["A8"].Value = "kiwi";
worksheet.Range["A9"].Value = "cherry";
worksheet.Range["B1"].Value = "year";
worksheet.Range["B2"].Value2 = 2020;
worksheet.Range["B3"].Value2 = 2020;
worksheet.Range["B4"].Value2 = 2020;
worksheet.Range["B5"].Value2 = 2020;
worksheet.Range["B6"].Value2 = 2021;
worksheet.Range["B7"].Value2 = 2021;
worksheet.Range["B8"].Value2 = 2021;
worksheet.Range["B9"].Value2 = 2021;
worksheet.Range["C1"].Value = "amount";
worksheet.Range["C2"].Value2 = 50;
worksheet.Range["C3"].Value2 = 60;
worksheet.Range["C4"].Value2 = 70;
worksheet.Range["C5"].Value2 = 80;
worksheet.Range["C6"].Value2 = 90;
worksheet.Range["C7"].Value2 = 100;
worksheet.Range["C8"].Value2 = 110;
worksheet.Range["C9"].Value2 = 120;
// Get slicer collection
XlsSlicerCollection slicers = worksheet.Slicers;
//Create a super table with the data from the specific cell range.
IListObject table = worksheet.ListObjects.Create("Super Table", worksheet.Range["A1:C9"]);
int count = 3;
int index = 0;
foreach (SlicerStyleType type in Enum.GetValues(typeof(SlicerStyleType)))
{
count += 5;
//Add a Slicer through table data : here invoke Add(IListObject, string, int) api.
String range = "E" + count;
index = slicers.Add(table, range.ToString(), 0);
//Style setting
XlsSlicer xlsSlicer = slicers[index];
xlsSlicer.Name = "slicers_" + count;
xlsSlicer.StyleType = type;
}
//Save to file
wb.SaveToFile("output.xlsx", ExcelVersion.Version2013);Workbook wb = new Workbook();
Worksheet worksheet = wb.Worksheets[0];
worksheet.Range["A1"].Value = "fruit";
worksheet.Range["A2"].Value = "grape";
worksheet.Range["A3"].Value = "blueberry";
worksheet.Range["A4"].Value = "kiwi";
worksheet.Range["A5"].Value = "cherry";
worksheet.Range["A6"].Value = "grape";
worksheet.Range["A7"].Value = "blueberry";
worksheet.Range["A8"].Value = "kiwi";
worksheet.Range["A9"].Value = "cherry";
worksheet.Range["B1"].Value = "year";
worksheet.Range["B2"].Value2 = 2020;
worksheet.Range["B3"].Value2 = 2020;
worksheet.Range["B4"].Value2 = 2020;
worksheet.Range["B5"].Value2 = 2020;
worksheet.Range["B6"].Value2 = 2021;
worksheet.Range["B7"].Value2 = 2021;
worksheet.Range["B8"].Value2 = 2021;
worksheet.Range["B9"].Value2 = 2021;
worksheet.Range["C1"].Value = "amount";
worksheet.Range["C2"].Value2 = 50;
worksheet.Range["C3"].Value2 = 60;
worksheet.Range["C4"].Value2 = 70;
worksheet.Range["C5"].Value2 = 80;
worksheet.Range["C6"].Value2 = 90;
worksheet.Range["C7"].Value2 = 100;
worksheet.Range["C8"].Value2 = 110;
worksheet.Range["C9"].Value2 = 120;
// Get pivot table collection
Spire.Xls.Collections.PivotTablesCollection pivotTables = worksheet.PivotTables;
//Add a PivotTable to the worksheet
CellRange dataRange = worksheet.Range["A1:C9"];
PivotCache cache = wb.PivotCaches.Add(dataRange);
//Cell to put the pivot table
Spire.Xls.PivotTable pt = worksheet.PivotTables.Add("TestPivotTable", worksheet.Range["A12"], cache);
//Drag the fields to the row area.
PivotField pf = pt.PivotFields["fruit"] as PivotField;
pf.Axis = AxisTypes.Row;
PivotField pf2 = pt.PivotFields["year"] as PivotField;
pf2.Axis = AxisTypes.Column;
//Drag the field to the data area.
pt.DataFields.Add(pt.PivotFields["amount"], "SUM of Count", SubtotalTypes.Sum);
//Set PivotTable style
pt.BuiltInStyle = PivotBuiltInStyles.PivotStyleMedium10;
pt.CalculateData();
//Get slicer collection
XlsSlicerCollection slicers = worksheet.Slicers;
//Add a Slicer through pivot table data: here invoke Add(IPivotTable, string, int) api.
int index = slicers.Add(pt, "E12", 0);
XlsSlicer xlsSlicer = slicers[index];
xlsSlicer.Name = "test_xlsSlicer";
xlsSlicer.Width = 100;
xlsSlicer.Height = 120;
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleLight2;
xlsSlicer.PositionLocked = true;
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.SlicerCache;
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData;
//Style setting
XlsSlicerCacheItemCollection slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[0];
xlsSlicerCacheItem.Selected = false;
XlsSlicerCollection slicers_2 = worksheet.Slicers;
IPivotField r1 = pt.PivotFields["year"];
int index_2 = slicers_2.Add(pt, "I12", r1);
XlsSlicer xlsSlicer_2 = slicers[index_2];
xlsSlicer_2.RowHeight = 40;
xlsSlicer_2.StyleType = SlicerStyleType.SlicerStyleLight3;
xlsSlicer_2.PositionLocked = false;
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache_2 = xlsSlicer_2.SlicerCache;
slicerCache_2.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithDataAtTop;
//Style setting
XlsSlicerCacheItemCollection slicerCacheItems_2 = xlsSlicer_2.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem_2 = slicerCacheItems_2[1];
xlsSlicerCacheItem_2.Selected = false;
pt.CalculateData();
//Save to file
wb.SaveToFile("out.xlsx", ExcelVersion.Version2013);Workbook wb = new Workbook();
wb.LoadFromFile(inputFile);
//Get slicer collection of first worksheet
Worksheet worksheet = wb.Worksheets[0];
XlsSlicerCollection slicers = worksheet.Slicers;
//Remove the first slicer by index
slicers.RemoveAt(0);
Worksheet worksheet_2 = wb.Worksheets[1];
//Remove all slicers
worksheet_2.Slicers.Clear();
wb.SaveToFile(outputFile, ExcelVersion.Version2013);Workbook wb = new Workbook();
wb.LoadFromFile("in.xlsx");
//Get the first worksheet of workbook
Worksheet worksheet = wb.Worksheets[0];
//Get slicer collection
XlsSlicerCollection slicers = worksheet.Slicers;
//Style setting
XlsSlicer xlsSlicer = slicers[0];
xlsSlicer.StyleType = SlicerStyleType.SlicerStyleDark4;
xlsSlicer.Caption = "Slicer";
xlsSlicer.PositionLocked = true;
XlsSlicerCacheItemCollection slicerCacheItems = xlsSlicer.SlicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[0];
xlsSlicerCacheItem.Selected = false;
string displayValue = xlsSlicerCacheItem.DisplayValue;
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.SlicerCache;
slicerCache.CrossFilterType = SlicerCacheCrossFilterType.ShowItemsWithNoData;
//Save to file
wb.SaveToFile("out.xlsx", ExcelVersion.Version2013);Workbook wb = new Workbook();
wb.LoadFromFile("in.xlsx");
//Get slicer collection of first worksheet
Worksheet worksheet = wb.Worksheets[0];
XlsSlicerCollection slicers = worksheet.Slicers;
StringBuilder builder = new StringBuilder();
builder.AppendLine("slicers.Count:" + slicers.Count);
XlsSlicer xlsSlicer = slicers[1];
builder.AppendLine("xlsSlicer.Name:" + xlsSlicer.Name);
builder.AppendLine("xlsSlicer.Caption:" + xlsSlicer.Caption);
builder.AppendLine("xlsSlicer.NumberOfColumns:" + xlsSlicer.NumberOfColumns);
builder.AppendLine("xlsSlicer.ColumnWidth:" + xlsSlicer.ColumnWidth);
builder.AppendLine("xlsSlicer.RowHeight:" + xlsSlicer.RowHeight);
builder.AppendLine("xlsSlicer.ShowCaption:" + xlsSlicer.ShowCaption);
builder.AppendLine("xlsSlicer.PositionLocked:" + xlsSlicer.PositionLocked);
builder.AppendLine("xlsSlicer.Width:" + xlsSlicer.Width);
builder.AppendLine("xlsSlicer.Height:" + xlsSlicer.Height);
//Get SlicerCache object of current slicer
XlsSlicerCache slicerCache = xlsSlicer.SlicerCache;
builder.AppendLine("slicerCache.SourceName:" + slicerCache.SourceName);
builder.AppendLine("slicerCache.IsTabular:" + slicerCache.IsTabular);
builder.AppendLine("slicerCache.Name:" + slicerCache.Name);
XlsSlicerCacheItemCollection slicerCacheItems = slicerCache.SlicerCacheItems;
XlsSlicerCacheItem xlsSlicerCacheItem = slicerCacheItems[1];
builder.AppendLine("xlsSlicerCacheItem.Selected:" + xlsSlicerCacheItem.Selected);
File.WriteAllText("out.txt", builder.ToString());
wb.Dispose();Workbook wb = new Workbook();
wb.LoadFromFile(inputFile);
Worksheet worksheet = wb.Worksheets[0];
XlsSlicerCollection slicers = worksheet.Slicers;
XlsSlicer xlsSlicer = slicers[0];
xlsSlicer.Caption = "Name1";
wb.SaveToFile(outputFile, ExcelVersion.Version2013);ExportTableOptions op = new ExportTableOptions();
op.ExportColumnNames = true;
op.KeepDataType = true;
var r = sheet.Range["A1:M7"];Workbook workbook = new Workbook();
workbook.Worksheets[0].Range["C2"].Formula = "=MUNIT(5)";
workbook.Worksheets[0].Range["C8"].Formula = "=MUNIT(0)";
workbook.Worksheets[0].Range["A1"].Formula = "=FLOOR.PRECISE(3.2)";
workbook.Worksheets[0].Range["D1"].Formula = "CSC(-2)";
workbook.Worksheets[0].Range["A3"].Formula = "=IMCSCH(\"4 + 3i\")";
workbook.CalculateAllValue();问题修复:
新功能:
Presentation ppt = new Presentation();
ppt.LoadFromFile(inputFile);
int num = 1;
IMasterSlide masterSlide = ppt.Masters[0];
for (int i = 0; i < masterSlide.Shapes.Count; i++)
{
IShape s = masterSlide.Shapes[i];
if (s is SlidePicture)
{
SlidePicture ps = s as SlidePicture;
byte[] svgByte = s.SaveAsSvgInSlide();
FileStream fs = new FileStream(outputFile +num + ".svg", FileMode.Create);
fs.Write(svgByte, 0, svgByte.Length);
fs.Close();
num++;
}
}问题修复:
新功能:
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(inputFile);
for (int i = 0; i < pdf.Pages.Count; i++)
{
PdfPageBase page = pdf.Pages[i] ;
PdfTextReplacer replacer = new PdfTextReplacer(page);
PdfTextReplaceOptions replaceOptions = new PdfTextReplaceOptions();
RectangleF rectangle = new RectangleF(10, 0, 841, 150);
replaceOptions.SetReplacementArea(rectangle);
replaceOptions.ReplaceType = PdfTextReplaceOptions.ReplaceActionType.IgnoreCase;
replacer.Options = replaceOptions;
replacer.ReplaceAllText("sql", "123456");
}
pdf.SaveToFile(outputFile);
pdf.Dispose();PdfDocument doc = new PdfDocument();
doc.LoadFromFile(inputFile);
PdfFormWidget formWidget = (PdfFormWidget)doc.Form;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("btnAction:");
for (int i = 0; i < formWidget.FieldsWidget.Count; ++i)
{
var field = formWidget.FieldsWidget[i] as PdfButtonWidgetFieldWidget;
if (field.Actions.MouseUp != null && field.Actions.MouseUp is PdfNamedAction)
{
var aaa = (PdfNamedAction)field.Actions.MouseUp;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseUp-" + aaa.Destination.ToString());
}
else if (field.Actions.MouseDown != null && field.Actions.MouseDown is PdfNamedAction)
{
var aaa = (PdfNamedAction)field.Actions.MouseDown;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseDown--" + aaa.Destination.ToString());
}
else if (field.Actions.MouseDown != null && field.Actions.MouseDown is PdfUriAction)
{
var aaa = (PdfUriAction)field.Actions.MouseDown;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseDown--" + aaa.Uri.ToString());
}
else if (field.Actions.MouseUp != null && field.Actions.MouseUp is PdfUriAction)
{
var aaa = (PdfUriAction)field.Actions.MouseUp;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseUp-" + aaa.Uri.ToString());
}
else if (field.Actions.MouseDown != null && field.Actions.MouseDown is PdfGotoNameAction)
{
var aaa = (PdfGotoNameAction)field.Actions.MouseDown;
stringBuilder.AppendLine(formWidget.FieldsWidget[i].Name + "-MouseDown-" + aaa.Destination.ToString());
}
}
File.WriteAllText(outputFile, stringBuilder.ToString());
doc.Dispose();PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(inputFile);
PdfPageBase page = pdf.Pages[0];
PdfTextReplacer replacer = new PdfTextReplacer(page);
int count = replacer.ReplaceAllText("SQL", "ABC");问题修复:
Spire.Presentation 10.3 已发布。本次更新支持保存母版幻灯片中的图片为 SVG,同时增强了形状到 SVG 的转换功能。此外,一些已知问题也在该版本中成功修复,如设置 TextAutofitType.Shape 不生效的问题。详情请阅读以下内容。
新功能:
Presentation ppt = new Presentation();
ppt.LoadFromFile(inputFile);
int num = 1;
IMasterSlide masterSlide = ppt.Masters[0];
for (int i = 0; i < masterSlide.Shapes.Count; i++)
{
IShape s = masterSlide.Shapes[i];
if (s is SlidePicture)
{
SlidePicture ps = s as SlidePicture;
byte[] svgByte = s.SaveAsSvgInSlide();
FileStream fs = new FileStream(outputFile +num + ".svg", FileMode.Create);
fs.Write(svgByte, 0, svgByte.Length);
fs.Close();
num++;
}
}问题修复:
https://www.e-iceblue.cn/Downloads/Spire-Presentation-NET.html