如何通过SheetJS从XLSX获取原始数值(Google Apps Script场景)
问题分析与解决方案
问题根源在于你调用IMPORTXLSX时未传入range参数,代码会执行sheet_to_csv分支逻辑。而SheetJS的sheet_to_csv默认输出的是单元格格式化后的显示值(对应单元格对象的w字段),而非原始的高精度数值(v字段),因此你拿到的是四舍五入后的0.80,而非原始的0,797698。
下面是两种可行的修复方案:
方案1:修改CSV导出配置
给sheet_to_csv添加raw: true参数,强制导出原始值而非格式化内容:
function IMPORTXLSX(url, sheetName, range) { const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }); if (res.getResponseCode() != 200) { throw new Error("XLSX file cannot be obtained. Please confirm the link again."); } const book = XLSX.read(new Uint8Array(res.getContent()), { type: "array" }); const worksheet = book.Sheets[sheetName]; if (!range) { // 添加raw: true参数,导出原始值 const csv = XLSX.utils.sheet_to_csv(worksheet, { raw: true }); const values = Utilities.parseCsv(csv); return values; } var rng = XLSX.utils.decode_range(range); const values = []; for (let row = rng.s.r; row <= rng.e.r; row++) { const temp = []; for (let col = rng.s.c; col <= rng.e.c; col++) { const v = XLSX.utils.encode_cell({ r: row, c: col }); temp.push(worksheet[v] ? worksheet[v].v : null); } values.push(temp); } return values; }
方案2:替换CSV分支为单元格遍历逻辑(更可靠)
如果担心CSV解析因小数点分隔符出现问题,可以直接遍历整个工作表的单元格,和指定range时的逻辑保持一致:
function IMPORTXLSX(url, sheetName, range) { const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }); if (res.getResponseCode() != 200) { throw new Error("XLSX file cannot be obtained. Please confirm the link again."); } const book = XLSX.read(new Uint8Array(res.getContent()), { type: "array" }); const worksheet = book.Sheets[sheetName]; if (!range) { // 获取整个工作表的有效范围 const rng = XLSX.utils.decode_range(worksheet['!ref']); const values = []; for (let row = rng.s.r; row <= rng.e.r; row++) { const temp = []; for (let col = rng.s.c; col <= rng.e.c; col++) { const cellAddr = XLSX.utils.encode_cell({ r: row, c: col }); const cell = worksheet[cellAddr]; // 直接获取原始值v,保留完整精度 temp.push(cell ? cell.v : null); } values.push(temp); } return values; } var rng = XLSX.utils.decode_range(range); const values = []; for (let row = rng.s.r; row <= rng.e.r; row++) { const temp = []; for (let col = rng.s.c; col <= rng.e.c; col++) { const v = XLSX.utils.encode_cell({ r: row, c: col }); temp.push(worksheet[v] ? worksheet[v].v : null); } values.push(temp); } return values; }
额外处理:文本类型的逗号小数点
如果原文件中单元格是文本格式存储的"0,797698"(而非数值类型),可以在取值时替换逗号为小数点,转为数值:
// 替换方案2中temp.push的逻辑 temp.push(cell ? (typeof cell.v === 'string' && cell.v.includes(',') ? parseFloat(cell.v.replace(',', '.')) : cell.v) : null);
内容的提问来源于stack exchange,提问作者I_am_not_a_programmer
相关产品推荐
相关产品推荐

