Exportar dados do WordPress nem sempre exige um plugin. Se precisa de posts, utilizadores, submissões de formulários ou encomendas WooCommerce numa folha de cálculo, o método certo depende do tamanho do conjunto, de quem consome o ficheiro e de com que frequência o trabalho corre.
Use CSV simples na maioria das exportações, faça stream com fputcsv() para downloads no browser, processe em lotes com WP_Query e passe para WP-CLI quando um pedido de admin bater nos limites de memória ou timeout. Recorra à REST API quando outro sistema precisa de dados estruturados em vez de um ficheiro.
Como exportar dados do WordPress para Excel
Três abordagens cobrem quase todos os trabalhos de exportação no WordPress:
- PHP dentro do WordPress para downloads no admin com verificação de capacidades
- WP-CLI para conjuntos grandes e trabalhos agendados no servidor
- REST API para dashboards, warehouses, CRMs e consumidores headless
Exportações ocasionais e pequenas cabem bem num download PHP. Tabelas recorrentes ou muito grandes pertencem à CLI. Sistemas externos devem puxar JSON via REST e moldar o CSV fora do WordPress quando ainda precisarem de uma folha.
Combine o método com o modo de falha. Downloads no browser falham por timeout. Plugins falham quando tentam construir um objeto de folha inteiro num único pedido. Dumps SQL ad hoc falham quando os nomes das colunas mudam após uma atualização de plugin. Escolha o caminho que mantém a exportação reproduzível no mês seguinte, não só hoje.
Numa loja portuguesa a enviar relatórios financeiros por email, o padrão que mais vezes salvou o pedido foi WP-CLI à noite e CSV diurno só para amostras. Precisa de um exportador ligado ao seu stack? Fale com um programador WordPress que já tenha enviado exportações em produção, ou contacte-nos.
O que exporta Ferramentas > Exportar no WordPress
O WordPress traz um exportador no núcleo, mas não gera uma folha de cálculo. Segundo a documentação do ecrã Ferramentas > Exportar, o ficheiro descarregado é um XML no formato WordPress eXtended RSS (WXR) com artigos, páginas, tipos de conteúdo personalizados, comentários, campos personalizados, categorias, etiquetas, taxonomias personalizadas e utilizadores. Ao escolher artigos ou páginas, pode filtrar por categoria, autor, intervalo de datas e estado.
Esse ficheiro destina-se a Ferramentas > Importar > WordPress noutra instalação. O Excel consegue abrir o XML, mas cada entrada arrasta o HTML completo do conteúdo, os metadados e os comentários, por isso como folha de cálculo serve de pouco. Use WXR para migrações e cópias de conteúdo. Use CSV quando uma pessoa tem de filtrar, somar ou cruzar colunas.
O mesmo WXR sai do servidor com wp export. Aceita filtros como --post_type, --start_date e --end_date (formato AAAA-MM-DD), --post_status e --author, corta os ficheiros em 15 MB por omissão (--max_file_size, com -1 para não limitar) e, com --stdout, escreve o XML na saída padrão:
wp export --dir=/tmp/exports/ --post_type=post --start_date=2026-01-01 --end_date=2026-06-30CSV ou XLSX para exportar dados do WordPress
Comece por CSV a menos que um stakeholder tenha um requisito rígido de .xlsx.
Pontos fortes do CSV
- Fácil de gerar com PHP ou WP-CLI
- Fácil de inspecionar e depurar num editor de texto
- Abre no Excel, Numbers e Google Sheets
- Evita bibliotecas XLSX e o custo de memória delas
Compromissos do XLSX
- Formato binário com folhas, estilos e strings partilhadas
- Precisa de uma biblioteca como PhpSpreadsheet ou de um passo de conversão pós-exportação
- Constrói mais estado em memória antes do ficheiro estar completo
- Mais difícil de fazer stream com segurança durante um pedido HTTP longo
Padrão prático: exporte CSV a partir do WordPress e converta depois com Excel, LibreOffice ou um script offline pequeno se alguém insistir em XLSX. Assim o pedido WordPress mantém-se leve.
Dica Excel: ficheiros CSV em UTF-8 por vezes precisam de um BOM (\xEF\xBB\xBF) para o Excel no Windows abrir corretamente acentos e cedilhas. O suporte da Microsoft confirma-o: um CSV em UTF-8 gravado com BOM abre normalmente com duplo clique. Sem BOM, o caminho documentado é Dados > Obter Dados > De Ficheiro > De Texto/CSV, que deixa escolher a codificação antes de carregar. Escreva o BOM antes da linha de cabeçalho quando o público vive no Excel, e omita-o quando o ficheiro alimenta outro script, porque muitos parsers leem esses três bytes como parte do nome da primeira coluna.
Exportar utilizadores WordPress para CSV com PHP
Em ferramentas de admin personalizadas, faça stream do CSV para o browser. As verificações de capacidade e de nonce vêm primeiro. Depois defina cabeçalhos, abra php://output, escreva a linha de cabeçalho e faça stream das linhas de dados por páginas.
add_action( 'admin_post_wppoland_export_users', 'wppoland_export_users_csv' );
function wppoland_export_users_csv() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Acesso negado.' );
}
check_admin_referer( 'wppoland_export_users' );
header( 'Content-Type: text/csv; charset=utf-8' );
header( 'Content-Disposition: attachment; filename=users-export.csv' );
$output = fopen( 'php://output', 'w' );
// BOM opcional para Excel no Windows:
// fwrite( $output, "\xEF\xBB\xBF" );
fputcsv( $output, array( 'ID', 'Email', 'Registered' ), ',', '"', '' );
$page = 1;
do {
$users = get_users(
array(
'fields' => array( 'ID', 'user_email', 'user_registered' ),
'number' => 500,
'paged' => $page,
'orderby' => 'ID',
'order' => 'ASC',
)
);
foreach ( $users as $user ) {
fputcsv(
$output,
array( $user->ID, $user->user_email, $user->user_registered ),
',',
'"',
''
);
}
$page++;
} while ( count( $users ) === 500 );
fclose( $output );
exit;
}Este padrão funciona para exportações mais pequenas e ferramentas internas de admin. Não reúna todas as linhas num array PHP gigante para depois fazer implode. Faça stream de cada linha à medida que a obtém. Uma única chamada a get_users() com number => 500 devolveria só os primeiros 500 utilizadores; o ciclo com paged percorre o resto em páginas do mesmo tamanho.
Proteja o endpoint com nonce e verificação de capacidade. O formulário que lança o download tem de incluir wp_nonce_field( 'wppoland_export_users' ) para que check_admin_referer() o valide. Exportações de utilizadores e encomendas costumam conter dados pessoais, por isso trate-as como qualquer outra ação privilegiada de admin sob regras no espírito do RGPD: registe quem correu a exportação e mantenha o ficheiro fora de URLs públicas.
fputcsv no PHP 8.4 e o parâmetro escape
Os exemplos deste guia passam cinco argumentos a fputcsv(), e isso é intencional. O manual do PHP indica que, a partir do PHP 8.4.0, depender do valor por omissão de escape está obsoleto: tem de ser passado explicitamente, por posição ou como argumento nomeado. Uma exportação que corre em cada cron encheria o log com avisos de deprecação.
O mesmo manual explica que qualquer escape diferente da string vazia pode produzir CSV que não cumpre o RFC 4180 ou que não sobrevive a uma ida e volta pelas funções CSV do PHP. O valor por omissão é a barra invertida, e a recomendação é defini-lo como "". Por isso todas as chamadas usam ',', '"', ''. O manual avisa ainda que o valor por omissão vai mudar numa versão futura, não antes do PHP 9.0, por isso fixá-lo hoje evita que a saída mude sozinha depois de uma atualização do servidor.
Exportar muitos dados do WordPress sem erros de memória
O modo de falha habitual é carregar demasiado de uma vez. Limites de memória PHP, max_execution_time e timeouts de reverse proxy matam exportações longas no admin. Processe em lotes com WP_Query usando posts_per_page e offset, ou, melhor, pagine com um cursor estável quando o offset fica caro em tabelas grandes.
// $output é o stream aberto como no exemplo de utilizadores.
$offset = 0;
$limit = 500;
do {
$query = new WP_Query(
array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => $limit,
'offset' => $offset,
'orderby' => 'ID',
'order' => 'ASC',
'fields' => 'ids',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
)
);
foreach ( $query->posts as $post_id ) {
fputcsv( $output, array( $post_id, get_the_title( $post_id ) ), ',', '"', '' );
}
$offset += $limit;
wp_cache_flush_runtime(); // WP 6.0+: limpa só a cache em memória deste pedido
} while ( count( $query->posts ) === $limit );Porque isto ajuda:
fields => 'ids'mantém a hidratação de objetos leve- Desativar caches de meta e termos impede o object cache de crescer sem limite
- Tamanhos de lote fixos mantêm o pico de memória perto de uma página de linhas
- Stream com
fputcsv()evita guardar a string CSV completa em RAM - Ordenar por
IDascendente impede que um artigo publicado a meio da exportação desloque as páginas e duplique ou salte linhas
Use wp_cache_flush_runtime() e não wp_cache_flush() dentro do ciclo. Com um object cache persistente (Redis ou Memcached), wp_cache_flush() esvazia a cache do site inteiro a meio da exportação. A função runtime, disponível desde o WordPress 6.0, limpa apenas a memória do pedido atual e, se o drop-in não a suportar, devolve false sem tocar na cache partilhada.
Em tabelas muito grandes, o próprio offset fica lento porque o MySQL ainda percorre as linhas descartadas. Prefira keyset pagination: WHERE ID > last_id ORDER BY ID ASC LIMIT N. Em trabalhos CLI, esse padrão vale o código extra.
Referência oficial dos argumentos de consulta: a classe WP_Query em developer.wordpress.org.
Exportar posts WordPress para CSV com WP-CLI
Quando exporta dezenas de milhares de linhas, o WP-CLI evita o browser e a cadeia de timeouts do servidor web.
wp post list --post_type=post --fields=ID,post_title,post_date --format=csv > posts.csvÚtil para:
- catálogos grandes de posts ou produtos
- dumps de encomendas WooCommerce que dariam timeout no wp-admin
- exportações noturnas via cron para object storage ou uma pasta partilhada
- entregas de migração e reporting
Documentação do comando: wp post list. Aceita --format=csv, json, yaml, ids, count ou table, e qualquer argumento de WP_Query na forma --<campo>=<valor>. Há um detalhe que pesa em sites grandes: --posts_per_page vale -1 por omissão, ou seja, todos os artigos numa única consulta. Se a tabela for enorme, pagine com --posts_per_page=1000 --paged=N num ciclo de shell.
Para utilizadores existe o comando equivalente wp user list, com os campos por omissão ID, user_login, display_name, user_email, user_registered e roles:
wp user list --role=customer --fields=ID,user_email,user_registered --format=csv > clientes.csvTodos os comandos aceitam o parâmetro global --ssh=utilizador@host/caminho, que corre a exportação contra um servidor remoto a partir da sua máquina sem abrir uma sessão à parte.
Também pode escrever um comando WP-CLI personalizado que abre um ficheiro, pagina com WC_Order_Query ou WP_Query e escreve CSV em disco. Isso mantém a memória previsível e permite retomar a partir de um checkpoint se o trabalho for interrompido:
WP_CLI::add_command( 'wppoland export-orders', function ( $args, $assoc_args ) {
$file = fopen( 'orders.csv', 'w' );
fputcsv( $file, array( 'order_id', 'date_created', 'status', 'total', 'billing_email' ), ',', '"', '' );
$page = 1;
do {
$orders = wc_get_orders(
array(
'type' => 'shop_order',
'limit' => 200,
'paged' => $page,
'orderby' => 'ID',
'order' => 'ASC',
)
);
foreach ( $orders as $order ) {
$created = $order->get_date_created();
fputcsv(
$file,
array(
$order->get_id(),
$created ? $created->date( 'c' ) : '',
$order->get_status(),
$order->get_total(),
$order->get_billing_email(),
),
',',
'"',
''
);
}
$page++;
} while ( count( $orders ) === 200 );
fclose( $file );
WP_CLI::success( 'Exported to orders.csv' );
} );limit e paged são parâmetros documentados de wc_get_orders(). Com limit => -1, o comando carregaria todas as encomendas em memória antes de escrever a primeira linha, exatamente o que o lote evita.
Exportar a base de dados completa com wp db export
Por vezes o pedido não é uma folha, mas uma cópia de tudo. O wp db export corre o mysqldump com as credenciais do wp-config.php e escreve um ficheiro SQL. Com --tables escolhe tabelas concretas, com --exclude_tables exclui-as e com - como nome de ficheiro o dump sai pela saída padrão:
wp db export - --tables=wp_posts,wp_postmeta | gzip > conteudo.sql.gzAjuste o prefixo das tabelas ao da sua instalação. Um dump SQL serve para restaurar ou carregar noutra base de dados, não para abrir no Excel. Além disso inclui a tabela de utilizadores com os hashes das palavras-passe e, com frequência, chaves de API que os plugins guardam em wp_options. Trate-o como um segredo: nunca numa pasta pública, nunca como anexo de email.
Exportar dados do WordPress para um CRM com REST API
Se o consumidor é software, não uma pessoa com Excel, a REST API é muitas vezes mais limpa do que gerar CSV dentro do WordPress.
Casos típicos:
- sincronizar conteúdo para um warehouse ou ferramenta de BI
- alimentar um CRM a partir de utilizadores ou leads
- front ends headless que precisam de payloads estruturados de posts
Referência da coleção de posts: endpoint de Posts.
A REST devolve JSON. Paginem com page e per_page, autentiquem com Application Passwords ou fluxos OAuth que o hosting suporte, e respeitem rate limits. Segundo o guia de paginação, per_page tem um máximo de 100 registos, e cada resposta traz os cabeçalhos X-WP-Total (total de registos) e X-WP-TotalPages (total de páginas). O cliente deve ler X-WP-TotalPages e pedir páginas até esse número, em vez de adivinhar quando parar. Construam o CSV a jusante se ainda for preciso uma folha. Essa divisão mantém o WordPress responsável pelo acesso autorizado e deixa a formatação do ficheiro ao consumidor.
Não exponha rotas privilegiadas de exportação sem autenticação. Trate endpoints de exportação como qualquer outra superfície de admin adjacente a escrita, mesmo quando só leem.
Exportar produtos WooCommerce para CSV sem plugin
O catálogo não precisa de código. Segundo a documentação do importador e exportador CSV de produtos, o WooCommerce inclui uma ferramenta própria para importar, exportar e atualizar produtos em massa:
- Vá a Produtos > Todos os produtos e clique em Exportar no topo da página.
- Escolha as colunas ou mantenha a opção de exportar todas.
- Filtre por tipos de produto e categorias, ou deixe ambos em todos.
- Marque a opção de exportar todos os metadados personalizados se precisar de dados do WooCommerce ou de outros plugins. Essas colunas levam o prefixo
meta:. - Clique em Gerar CSV e espere que o browser descarregue o ficheiro.
O ficheiro usa o mesmo formato que o importador lê, por isso serve de base para alterações em massa de preços ou stock: exporta, edita na folha e volta a importar. A ferramenta cobre o catálogo de produtos. As encomendas ficam de fora, e a secção seguinte trata delas.
Como exportar encomendas WooCommerce para CSV
Exportações de encomendas parecem simples até linhas de item, reembolsos e HPOS mudarem o quadro.
Linhas de item não são uma única linha. Uma encomenda pode ter vários produtos, taxas, portes e impostos. Decida à partida se uma linha CSV significa uma encomenda ou uma linha de item. Misturar ambos sem um esquema claro produz folhas inutilizáveis.
Meta e campos personalizados explodem a largura. IDs de gateway de pagamento, números de tracking e meta de plugins criam colunas largas e esparsas. Exporte só os campos de que o relatório precisa. Adicione um segundo ficheiro para linhas de item se tiver de manter as duas formas.
Os backends de armazenamento diferem. Posts clássicos shop_order e tabelas High-Performance Order Storage (HPOS) não se consultam da mesma forma. O HPOS é o armazenamento por omissão desde o WooCommerce 8.2, segundo a documentação de wc_get_orders(). Prefira o CRUD do WooCommerce (wc_get_orders() / WC_Order_Query) em vez de WP_Query cru em shop_order, para o exportador sobreviver a mudanças de storage. Para filtrar por datas, date_created aceita um intervalo na forma 2026-01-01...2026-03-31, lido no fuso horário do site.
Filtros de estado importam. Rascunhos, pagamentos falhados, reembolsos e lixo inflacionam ou distorcem relatórios de receita. Documente que estados inclui.
PII e acesso. Encomendas incluem nomes, emails e moradas. Verificações de capacidade (manage_woocommerce ou uma capacidade personalizada), nonces e logs de auditoria pertencem a todos os exportadores de admin. Prefira WP-CLI para dumps em volume para o ficheiro nunca ficar num caminho de uploads publicamente alcançável.
Desempenho. Juntar todas as chaves de meta de encomenda num único SQL parece rápido até a tabela crescer. Paginem as encomendas, hidratem cada uma com wc_get_order(), escrevam a linha e descartem o objeto. Esse padrão é mais lento por encomenda do que um JOIN gigante e bem mais estável sob limites de memória.
Moeda e formatação. Guarde totais como números simples. Deixe o Excel formatar moeda. Separadores de milhares específicos do locale dentro de campos CSV partem importações noutras ferramentas.
Campos de data. Guarde ISO-8601 ou timestamps Unix no CSV e formate na folha. Strings de data locais misturadas (03/04/2026 vs 04/03/2026) causam bugs silenciosos de reordenação quando o ficheiro atravessa regiões, algo comum entre equipas em Lisboa e clientes no Reino Unido.
Reembolsos e reembolsos parciais. Decida se totais reembolsados aparecem como linhas negativas, IDs de reembolso separados ou totais líquidos da encomenda. Documente a escolha num README junto ao cron de exportação para finanças e engenharia concordarem na mesma folha.
Como evitar a injeção de fórmulas num CSV exportado
Um CSV exportado do WordPress mistura dados que os seus utilizadores escreveram: nomes visíveis, comentários, campos de formulários, moradas de faturação. A OWASP descreve o risco como CSV injection ou formula injection: acontece quando um site incorpora input não confiável num ficheiro CSV. Se uma célula começa por =, +, - ou @, ou por um tab, um retorno de carro ou uma quebra de linha, a folha de cálculo pode interpretá-la como fórmula ao abrir o ficheiro.
A mitigação da OWASP é garantir que nenhuma célula começa por esses caracteres, por exemplo acrescentando uma plica no início para que o programa leia a célula como texto:
function wppoland_csv_safe( $value ) {
$value = (string) $value;
if ( '' !== $value && in_array( $value[0], array( '=', '+', '-', '@', "\t", "\r", "\n" ), true ) ) {
return "'" . $value;
}
return $value;
}Aplique-a às colunas de texto livre, não aos montantes calculados pelo WooCommerce: um total negativo de reembolso começa por - e passaria a texto, o que parte as somas na folha.
Exportar os dados pessoais de um utilizador com a ferramenta RGPD
Quando o pedido vem de uma pessoa a exercer os seus direitos, não precisa de um exportador próprio. A documentação para programadores de plugins explica que o WordPress 4.9.6 acrescentou uma ferramenta de exportação de dados pessoais (Ferramentas > Exportar dados pessoais) pensada para leis como o RGPD.
A chave de cada exportação é o endereço de email, o que cobre utilizadores registados e também quem apenas deixou um comentário. O administrador introduz o nome de utilizador ou o email, o WordPress envia um link de confirmação e, depois de confirmado, o administrador descarrega o ZIP ou envia-o diretamente à pessoa. Lá dentro há uma página HTML de índice com os dados organizados em grupos, por exemplo os comentários. Os plugins que guardam dados pessoais próprios ligam-se através do filtro wp_privacy_personal_data_exporters para que esses dados entrem no mesmo ficheiro.
Checklist para exportar dados do WordPress
- Prefira CSV a XLSX dentro do WordPress, e WXR só para migrar conteúdo.
- Faça stream com
fputcsv(),escapeexplícito e verificações de capacidade para downloads pequenos no admin. - Processe em lotes com
WP_Queryou consultas WooCommerce; desative caches desnecessários. - Passe trabalhos grandes ou agendados para WP-CLI.
- Use a REST API quando outro sistema puxa dados estruturados.
- No WooCommerce, defina o grão da linha (encomenda vs linha de item) e use APIs CRUD para o HPOS não partir o exportador.
- Neutralize células que começam por
=,+,-ou@nas colunas de texto livre.
Bem feito, as exportações WordPress ficam aborrecidas: colunas previsíveis, memória limitada e sem timeouts surpresa durante um relatório de pico de tráfego.







