首页 > 解决方案 > 谷歌脚本只导入少数带有脚本的列

问题描述

有一个包含很多列和原始的 CSV 文件但是,我只想导入一些列,我在下面的网络上找到的链接中使用了这个脚本。它可以工作,但它会导入包含所有列和行的完整文件。我只需要导入几列而不是全部。例如:第 1 列、第 5 列、第 20 列有人可以帮助我吗?

https://bionicteaching.com/importing-csv-into-google-sheets-via-google-script/comment-page-1/

标签: google-apps-scriptgoogle-sheetsimportmultiple-columns

解决方案


我相信你的目标如下。

  • 您想从 URL 检索 CSV 数据。
  • 您想通过检索特定列将 CSV 数据放入 Google 电子表格。
  • 您想使用 Google Apps 脚本实现此目的。
    • 当我看到https://bionicteaching.com/importing-csv-into-google-sheets-via-google-script/comment-page-1/您问题中的 URL 时,我了解到该脚本是 Google Apps 脚本。
  • 您正在使用https://bionicteaching.com/importing-csv-into-google-sheets-via-google-script/comment-page-1/.

修改点:

  • 在当前阶段,Utilities.parseCsv()可用于将 CSV 数据解析为数组。使用此方法时,CSV 数据可以解析为二维数组。我认为这也许可以使用。
  • 为了检索特定的列,我认为可以从 CSV 数据解析的数组中检索。

当以上几点反映到脚本中时,它变成如下。

示例脚本:

请将以下脚本复制并粘贴到 Google 电子表格的脚本编辑器中。并且,请设置变量,然后运行myFunction​​. 这样,检索特定列的 CSV 数据将被放入活动工作表中。

function myFunction() {
  // 1. Set the required columns as the column number.
  const requiredColumns = [1, 5, 20]; // Please set the required columns. These values are from your question.

  // 2. Retrieve CSV data from an URL.
  const url = '###'; // Please set the direct link of CSV data.
  const res = UrlFetchApp.fetch(url);

  // 3. Parse CSV data.
  const ar = Utilities.parseCsv(res.getContentText());

  // 4. Retrieve the required columns from the CSV data.
  const values = ar.map(r => requiredColumns.map(i => r[i]));

  // 5. Put the values to the active sheet.
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
  • 如果您的 CSV 数据使用特定分隔符,请修改const ar = Utilities.parseCsv(res.getContentText());const ar = Utilities.parseCsv(res.getContentText(), "delimiter");. 参考

笔记:

  • 当您想将脚本作为自定义函数运行时,您还可以使用以下脚本。在这种情况下,请放到=SAMPLE("URL","1,5,20")一个单元格中。这样,检索特定列的 CSV 数据就会被放入。

      function SAMPLE(url, columns) {
        const requiredColumns = columns.split(",");
        const res = UrlFetchApp.fetch(url);
        return Utilities.parseCsv(res.getContentText()).map(r => requiredColumns.map(i => r[i.trim()]));
      }
    

参考:

添加1:

从您提供的示例 CSV 数据中,我可以了解问题的原因。我认为在这种情况下,对于上述方法,CSV 数据的大小可能会很大。这样,我认为可能会发生这样的错误。当我检查 CSV 数据时,发现它有 4,763,515 个单元格,42,155 行和 113 列。因此,为了消除这个问题,我想提出如下第二个示例脚本。

在此示例中,首先使用 Drive API 将 CSV 数据转换为电子表格,并使用 Sheets API 删除除所需列之外的列,然后将工作表复制到活动电子表格中。

示例脚本:

在使用此脚本之前,请在 Advanced Google services 中启用 Drive API 和 Sheets API。由于数据量大,我使用了 Drive API 和 Sheets API。

function myFunction2() {
  // 1. Set the required columns as the column number.
  const requiredColumns = [1, 5, 20]; // Please set the required columns. These values are from your question.

  // 2. Retrieve CSV data from an URL.  
  const url = "https://www.stanem.it/csv/InnovaCSV.csv";  // This is from your sample CSV data.
  const res = UrlFetchApp.fetch(url);

  // 3. Convert CSV data to Spreadsheet.
  const id = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "tempSpreadsheet"}, res.getBlob()).id;

  // 4. Delete the columns except for the required columns.
  const ss = SpreadsheetApp.openById(id);
  const sheet = ss.getSheets()[0];
  const maxColumn = sheet.getMaxColumns();
  const requests = [];  
  for (let i = 1; i <= maxColumn; i++) {
    if (!requiredColumns.includes(i)) {
      requests.push({deleteDimension: {range: {sheetId: sheet.getSheetId(), dimension: "COLUMNS", startIndex: i - 1, endIndex: i}}});
    }
  }
  Sheets.Spreadsheets.batchUpdate({requests: requests.reverse()}, id);

  // 5. Copy the sheet including CSV data to the active Spreadsheet.
  const dstss = SpreadsheetApp.getActiveSpreadsheet();
  sheet.copyTo(dstss).setName("sheetIncludingCSV");
  
  // 6. Remove the temporat Spreadsheet.
  DriveApp.getFileById(id).setTrashed(true);
}

添加2:

对不起这张表。copyTo(dstss); 有效,但它为我创造了很多复印纸,我只需要一张总是同名的纸

根据您的回复,我为此修改了上面的脚本。

示例脚本:

function myFunction3() {
  // 1. Set the required columns as the column number.
  const requiredColumns = [1, 5, 20]; // Please set the required columns. These values are from your question.

  // 2. Retrieve CSV data from an URL.  
  const url = "https://www.stanem.it/csv/InnovaCSV.csv";
  const res = UrlFetchApp.fetch(url);

  // 3. Convert CSV data to Spreadsheet.
  const id = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "tempSpreadsheet"}, res.getBlob()).id;

  // 4. Delete the columns except for the required columns.
  const ss = SpreadsheetApp.openById(id);
  const sheet = ss.getSheets()[0];
  const maxColumn = sheet.getMaxColumns();
  const requests = [];  
  for (let i = 1; i <= maxColumn; i++) {
    if (!requiredColumns.includes(i)) {
      requests.push({deleteDimension: {range: {sheetId: sheet.getSheetId(), dimension: "COLUMNS", startIndex: i - 1, endIndex: i}}});
    }
  }
  Sheets.Spreadsheets.batchUpdate({requests: requests.reverse()}, id);

  // 5. Copy the values of modified CSV data to a sheet in the active Spreadsheet.
  const destinationSheetName = "Sheet1";  // Please set the destilnation sheet name in the active Spreadsheet.
  const dstss = SpreadsheetApp.getActiveSpreadsheet();
  const values = Sheets.Spreadsheets.Values.get(id, sheet.getSheetName()).values;
  Sheets.Spreadsheets.Values.update({values: values}, dstss.getId(), destinationSheetName, {valueInputOption: "USER_ENTERED"});
  
  // 6. Remove the temporat Spreadsheet.
  DriveApp.getFileById(id).setTrashed(true);
}
  • 此示例脚本将修改后的 CSV 数据放到活动电子表格的特定工作表中。
  • 在这种情况下,值从第一行第一列开始。所以当你想放其他范围时,请修改脚本。

推荐阅读