CSV recebido por e-mail para tabela do Excel, sem loop
Em vez de percorrer o arquivo linha por linha, o fluxo entrega o texto inteiro do CSV a um Office Script, que grava tudo na tabela de uma vez. Menos ações, menos risco de 429 e muito mais rápido.
O problema
Toda manhã chega um e-mail com um CSV (vendas do dia, estoque, extrato) e alguém copia as linhas para uma planilha. A solução ingênua automatiza isso com um Aplicar a cada: para cada linha do CSV, uma ação Adicionar linha a uma tabela. Funciona com 20 linhas e vira um pesadelo com 5.000: cada linha é uma ação, o fluxo demora, consome o limite de ações e, no pior caso, atinge o erro 429.
A alternativa é entregar o CSV inteiro a um Office Script, um pequeno código que roda dentro do Excel na web e grava todas as linhas em lote. Para o fluxo, é uma única ação.
O que você precisa
- Uma licença Microsoft 365 empresarial com Office Scripts habilitado. Segundo a Microsoft, para usar Office Scripts no Power Automate é preciso uma licença empresarial do Microsoft 365.
- Uma pasta de trabalho do Excel salva no OneDrive for Business ou no SharePoint (não vale arquivo só no seu computador).
- Nessa pasta de trabalho, uma tabela (Inserir > Tabela) chamada
TabelaDados, com os cabeçalhos na mesma ordem das colunas do CSV.
Passo 1: crie o script
No Excel na web, abra Automatizar > Novo script > Criar no editor de código, apague o conteúdo e cole o código abaixo. Salve com o nome Gravar CSV na tabela.
function main(
workbook: ExcelScript.Workbook,
csv: string,
tableName: string = "TabelaDados"
): string {
const table = workbook.getTable(tableName);
if (!table) {
throw new Error("Tabela não encontrada: " + tableName);
}
const rows = parseCsv(csv);
if (rows.length < 2) {
return "O CSV não tem linhas de dados.";
}
const columns = table.getColumns().length;
const data = rows.slice(1).map((r) => normalize(r, columns));
// Grava em blocos de 500 linhas para ficar longe dos limites de tamanho
for (let i = 0; i < data.length; i += 500) {
table.addRows(-1, data.slice(i, i + 500));
}
return data.length + " linhas adicionadas.";
}
// ---- leitura do CSV (testada fora do Excel) ----
function normalize(row: string[], size: number): string[] {
const out = row.slice(0, size);
while (out.length < size) {
out.push("");
}
return out;
}
function parseCsv(text: string): string[][] {
const clean = text.replace(/^/, "");
const firstLine = clean.split(/\r?\n/)[0] || "";
const counts: { [key: string]: number } = { ",": 0, ";": 0, "\t": 0 };
let inQuotes = false;
for (const ch of firstLine) {
if (ch === '"') {
inQuotes = !inQuotes;
} else if (!inQuotes && ch in counts) {
counts[ch]++;
}
}
let delimiter = ",";
let best = 0;
for (const d of [",", ";", "\t"]) {
if (counts[d] > best) {
best = counts[d];
delimiter = d;
}
}
const rows: string[][] = [];
let row: string[] = [];
let value = "";
let quoted = false;
let fieldStart = true;
for (let i = 0; i < clean.length; i++) {
const c = clean[i];
if (quoted) {
if (c === '"') {
if (clean[i + 1] === '"') {
value += '"';
i++;
} else {
quoted = false;
}
} else {
value += c;
}
} else if (c === '"' && fieldStart) {
quoted = true;
fieldStart = false;
} else if (c === delimiter) {
row.push(value);
value = "";
fieldStart = true;
} else if (c === "\n" || c === "\r") {
if (c === "\r" && clean[i + 1] === "\n") {
i++;
}
row.push(value);
rows.push(row);
row = [];
value = "";
fieldStart = true;
} else {
value += c;
fieldStart = false;
}
}
row.push(value);
rows.push(row);
return rows.filter((r) => r.some((cell) => cell !== ""));
}
parseCsv e normalize) é executada por testes automatizados do Me Ajuda Flow com vírgula, ponto e vírgula, Tab, aspas, aspas escapadas, quebra de linha dentro de aspas, BOM, linhas em branco e linhas mais curtas ou mais longas que a tabela. A gravação no Excel (main) segue a documentação oficial e deve ser testada no seu ambiente.O que o script faz: lê o CSV (detecta sozinho se o separador é vírgula, ponto e vírgula ou Tab), ajusta cada linha ao número de colunas da tabela (completa com vazio ou descarta o excesso) e grava em blocos de 500 linhas.
Passo 2: monte o fluxo
- Gatilho: Office 365 Outlook, Quando um novo e-mail chegar (V3). Em Opções avançadas, deixe Somente com anexo = Sim e Incluir anexos = Sim. Filtre por remetente ou assunto, para o fluxo não disparar com qualquer e-mail.
- Filtrar matriz (para ignorar imagens de assinatura e outros anexos): em De, use
triggerOutputs()?['body/attachments']e, na condição avançada,endsWith(item()?['name'], '.csv'). Renomeie a ação paraFiltrar_anexos. - Executar script (Excel Online (Business)): escolha o arquivo pelo seletor, o script
Gravar CSV na tabelae preencha os parâmetros. Emcsv, use a expressão:base64ToString(first(body('Filtrar_anexos'))?['contentBytes'])EmtableName, escrevaTabelaDados. - Opcional: um e-mail ou uma mensagem no Teams confirmando, com o texto que o script devolve (
quantas linhas foram adicionadas).
assinatura.png e Vendas.CSV). O Filtrar matriz devolveu só o Vendas.CSV (o endsWith não diferencia .CSV de .csv), e base64ToString(first(body('Filtrar_anexos'))?['contentBytes']) devolveu o texto nome;valor e Ana;1,5, com a quebra de linha. A gravação no Excel pelo script não foi executada nesse teste.Limites que você precisa conhecer
| Limite | Valor |
|---|---|
| Tamanho de requisição e resposta do Excel | 5 MB |
| Tamanho máximo dos parâmetros da ação Executar script | 30.000.000 bytes |
| Tempo máximo de uma operação síncrona do Power Automate | 120 segundos |
| Chamadas da ação Executar script por usuário | 1.600 por dia (zera às 00:00 UTC) |
Chamadas externas (fetch) dentro do script | Não funcionam no Power Automate |
Para CSV muito grande, divida o arquivo ou chame o script mais de uma vez com partes menores. O script já grava em blocos para não estourar o limite de tamanho em uma única gravação.
Armadilhas
- Excel interpretando valores: textos que parecem número ou data (como
007ou01/02) podem ser convertidos ao serem gravados. Se precisar preservar zeros à esquerda, formate a coluna como Texto antes. - Tabela não encontrada: o nome do segundo parâmetro precisa ser exatamente o da tabela (Design da tabela > Nome da tabela).
- Parâmetros novos não aparecem na ação: se você mudou o script depois de adicionar a ação, o Power Automate guarda a assinatura antiga. Remova a ação e adicione de novo.
- Vários CSV no mesmo e-mail: este fluxo pega o primeiro. Para vários, será preciso repetir a ação para cada anexo.
- Dados duplicados: se o mesmo e-mail disparar o fluxo duas vezes, as linhas entram duas vezes. Se isso for um risco, grave uma coluna com o identificador do arquivo e confira antes.
Como testar antes de confiar
- Envie para você mesmo um CSV pequeno (3 linhas), com acentos e uma célula com vírgula entre aspas.
- Abra a execução no histórico e confira a saída da ação Executar script: deve dizer "3 linhas adicionadas".
- Abra a tabela no Excel e confira acentos, colunas e valores.
- Só então teste com um arquivo real, e depois com um grande.
Ferramentas para usar com este guia
Fontes oficiais
- Run Office Scripts with Power Automate (Microsoft Learn)
- Platform limits and requirements with Office Scripts (Microsoft Learn)
- Sample: Convert CSV files to Excel workbooks (Microsoft Learn)
- Sample: Write a large dataset (Microsoft Learn)
- Troubleshoot Office Scripts running in Power Automate (Microsoft Learn)