同一列单元格里往往挤着好几项信息:联系人的姓名、电话与城市写在一格里,订单编码把国家代码、年月日与流水号连成一段。这类数据既排不了序,也筛不出其中某一项。分列要做的,就是按既定规则把一列文本拆开,逐项落到右侧相邻的各列中,原数据留在原处,拆分结果另列保存。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成上述操作,通过虚拟文件系统(VFS)管理输入与输出文件,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
按分隔符号分列
一列中各条目由同一符号分隔时,按该符号即可将其拆分到右侧相邻各列。拆分之后,每一类信息各自成列,可分别用于排序、校验或分类统计,原数据仍留在原处。
分列的做法是先读出首列的文本,拆成若干段,再依次写回右侧各列:
| 写法 | 得到的结果 |
|---|---|
sheet.Range.get({ row, column: 1 }).Text |
读出该行首列的原始文本 |
.split(' ') |
按空格把文本拆成若干段 |
sheet.Range.get({ row, column: index + 2 }).Text = piece |
把第 index 段写入该行右侧第 index + 1 列 |
sheet.AllocatedRange.AutoFitColumns() |
各列宽度按内容自适应 |
具体操作步骤如下:
- 用
window.spire.FetchFileToVFS把字体文件与测试数据文件载入 VFS。 - 用
new Workbook()新建工作簿,用workbook.LoadFromFile载入输入文件,再用workbook.Worksheets.get(0)取得目标工作表。 - 用
sheet.LastRow取得数据末行,自第 2 行起逐行处理,跳过表头。 - 用
sheet.Range.get({ row, column: 1 }).Text读出首列的原始文本,用split(' ')按分隔符号拆成若干段。 - 遍历各段,用
sheet.Range.get({ row, column: index + 2 }).Text自第二列起依次写回。 - 用
sheet.AllocatedRange.AutoFitColumns()令各列宽度随内容自适应。 - 用
workbook.SaveToFile保存工作簿,再用workbook.Dispose释放 workbook 对象以释放资源。
以下为完整的代码示例,演示如何在 React 中按分隔符号拆分 Excel 列:
function App() {
const splitByDelimiter = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体与测试数据文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'SplitTextIntoColumns.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);
// 逐行取 A 列文本,按空格拆分后写入右侧各列
const lastRow = sheet.LastRow;
for (let row = 2; row <= lastRow; row++) {
const pieces = sheet.Range.get({ row, column: 1 }).Text.split(' ');
pieces.forEach((piece, index) => {
sheet.Range.get({ row, column: index + 2 }).Text = piece;
});
}
// 让各列宽度按内容自适应
sheet.AllocatedRange.AutoFitColumns();
// 保存工作簿
const outputFileName = 'SplitByDelimiter.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2016 });
// 释放 workbook 对象以释放资源
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>设置 Excel 数据分列</h1>
<button id="split-by-delimiter" onClick={splitByDelimiter}>按分隔符号分列</button>
</div>
);
}
export default App;
按分隔符号分列后的工作表:

