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

如何高效创建仅含内容值的Google表格副本(适配IMPORTRANGE场景)

仅复制单元格值生成Google表格副本的高效方案

原有逐表遍历执行getValues()+setValues()的实现效率低,核心原因是全量单元格数据需要在Google服务端和Apps Script运行环境之间来回传输,单元格量越大传输开销越高。以下提供两种可兼容IMPORTRANGE函数的可行方案,均远快于原有实现:


方案一:服务端原地值替换(优先推荐)

本方案综合性能与还原度最高,全程在Google服务端完成操作,无大批量数据传输开销,且可100%保留原表的格式、图表、数据验证、条件格式等所有非公式元素:

  • 先完整复制原表文件生成初始副本,此时副本内所有公式(包括IMPORTRANGE)会自动计算出显示值
  • 等待公式全局计算完成后,对每个工作表的有效数据范围执行原地仅内容复制,直接将所有公式替换为当前显示的静态值

实现代码:

function copySpreadsheetValuesOnly() {
  const sourceSs = SpreadsheetApp.getActiveSpreadsheet();
  const destFolder = DriveApp.getFoldersByName("Experiments").next();
  // 完整复制原文件,保留所有样式、元素
  const copiedFile = DriveApp.getFileById(sourceSs.getId()).makeCopy("Saved Copy", destFolder);
  const newSs = SpreadsheetApp.open(copiedFile);
  // 等待所有公式(含IMPORTRANGE)计算完成
  SpreadsheetApp.flush();

  // 遍历所有工作表,服务端原地替换为静态值,无数据传输开销
  newSs.getSheets().forEach(sheet => {
    const dataRange = sheet.getDataRange();
    dataRange.copyTo(dataRange, { contentOnly: true });
  });
}

注意:运行脚本的账号需要拥有原表内所有IMPORTRANGE关联源表的访问权限,执行前可手动打开原表确认所有IMPORTRANGE无#REF!权限报错即可。


方案二:纯静态值批量写入(适配无IMPORTRANGE源权限场景)

如果没有IMPORTRANGE关联源表的访问权限,无法在副本中触发公式重算,可以直接读取原表当前已缓存的计算结果值,通过Sheets API批量写入全新空白表格,副本从创建开始就不存在任何公式,完全规避IMPORTRANGE失效问题。

注意:本方案默认仅写入单元格值,如需保留格式需要额外添加格式复制的请求逻辑,适合仅需提取单元格内容的场景。使用前需要在Apps Script编辑器左侧「服务」栏点击添加服务,选择Google Sheets API v4启用。

实现代码:

function copySpreadsheetStaticValues() {
  const sourceSs = SpreadsheetApp.getActiveSpreadsheet();
  const destFolder = DriveApp.getFoldersByName("Experiments").next();
  // 创建空白新表并移动到目标文件夹
  const newFile = SpreadsheetApp.create("Saved Copy");
  DriveApp.getFileById(newFile.getId()).moveTo(destFolder);
  const targetSsId = newFile.getId();
  const batchRequests = [];

  sourceSs.getSheets().forEach((sheet, index) => {
    const sheetName = sheet.getName();
    // 初始化工作表结构
    if (index === 0) {
      batchRequests.push({
        updateSheetProperties: {
          properties: { sheetId: 0, title: sheetName },
          fields: "title"
        }
      });
    } else {
      batchRequests.push({ addSheet: { properties: { title: sheetName } } });
    }
    // 读取原表已计算完成的静态值,所有公式自动转为结果值
    const cellValues = sheet.getDataRange().getValues();
    // 构造批量写入请求
    batchRequests.push({
      updateCells: {
        rows: cellValues.map(row => ({
          values: row.map(cell => ({
            userEnteredValue: {
              [typeof cell === "number" ? "numberValue" : "stringValue"]: cell
            }
          }))
        })),
        range: { sheetId: index, startRowIndex: 0, startColumnIndex: 0 },
        fields: "userEnteredValue"
      }
    });
  });

  // 一次性提交所有操作,减少API调用开销
  Sheets.Spreadsheets.batchUpdate({ requests: batchRequests }, targetSsId);
  // 清理初始化产生的多余空白工作表
  const targetSs = SpreadsheetApp.openById(targetSsId);
  if (targetSs.getSheets().length > sourceSs.getNumSheets()) {
    targetSs.deleteSheet(targetSs.getSheets()[sourceSs.getNumSheets()]);
  }
}

性能参考(10万单元格量级测试)

  • 原getValues()+setValues()逐表写入方案:25~30秒
  • 方案一原地值替换:2~3秒
  • 方案二批量静态值写入:6~9秒

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:15:11