Lendo e escrevendo arquivos CSV com PHP
E ai, galera, beleza?
As vezes precisamos ler ou escrever um arquivo em formato CSV. O que seria uma tarefa simples pode tomar boa parte do seu dia. Para solucionar esse problema de forma simples, eu recomendo utilizar a biblioteca League\Csv.
Instalação
Sua instalação é simples, basta executar o seguinte comando para baixá-la usando o Composer:
composer require league/csv
Caso não esteja utilizando algum framework que carregue automaticamente as classes, deve importar o arquivo autoload:
<?php
require 'vendor/autoload.php';
Ler Arquivo
Como exemplo, irei usar o seguinte conteúdo de uma arquivo CSV:
Nome,Sobrenome,E-mail
van,neves,van@gmail.com
maria,souza,maria@gmail.com
paulo,silva,paulo@hotmail.com
Agora vamos ler as linhas desse arquivo que coloquei como exemplo:
<?php
use League\Csv\Reader;
$leitor = Reader::createFromPath('/caminho/para/arquivo.csv', 'r');
$linhas = $leitor->getRecords();
foreach ($linhas as $numero => $linha) {
echo $linha[0];
}
No exemplo acima estamos pegando todas as linhas do arquivo, percorrendo-as e imprimindo o valor da primeira coluna, que no caso é o "Nome".
Uma coisa que acho interessante, principalmente quando estamos trabalhando com muitas colunas, é definir nomes para que a programação fique mais clara. Ao invés de usar $linha[0]
ou $linha[1]
, podemos definir um índice de texto. Para isso, bastaria substituir o código da linha 6 pelo seguinte código:
<?php
$linhas = $leitor->getRecords(['nome', 'sobrenome', 'email']);
Dessa maneira bastaria acessarmos as colunas pelos menos que definimos, como $linha['nome']
. Mas com essa biblioteca podemos ir além e fazer coisas mais interessantes. Imagine um arquivo CSV com mais de 100 e você deseja filtra, ordenar ou retornar fazer uma paginação. Então vamos lá:
<?php
use League\Csv\Reader;
use League\Csv\Statement;
function filtrarPorEmail(array $linha)
{
// verifica se a coluna é realmente um e-mail
return (bool) filter_var($linha[2], FILTER_VALIDATE_EMAIL);
}
function ordernarPorSobrenome(array $linhaA, array $linhaB)
{
// ordenando pela coluna 1 (sobrenome)
return strcmp($linhaB[1], $linhaA[1]);
}
$leitor = Reader::createFromPath('/caminho/para/arquivo.csv', 'r');
$stmt = (new Statement())
->where('filtrarPorEmail') // filtro
->orderBy('ordernarPorSobrenome') // ordenação
->offset(3) // pular os 3 primeiros resultados
->limit(10) // retornar apenas 10 linhas
;
$linhas = $stmt->process($leitor);
No exemplo acima o código está lendo um arquivo CSV, filtrando pela coluna 2 (verifica se é um e-mail válido), orderna pelo sobrenome, pula as 3 primeiras linhas e retorna as próximas 10 linhas.
Escrever em Arquivo
Caso precise criar um arquivo em formato CSV, também é muito fácil. Veja o exemplo abaixo:
<?php
use League\Csv\Writer;
$linhas = [
['van','neves','van@gmail.com','+556392621234'],
['paulo','souza','paulo@hotmail.com','+556384082020'],
['fabio','maciel','fabio@gmail.com','+556399887766'],
];
$escritor = Writer::createFromPath('/caminho/para/salvar/arquivo.csv', 'w+');
$escritor->insertAll($linhas);
O código acima está pegando um array, com um array dentro, e inserindo no arquivo CSV. Você pode inserir também somente uma linha, para isso pode usar o seguinte método:
<?php
$escritor->insertOne(['maria', 'nunes', 'maria@nunes.com.br', '+556399876543']);
O codigo recebe um array acima insere e uma linha no final do arquivo. A diferença dele para o outro é que não precisa passar um array bidimensional para inserir apenas uma linha.
A biblioteca oferece bem mais recursos, como converter o array em arquivos XML e tabelas HTML. Além disso você pode ver mais detalhes e mais métodos das funcionalidades apresentadas aqui, basta acessar o site oficial com a documentação.