按固定宽度分列
另有一类文本不靠符号分段,各条目长度固定、首尾相接,例如由多个定宽字段拼接而成的编码。这类文本需按各条目的字符数依次切分,自上一段的末尾接着截取。
切分按各段的字符数推进截取位置,再依次写回右侧各列:
| 写法 | 得到的结果 |
|---|---|
sheet.Range.get({ row, column: 1 }).Text |
读出该行首列的原始编码 |
code.substring(start, start + width) |
自 start 起截取 width 个字符 |
start += width |
截取位置后移该段长度,下一段接着切 |
sheet.Range.get({ row, column: index + 2 }).Text = piece |
把第 index 段写入该行右侧第 index + 1 列 |
sheet.AllocatedRange.AutoFitColumns() |
各列宽度按内容自适应 |
具体操作步骤如下:
- 用
window.spire.FetchFileToVFS把字体文件与测试数据文件载入 VFS。 - 用
new Workbook()新建工作簿,用workbook.LoadFromFile载入输入文件,再用workbook.Worksheets.get(2)取得待拆分文本所在的工作表。 - 用数组记下各条目的字符数,各项之和应与原文长度一致。
- 用
sheet.LastRow取得数据末行,自第 2 行起逐行处理,跳过表头。 - 用
code.substring(start, start + width)自当前起始位置截取一段,再把起始位置后移该段长度;用sheet.Range.get({ row, column: index + 2 }).Text自第二列起依次写回。 - 用
sheet.AllocatedRange.AutoFitColumns()令各列宽度随内容自适应。 - 用
workbook.SaveToFile保存工作簿,再用workbook.Dispose释放 workbook 对象以释放资源。
以下为完整的代码示例,演示如何在 React 中按固定宽度拆分 Excel 列:
function App() {
const splitByFixedWidth = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体与测试数据文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'SplitTextIntoColumns.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(2);
// 逐行取 A 列编码,按各段长度切开后写入右侧各列
const widths = [2, 4, 2, 2, 3];
const lastRow = sheet.LastRow;
for (let row = 2; row <= lastRow; row++) {
const code = sheet.Range.get({ row, column: 1 }).Text;
let start = 0;
widths.forEach((width, index) => {
sheet.Range.get({ row, column: index + 2 }).Text = code.substring(start, start + width);
start += width;
});
}
// 让各列宽度按内容自适应
sheet.AllocatedRange.AutoFitColumns();
// 保存工作簿
const outputFileName = 'SplitByFixedWidth.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2016 });
// 释放 workbook 对象以释放资源
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>设置 Excel 数据分列</h1>
<button id="split-by-fixed-width" onClick={splitByFixedWidth}>按固定宽度分列</button>
</div>
);
}
export default App;
按固定宽度分列后的工作表:

常见问题
一列文本里的分隔符号不止一种,如何一次拆开
原因:split(' ') 一次只按一个字符切分,文本里混用逗号、斜杠等多种符号时,只能逐个符号分别处理,写法会随之累加,也容易遗漏其中某一种。
解决:把待选的分隔符号一并写进字符类,一次拆分即可覆盖全部——方括号内的字符互为「或」的关系,命中其中任意一个都算分隔点。示例工作簿的地址表用逗号或斜杠分隔各级地址,按该写法可一次拆成三列:
// 逗号与斜杠都算分隔点,一次拆开
const pieces = sheet.Range.get({ row, column: 1 }).Text.split(/[,/]/);
拆分后中间多出一列空白
原因:split(' ') 严格按单个空格切分,原始文本里出现两处相邻空格时,两格之间会切出一个空字符串,写到工作表上便是一列空白。
解决:先用 trim() 去掉首尾空格,再按 /\s+/ 拆分——连续的空格被视作一个分隔点,中间不会再切出空串:
// 去掉首尾空格后按一段连续空白拆分,避免拆出空串
const pieces = sheet.Range.get({ row, column: 1 }).Text.trim().split(/\s+/);
分列会把右侧各列原有的数据覆盖掉吗
原因:拆分结果是按 sheet.Range.get({ row, column: index + 2 }).Text = piece 逐格写入的,目标列原本的内容会被同一行新写入的条目取代。首列的原文不受影响,右侧各列则会按写入的段数多少被覆盖或留下未动的旧数据。
解决:要保留右侧原有的数据,先把结果写到更靠右的空白列,或另存一张工作表再写入;写入前也可以先用 sheet.LastColumn 确认右侧是否已有内容。
按固定宽度切分时,各段长度之和与原文长度不一致会怎样
原因:substring(start, start + width) 只截取原文中确实存在的部分。各段长度之和小于原文长度时,末尾多出的字符不会进入任何一列;大于原文长度时,超出部分截到空串,会写出一列空白。
解决:切分前先核对各段长度之和与原文长度是否相等,两者一致时每一段都能落在自己的列里。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







