You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JS中Excel转JSON的局部变量inputData移至全局以跨文件导入

解决方案

因为inputData是在异步回调(fileReader.onload)里生成的,没法直接同步拿到顶级作用域再导出——异步代码执行时机晚于顶级作用域代码,直接移到顶级的话初始值是undefined,后续赋值也不会自动通知其他模块。下面给几个实用的解决思路:

方案1:导出Promise对象

把数据的获取逻辑包装成Promise,其他模块通过then或await拿到异步生成的inputData:

let selectedFile;
// 顶级作用域定义Promise用于导出
export const inputDataPromise = new Promise((resolve) => {
    document.getElementById('button').addEventListener('click', () => {
        if (selectedFile) {
            const fileReader = new FileReader();
            fileReader.readAsBinaryString(selectedFile);
            fileReader.onload = (event) => {
                const data = event.target.result;
                const workbook = XLSX.read(data, { type: "binary" });
                const rowObject = XLSX.utils.sheet_to_row_object_array(workbook.Sheets.Grid);
                const newData = rowObject.filter((item, index) => {
                    return index === rowObject.findIndex((obj) => {
                        return JSON.stringify(item) === JSON.stringify(obj);
                    });
                });

                newData.pop();
                const inputData = JSON.stringify(newData, undefined, 4);
                console.log(inputData);
                // 异步完成后传递数据
                resolve(inputData);
            };
        }
    });
});

document.getElementById('input').addEventListener('change', (event) => {
    selectedFile = event.target.files[0];
});

其他文件使用:

import { inputDataPromise } from './你的文件名.js';

// 用await(需要在async函数里)
async function useData() {
    const inputData = await inputDataPromise;
    // 在这里处理inputData
    console.log(inputData);
}

// 或者用then
inputDataPromise.then(inputData => {
    console.log(inputData);
});

方案2:导出顶级变量+自定义事件通知

在顶级作用域定义inputData变量导出,同时通过自定义事件通知其他模块数据已准备好:

let selectedFile;
// 顶级变量,初始为null
export let inputData = null;

// 导出监听函数,方便其他模块等待数据
export function listenInputDataReady(callback) {
    // 如果数据已存在,直接回调
    if (inputData) {
        callback(inputData);
        return;
    }
    // 否则监听自定义事件
    document.addEventListener('inputDataReady', (e) => {
        callback(e.detail);
    });
}

document.getElementById('input').addEventListener('change', (event) => {
    selectedFile = event.target.files[0];
});

document.getElementById('button').addEventListener('click', () => {
    if (selectedFile) {
        const fileReader = new FileReader();
        fileReader.readAsBinaryString(selectedFile);
        fileReader.onload = (event) => {
            const data = event.target.result;
            const workbook = XLSX.read(data, { type: "binary" });
            const rowObject = XLSX.utils.sheet_to_row_object_array(workbook.Sheets.Grid);
            const newData = rowObject.filter((item, index) => {
                return index === rowObject.findIndex((obj) => {
                    return JSON.stringify(item) === JSON.stringify(obj);
                });
            });

            newData.pop();
            inputData = JSON.stringify(newData, undefined, 4);
            console.log(inputData);
            // 触发事件通知其他模块
            document.dispatchEvent(new CustomEvent('inputDataReady', { detail: inputData }));
        };
    }
});

其他文件使用:

import { inputData, listenInputDataReady } from './你的文件名.js';

// 检查数据是否已存在
if (inputData) {
    handleData(inputData);
} else {
    // 等待数据准备好
    listenInputDataReady((data) => {
        handleData(data);
    });
}

方案3:导出异步获取函数

把读取Excel并生成inputData的逻辑封装成异步函数,其他模块需要时主动调用:

let selectedFile;

document.getElementById('input').addEventListener('change', (event) => {
    selectedFile = event.target.files[0];
});

// 导出异步函数
export async function getProcessedInputData() {
    return new Promise((resolve, reject) => {
        if (!selectedFile) {
            reject(new Error('请先选择文件'));
            return;
        }
        const fileReader = new FileReader();
        fileReader.readAsBinaryString(selectedFile);
        fileReader.onload = (event) => {
            const data = event.target.result;
            const workbook = XLSX.read(data, { type: "binary" });
            const rowObject = XLSX.utils.sheet_to_row_object_array(workbook.Sheets.Grid);
            const newData = rowObject.filter((item, index) => {
                return index === rowObject.findIndex((obj) => {
                    return JSON.stringify(item) === JSON.stringify(obj);
                });
            });

            newData.pop();
            const inputData = JSON.stringify(newData, undefined, 4);
            console.log(inputData);
            resolve(inputData);
        };
        // 处理读取错误
        fileReader.onerror = (err) => {
            reject(err);
        };
    });
}

// 原按钮点击逻辑可以保留,也可以让其他模块触发
document.getElementById('button').addEventListener('click', async () => {
    try {
        await getProcessedInputData();
    } catch (err) {
        console.error('处理失败:', err);
    }
});

其他文件使用:

import { getProcessedInputData } from './你的文件名.js';

// 比如在某个按钮点击时获取数据
document.getElementById('另一个按钮').addEventListener('click', async () => {
    try {
        const inputData = await getProcessedInputData();
        handleData(inputData);
    } catch (err) {
        alert(err.message);
    }
});

内容的提问来源于stack exchange,提问作者Mwewol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 23:00:13