update at 2026-02-14 11:16:40

This commit is contained in:
douboer@gmail.com
2026-02-14 11:16:40 +08:00
parent 78896060b2
commit 3d9558508a
3 changed files with 67 additions and 3 deletions

View File

@@ -270,6 +270,34 @@ function parseXlsxBuffer(buffer) {
return toRawTable(rows);
}
/**
* 判断二进制是否为 Zip 容器xlsx魔数50 4B。
*/
function isZipMagic(bufferLike) {
if (!bufferLike || typeof bufferLike.byteLength !== 'number' || bufferLike.byteLength < 2) {
return false;
}
const bytes = new Uint8Array(bufferLike, 0, 2);
return bytes[0] === 0x50 && bytes[1] === 0x4b;
}
/**
* 判断二进制是否为 OLE 容器(老 xls魔数D0 CF 11 E0 A1 B1 1A E1。
*/
function isOleMagic(bufferLike) {
if (!bufferLike || typeof bufferLike.byteLength !== 'number' || bufferLike.byteLength < 8) {
return false;
}
const bytes = new Uint8Array(bufferLike, 0, 8);
const signature = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];
for (let i = 0; i < signature.length; i += 1) {
if (bytes[i] !== signature[i]) {
return false;
}
}
return true;
}
/**
* 按文件名后缀自动分流解析器。
*/
@@ -281,6 +309,13 @@ function parseTableByFileName(fileName, payload) {
if (lowerName.endsWith('.xlsx') || lowerName.endsWith('.xls')) {
return parseXlsxBuffer(payload);
}
// 兜底:后缀不可用时,通过文件魔数自动识别 Excel。
if (payload && typeof payload === 'object' && typeof payload.byteLength === 'number') {
if (isZipMagic(payload) || isOleMagic(payload)) {
return parseXlsxBuffer(payload);
}
}
throw new Error('仅支持 .csv / .xlsx / .xls 文件');
}