Como exportar un CSV desde el admin usando PHP en WordPress

Contents

Introducción

Este tutorial explica paso a paso cómo exportar un archivo CSV desde el área de administración de WordPress usando PHP. Cubre desde la creación de un pequeño plugin o fragmento en functions.php hasta el manejo seguro de la petición, la generación del CSV con fputcsv, recomendaciones para grandes volúmenes de datos y ejemplos prácticos para posts y usuarios. El código de ejemplo está listo para copiar y pegar en un plugin.

Conceptos clave antes de comenzar

  • Evitar salida previa: No debe imprimirse nada antes de enviar las cabeceras HTTP por eso es preferible implementar la lógica en un plugin o en hooks adecuados.
  • Seguridad: Usar comprobaciones de capability y nonce para evitar accesos no autorizados.
  • Encodificación: Para compatibilidad con Excel en Windows, se suele añadir la marca BOM UTF-8.
  • Rendimiento: Para grandes cantidades de registros usar paginación, consulta por IDs o procesos en segundo plano (WP CLI, cron o jobs).

Flujo general

  1. Crear una página o botón en el admin que envíe una petición (form) a admin-post.php o admin-ajax.php.
  2. Registrar un hook (admin_post_ / admin_post_nopriv_ o wp_ajax_) para manejar la petición.
  3. En el handler: validar capability y nonce, preparar cabeceras HTTP, abrir php://output y escribir CSV con fputcsv.
  4. Finalizar correctamente con exit para evitar añadir HTML extra.

Ejemplo completo: plugin que exporta posts a CSV

Este ejemplo añade un menú en el admin con un botón para exportar posts. Usa admin-post.php y un handler seguro.


    

Exportar posts a CSV

>

post_type, post_status => any, posts_per_page => posts_per_page, paged => paged, no_found_rows => true, fields => ids, ) ) if ( ! query->have_posts() ) { break } foreach ( query->posts as post_id ) { post = get_post( post_id ) row = array( post->ID, post->post_title, post->post_date, post->post_status, post->post_type, get_the_author_meta( display_name, post->post_author ), get_permalink( post->ID ), ) // Permitir filtrar la fila (añadir meta, taxonomías, etc.) row = apply_filters( ced_export_csv_row, row, post ) fputcsv( output, row ) } // Limpieza entre paginaciones para liberar memoria wp_reset_postdata() paged // Si hay muchos posts, continuar el bucle } while ( query->found_posts > ( ( paged - 1 ) posts_per_page ) ) fclose( output ) exit }

Notas sobre el ejemplo anterior

  • La consulta usa no_found_rows => true y fields => ids para reducir memoria cuando es posible.
  • Se incluye un filtro ced_export_csv_columns y ced_export_csv_row para permitir extensiones sin tocar el plugin.
  • Se utiliza un tamaño de página (posts_per_page) de 200 ajustarlo según recursos del servidor.
  • Usar wp_reset_postdata() y liberar variables para prevenir fugas de memoria.

Ejemplo: exportar usuarios

Similar al caso de posts, pero usando get_users.

add_action( admin_post_ced_export_users, ced_export_users_handler )

function ced_export_users_handler() {
    if ( ! current_user_can( list_users ) ) {
        wp_die( No tienes permisos )
    }
    // Validar nonce aquí...

    if ( headers_sent() ) {
        wp_die( Cabeceras ya enviadas )
    }

    header( Content-Type: text/csv charset=UTF-8 )
    header( Content-Disposition: attachment filename=usuarios-export- . gmdate( Y-m-d-H-i-s ) . .csv )
    echo xEFxBBxBF

    output = fopen( php://output, w )
    columns = array( ID, user_login, user_email, display_name, roles )
    fputcsv( output, columns )

    args = array(
        fields => all,
        number => 0, // 0 significa todos para muchos usuarios usar paginación
    )

    users = get_users( args )
    foreach ( users as user ) {
        roles = implode( ,, user->roles )
        row = array( user->ID, user->user_login, user->user_email, user->display_name, roles )
        fputcsv( output, row )
    }

    fclose( output )
    exit
}

Manejo de grandes volúmenes de datos

  • Usar paginación en la consulta para procesar lotes y liberar memoria entre iteraciones.
  • Considerar exportaciones asíncronas mediante WP-CLI, cron o colas para no bloquear el request HTTP.
  • Si la exportación excede el tiempo máximo de ejecución, usar set_time_limit(0) y aumentar memory_limit temporalmente.
  • Para datasets extremadamente grandes, generar archivos temporales en disco (fputcsv a un fichero) y luego ofrecer la descarga del fichero ya creado.

Formato y compatibilidad con Excel

  • Excel en Windows detecta mejor UTF-8 si se antepone la BOM: echo xEFxBBxBF
  • En algunos países (p.ej. España) Excel usa el punto y coma como separador puedes transformar usando str_replace o fputcsv con el parámetro delimiter si es necesario.
  • fputcsv gestiona correctamente comillas y comas dentro de campos evita concatenar valores con comas manualmente.

Buenas prácticas y seguridad

  • Comprobar capability (current_user_can).
  • Verificar nonce (wp_verify_nonce) para prevenir CSRF.
  • Escapar/sanitizar entrada del usuario antes de usar en consultas (sanitize_text_field, absint, etc.).
  • No imprimir HTML ni debug antes de las cabeceras evitar var_dump/echos durante desarrollo en handlers de exportación.
  • Usar sanitize_file_name para el nombre del fichero de descarga.

Extender y personalizar

  • Añadir opciones en la página admin para elegir campos, rango de fechas, estados o taxonomías.
  • Ofrecer varios formatos (CSV, TSV, Excel XML, JSON) usando filtros y acciones.
  • Usar hooks para que otros plugins añadan columnas o transformen filas antes de escribir el CSV.

Errores comunes y cómo resolverlos

  1. Cabeceras ya enviadas: Aparece si hay salida previa. Solución: eliminar cualquier echo/whitespace antes del handler y colocar código en plugin o en hooks apropiados.
  2. CSV corrupto o con caracteres extraños: Añadir BOM y asegurarse de usar charset UTF-8 tanto al generar como al abrir en destino.
  3. Tiempo de ejecución agotado: Procesar en lotes, usar set_time_limit(0) o ejecutar en background.
  4. Memoria insuficiente: Aumentar memory_limit temporalmente o procesar por lotes, no cargar todos los objetos completos si solo necesitas campos concretos.

Resumen

Exportar un CSV desde el admin de WordPress es una tarea que, bien planteada, es segura y eficiente: crear una acción admin_post, validar permisos y nonces, preparar cabeceras, usar php://output con fputcsv y manejar la consulta de forma paginada para grandes conjuntos. El ejemplo de plugin mostrado es un punto de partida que puede extenderse con filtros para adaptarlo a cualquier necesidad.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *