Text Editing & Formatting

Cells to Commas

Convert selected spreadsheet cells to CSV, keeping rows and columns.

OfficialOn-device

Download action

What Cells to Commas does

Converts cells from Google Sheets, Excel, or other tab-separated text to CSV. Separates columns with commas and keeps each spreadsheet row on its own line, preserving empty cells within the data and blank rows. Omits completely empty trailing columns. Quotes values containing commas, quotes, or line breaks. Copy the result or use Add to note.

CategoryText Editing & Formatting
Action typeJavaScript
Default resultCopy the result
InternetNot required

Action and outcome

Cells to Commas example
ActionOutcome
Cells to CommasSelected text: Apple Banana Pear OrangeApple,Banana Pear,Orange

Use Cells to Commas

Follow these steps to convert selected spreadsheet cells to CSV, keeping rows and columns with ActionClip.

  1. Select the text you want to use.
  2. Choose Cells to Commas from ActionClip.
  3. Review the extracted result, then copy it where you need it.

Requirements and privacy

  • Before you start: No setup required.
  • Your selected text: Runs locally in ActionClip’s JavaScript sandbox. Selected text does not leave your Mac.

Action script

The script below is included so you can inspect how the action works before downloading it.

JavaScript definition
function run(selected_text) {
  const rows = [];
  let row = [];
  let cell = "";
  let quoted = false;
  let closedQuote = false;
  let atStart = true;
  const isSeparator = (character) => /[\t\r\n\u000B\u000C\u0085\u2028\u2029]/.test(character);
  const finishCell = () => {
    row.push(cell);
    cell = "";
    closedQuote = false;
    atStart = true;
  };

  for (let index = 0; index < selected_text.length; index += 1) {
    const character = selected_text[index];
    if (quoted) {
      if (character === '"') {
        if (selected_text[index + 1] === '"') {
          cell += '"';
          index += 1;
        } else {
          quoted = false;
          closedQuote = true;
        }
      } else {
        cell += character;
      }
    } else if (isSeparator(character)) {
      finishCell();
      if (character !== "\t") {
        rows.push(row);
        row = [];
      }
      if (character === "\r" && selected_text[index + 1] === "\n") index += 1;
    } else if (closedQuote) {
      throw new Error("Invalid quoted cell. Copy the cell range again and retry.");
    } else if (atStart && character === '"') {
      quoted = true;
      atStart = false;
    } else {
      cell += character;
      atStart = false;
    }
  }
  if (quoted) throw new Error("Incomplete quoted cell. Copy the cell range again and retry.");
  finishCell();

  rows.push(row);
  // Drop only columns that are empty in every selected row.
  let width = rows.reduce((maximum, values) => Math.max(maximum, values.length), 0);
  while (width > 0 && rows.every((values) => (values[width - 1] || "") === "")) width -= 1;
  return rows.map((values) => values.slice(0, width).map((value) =>
    /[,"\t\r\n\u000B\u000C\u0085\u2028\u2029]/.test(value) || value !== value.trim()
      ? '"' + value.replace(/"/g, '""') + '"'
      : value
  ).join(",")).join("\n");
}