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

使用JavaScript和Script Lab导出Excel表格为带引号CSV失败求助

Excel Script Lab脚本无法生成下载文件的问题排查

一年多前我在Script Lab编写了一个脚本,可将当前工作表中的所有表格导出为单独的带引号CSV文件,此前在M365 Excel桌面版运行正常,今年4月还能正常使用。运行时控制台会记录表名,文件会下载到电脑默认下载文件夹。

原脚本代码

$("#run").click(() => tryCatch(run));

async function run() {
  await Excel.run(async (context) => {

    exportAllTablesToCSV();

    console.log("Exporting all tables on current worksheet to quoted csv files.");

    await context.sync();
  });
}

/** Default helper for invoking an action and handling errors. */
async function tryCatch(callback) {
  try {
    await callback();
  } catch (error) {
    // Note: In a production add-in, you'd want to notify the user through your add-in's UI.
    console.error(error);
  }
}

// Function to export a table to a CSV file
async function exportTableToCSV(table, tableName, fileNamePrefix, fileNameSuffix) {
  return new Promise(async (resolve, reject) => {
    try {
      await Excel.run(async (context) => {
        const sheet = context.workbook.worksheets.getActiveWorksheet();
        const dataBodyRange = sheet.tables.getItem(tableName).getRange();

        dataBodyRange.load("values");

        await context.sync();

        const fileName = fileNamePrefix + String(tableName).replace(/Table_/g, "") + fileNameSuffix + ".csv";

        const csvData = dataBodyRange.values
          .map((row) => {
            const quotedRow = row.map((cell) => {
              // Quote and escape existing double quotes
              return '"' + String(cell).replace(/"/g, '""') + '"';
            });
            return quotedRow.join(",");
          })
          .join("\n");

        const blob = new Blob([csvData], { type: "text/csv" });
        const url = URL.createObjectURL(blob);

        const a = document.createElement("a");
        a.href = url;
        a.download = fileName;
        document.body.appendChild(a);
        a.click();

        // Wait for the download to complete before resolving
        // Adjust the delay as needed
        await new Promise((innerResolve) => setTimeout(innerResolve, 1000));

        console.log("Exported " + tableName + " as " + fileName);

        URL.revokeObjectURL(url);
        document.body.removeChild(a);

        resolve();
      });
    } catch (error) {
      console.log(error);
    }
  });
}

// Function to export all tables on the active worksheet to CSV
async function exportAllTablesToCSV() {
  try {
    await Excel.run(async (context) => {
      const sheet = context.workbook.worksheets.getActiveWorksheet();
      const tables = sheet.tables.load("items/name");
      const currentDate = new Date()
        .toISOString()
        .slice(0, 10)
        .replace(/-/g, "");

      const fileNamePrefix = "Pre_";
      const fileNameSuffix = "_" + currentDate;

      await context.sync();

      for (const table of tables.items) {
        const tableName = table.name;
        await exportTableToCSV(table, tableName, fileNamePrefix, fileNameSuffix);
      }
    });
  } catch (error) {
    console.log(error);
  }
}

问题现象

现在脚本运行无报错,但不会在下载文件夹生成文件,浏览器下载记录也无相关记录,且未发现文件被下载到其他位置。我已在最新版Excel桌面版、Edge/Chrome/Firefox中的Excel Online,以及多台Windows10/11设备测试,均出现此问题。我为click()事件添加监听器,确认事件已触发。

核心下载逻辑如下:

const blob = new Blob([csvData], { type: "text/csv" });
const url = URL.createObjectURL(blob);

const a = document.createElement("a");
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();

验证脚本

我搜索到不少该写法的旧参考资料,于是编写了如下验证脚本,运行同样无报错,但仍无法生成下载文件:

$("#run").on("click", () => tryCatch(run));

async function run() {
  await Excel.run(async (context) => {
    const sheet = context.workbook.worksheets.getActiveWorksheet();

    // Create a blob with some data
    const data = new Blob(["Hello, world!"], { type: "text/plain" });

    // Create a URL for the blob
    const url = URL.createObjectURL(data);

    // Create an <a> element
    const link = document.createElement("a");
    link.href = url;
    link.download = "example.txt"; // Specify the filename

    // Append the link to the document (optional, if you want to make it visible)
    document.body.appendChild(link);

    // Trigger the download
    link.click();

    console.log("link clicked");

    // Clean up by revoking the object URL after a delay
    setTimeout(() => {
      URL.revokeObjectURL(url);
      document.body.removeChild(link); // Remove the link from the document
    }, 3000);

    await context.sync();
  });
}

/** Default helper for invoking an action and handling errors. */
async function tryCatch(callback) {
  try {
    await callback();
  } catch (error) {
    // Note: In a production add-in, you'd want to notify the user through your add-in's UI.
    console.error(error);
  }
}

疑问

  1. 有人能成功运行这些脚本吗?
  2. 可能的原因是什么?是否Office.js有未公开的变更?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:40:03