IRONSOFTWAREHOME
USANDO IRONXL

Exportar DataTable de registros SII a XLSX para AEAT con IronXL sin Office en .NET

Curtis Chau
Curtis Chau
Updated: 28 de junio de 2026

Exportar una DataTable de registros SII a XLSX para la AEAT es uno de los patrones más frecuentes en los equipos de cumplimiento fiscal que trabajan con .NET. Los registros de facturas emitidas y recibidas del SII (Suministro Inmediato de Información) se almacenan habitualmente en tablas de base de datos accesibles como DataTable en el código C#; la tarea es convertir esas filas en un fichero XLSX estructurado para su revisión, archivo o presentación a la AEAT (modelos 303, 347, 390). La dirección inversa —leer un XLSX existente y cargarlo en un DataTable— es igual de importante para los flujos de importación de declaraciones. IronXL gestiona ambas direcciones en .NET puro, sin dependencia de Microsoft Office y sin configuración de interoperabilidad COM, funcionando en Linux y Docker.

Instala IronXL antes de ejecutar cualquiera de los ejemplos siguientes:

PM > Install-Package IronXL.Excel

Una vez instalados, los tipos WorkBook y WorkSheet exponen los métodos ToDataTable y ToDataSet que se asignan directamente a las estructuras System.Data. También puede invertir el proceso escribiendo los valores DataRow de vuelta en una hoja de cálculo y guardando el fichero en formato XLSX para la AEAT, aplicando además el principio de minimización de datos de la LOPDGDD: solo exporte las columnas necesarias para el trámite fiscal.

¿Cómo se convierte una hoja de cálculo completa en una DataTable de registros SII?

El método ToDataTable convierte una hoja de cálculo completa —o un rango con nombre— en un System.Data.DataTable. Pase true para tratar la primera fila como encabezados de columna, de modo que los nombres de las columnas coincidan exactamente con los campos del fichero SII (NIF emisor, fecha factura, base imponible, cuota IVA, etc.).

using IronXL;
using System.Data;

// Load the workbook from disk
WorkBook workbook = WorkBook.Load("customers.xlsx");

// Grab the default (first) worksheet
WorkSheet worksheet = workbook.DefaultWorkSheet;

// Convert the entire sheet; first row becomes column headers
DataTable dataTable = worksheet.ToDataTable(true);

// Iterate every row and print each cell value
foreach (DataRow row in dataTable.Rows)
{
    for (int i = 0; i < dataTable.Columns.Count; i++)
    {
        Console.Write(row[i] + "\t");
    }
    Console.WriteLine();
}

Qué hace el código

WorkBook.Load lee el fichero XLSX sin automatización de Office. worksheet.ToDataTable(true) recorre cada celda y la asigna a un DataRow, utilizando la primera fila como nombres de DataColumn. El resultado DataTable es un objeto estándar System.Data: puede vincularlo a un DataGridView, pasarlo a un SqlBulkCopy para insertar en la base de datos de declaraciones AEAT, o ejecutar consultas LINQ sobre él inmediatamente.

La llamada ToDataTable es compatible con los formatos XLS y XLSX, por lo que el mismo código funciona para hojas de cálculo heredadas sin modificaciones. Consulte la documentación de IronXL DataTable y DataSet para la referencia completa de la API.

¿Cómo exportar un rango específico a DataTable para cumplir la LOPDGDD?

Cuando se preparan los datos del modelo 347 (operaciones con terceros superiores a 3.005,06 €) o del modelo 303 (cuotas de IVA del trimestre), solo deben exportarse las columnas estrictamente necesarias. La LOPDGDD impone el principio de minimización de datos: no incluir campos de datos personales (nombres completos, domicilios) que no sean requeridos por la declaración específica. IronXL permite exportar únicamente el rango de celdas necesario, lo que también mejora el rendimiento en ficheros grandes.

using IronXL;
using System.Data;

WorkBook workbook = WorkBook.Load("financial_report.xlsx");

// Access a named worksheet
WorkSheet worksheet = workbook.GetWorkSheet("Summary");

// Select only the region A1:D20 and convert it
DataTable dt = worksheet["A1:D20"].ToDataTable(true);

Console.WriteLine($"Rows: {dt.Rows.Count}, Columns: {dt.Columns.Count}");

foreach (DataRow row in dt.Rows)
{
    foreach (var item in row.ItemArray)
    {
        Console.Write(item + "\t");
    }
    Console.WriteLine();
}

Por qué es importante la selección de rangos para declaraciones AEAT

La sintaxis entre corchetes worksheet["A1:D20"] devuelve un objeto IronXL.Range. Llamar a ToDataTable en ese rango limita el procesamiento exactamente a esas celdas, lo que significa una ejecución más rápida y menor consumo de memoria cuando el fichero SII tiene decenas de miles de registros de facturas.

También puede especificar rangos con nombre o construir la cadena de rango dinámicamente —por ejemplo, $"A1:D{lastRow}"—, lo que hace el enfoque flexible para exportaciones de longitud variable (como el número de operaciones del modelo 347 que varía por ejercicio). La referencia de la API de la clase Range documenta todos los métodos de selección disponibles.

¿Cómo se convierte un libro de varias hojas en un DataSet para los modelos AEAT?

Los libros de trabajo con varias hojas —por ejemplo, una hoja para el modelo 303, otra para el modelo 347 y una tercera para el modelo 390 (resumen anual IVA)— se asignan de forma natural a System.Data.DataSet, donde cada hoja se convierte en un DataTable independiente. El método ToDataSet realiza esta conversión en una sola llamada, preservando los nombres de hoja como TableName de cada DataTable.

using IronXL;
using System.Data;

WorkBook workbook = WorkBook.Load("multi_sheet.xlsx");

// Each worksheet becomes a DataTable inside the DataSet
DataSet dataSet = workbook.ToDataSet();

foreach (DataTable table in dataSet.Tables)
{
    Console.WriteLine($"Sheet: {table.TableName}");
    Console.WriteLine($"Rows:  {table.Rows.Count}");
    Console.WriteLine();
}

Acceder a hojas de declaraciones AEAT por nombre

Cada DataTable en el DataSet utiliza el nombre original de la hoja como TableName, por lo que puede recuperar una hoja específica con dataSet.Tables["Modelo303"] en lugar de iterar por la colección. Esto facilita la lógica de generación de informes en varias declaraciones o la combinación de datos de distintas hojas antes de escribir los resultados en la base de datos de cumplimiento. Las entidades supervisadas por el Banco de España / CNMV que gestionan envíos regulatorios XLSX con múltiples pestañas se benefician especialmente de este patrón.

Para más formas de trabajar con varias hojas, consulta cómo abrir y gestionar hojas de cálculo de Excel.

¿Cómo exportar una DataTable de registros SII a un fichero XLSX para la AEAT?

Esta es la operación principal en los flujos de generación de declaraciones: el sistema de gestión produce un DataTable con los registros del SII (NIF, tipo de factura, base imponible, cuota IVA, fecha) y debe convertirlo en un fichero XLSX para la presentación telemática a la AEAT o para el archivo según la LOPDGDD. IronXL permite hacer esto en .NET sin Office, en Linux/Docker.

using IronXL;
using System.Data;

// Build a sample DataTable
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("ProductID", typeof(int)));
dt.Columns.Add(new DataColumn("ProductName", typeof(string)));
dt.Columns.Add(new DataColumn("UnitPrice", typeof(decimal)));
dt.Rows.Add(1, "Widget Pro", 29.99m);
dt.Rows.Add(2, "Gadget Max", 49.99m);
dt.Rows.Add(3, "Sensor Kit", 14.50m);

// Create a new workbook and worksheet
WorkBook workbook = WorkBook.Create();
WorkSheet worksheet = workbook.CreateWorkSheet("Products");

// Write column headers from DataTable.Columns
for (int col = 0; col < dt.Columns.Count; col++)
{
    worksheet.SetCellValue(0, col, dt.Columns[col].ColumnName);
}

// Write data rows
for (int row = 0; row < dt.Rows.Count; row++)
{
    for (int col = 0; col < dt.Columns.Count; col++)
    {
        worksheet.SetCellValue(row + 1, col, dt.Rows[row][col]);
    }
}

// Save as XLSX
workbook.SaveAs("products_export.xlsx");
Console.WriteLine("Export complete.");

Cómo funciona el bucle de escritura de celdas

SetCellValue(rowIndex, columnIndex, value) acepta valores object, por lo que se pasan los nombres de las columnas para la fila de encabezado y los valores de las celdas sin formato para las filas de datos sin necesidad de conversión de tipos. El desplazamiento de fila de row + 1 reserva la fila 0 para los encabezados. El fichero XLSX resultante es una hoja de cálculo totalmente válida para la AEAT, sin marcadores de posición ni archivos temporales.

Para tablas con muchos registros SII, aplique el ajuste automático del tamaño de las columnas tras la escritura para que el contenido (NIF, importes, fechas) se muestre claramente sin formateo manual.

¿Cómo vincular la DataTable de declaraciones a un DataGridView?

Una razón habitual para exportar un fichero XLSX de declaraciones AEAT a un DataTable es mostrarlo en un DataGridView de Windows Forms para la revisión por parte del equipo de cumplimiento antes de la presentación. Una vez que se tiene el DataTable, la vinculación se realiza con una sola línea.

using IronXL;
using System.Data;
using System.Windows.Forms;

WorkBook workbook = WorkBook.Load("inventory.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;
DataTable dataTable = worksheet.ToDataTable(true);

// Bind directly to a DataGridView
dataGridViewInventory.DataSource = dataTable;

¿Qué ocurre en el momento de la vinculación?

Al establecer DataSource, el DataGridView lee los nombres de las columnas y los datos de las filas del DataTable. Cada DataColumn se convierte en una columna de la cuadrícula, y cada DataRow en una fila visible. Puede aplicar comportamientos de ordenación, filtrado y selección a través de los controles integrados sin código adicional —útil para revisar los registros del modelo 347 antes de marcarlos como listos para presentación.

Este patrón funciona igualmente con WPF DataGrid, ASP.NET GridView y cualquier otra infraestructura de enlace de datos de .NET. Para una guía paso a paso, consulte cómo exportar un DataGridView a Excel.

¿Cómo ejecutar consultas LINQ en una DataTable de registros SII exportada?

Después de convertir el fichero XLSX del SII a un DataTable, puede ejecutar consultas LINQ para filtrar operaciones del modelo 347 que superen los 3.005,06 €, identificar facturas con cuota de IVA del modelo 303 por debajo de un umbral, o detectar registros de VeriFactu (Real Decreto-Ley 15/2025) con campos obligatorios vacíos.

using IronXL;
using System.Data;
using System.Linq;

WorkBook workbook = WorkBook.Load("sales.xlsx");
DataTable dt = workbook.DefaultWorkSheet.ToDataTable(true);

// Filter rows where the "Revenue" column exceeds 10000
var highRevenue = dt.AsEnumerable()
    .Where(row => row.Field<double>("Revenue") > 10000)
    .OrderByDescending(row => row.Field<double>("Revenue"))
    .ToList();

Console.WriteLine($"High-revenue records: {highRevenue.Count}");
foreach (var row in highRevenue)
{
    Console.WriteLine($"{row["Product"]}: {row["Revenue"]:C}");
}

Por qué LINQ es útil para la validación de datos AEAT

Las consultas LINQ ofrecen una forma legible y fuertemente tipada de filtrar, ordenar, agrupar y proyectar datos de un fichero de declaración convertido. row.Field<T>(columnName) gestiona la coerción de tipos de forma limpia, lanzando InvalidCastException si un valor no puede convertirse —lo que facilita la detección temprana de errores de calidad de datos en registros SII antes de la presentación a la AEAT.

Combine este enfoque con la exportación basada en rangos de la sección anterior para consultar únicamente los campos declarados del modelo 303 o del modelo 390, manteniendo bajo el uso de memoria.

¿Cómo ahorrar memoria al exportar ficheros SII de gran tamaño?

Los ficheros XLSX del SII con muchos miles de registros de facturas pueden ser grandes. Al exportar toda la hoja de una vez se asignan todos los datos a la memoria simultáneamente. Dos patrones de IronXL reducen el pico de uso de memoria en servidores Linux de producción:

  • Exportación de rango: Use worksheet["A1:D5000"].ToDataTable(true) para procesar una región delimitada.
  • Procesamiento por lotes: Calcule la última fila con worksheet.RowCount, luego recorra rangos de tamaño fijo —por ejemplo, 1.000 filas a la vez— y procese cada lote antes de pasar al siguiente.
using IronXL;
using System.Data;

WorkBook workbook = WorkBook.Load("large_dataset.xlsx");
WorkSheet worksheet = workbook.DefaultWorkSheet;

int batchSize = 1000;
int totalRows = worksheet.RowCount;

for (int startRow = 1; startRow <= totalRows; startRow += batchSize)
{
    int endRow = Math.Min(startRow + batchSize - 1, totalRows);
    string rangeAddress = $"A{startRow}:Z{endRow}";

    DataTable batch = worksheet[rangeAddress].ToDataTable(false);
    // Process each batch -- write to database, transform, etc.
    Console.WriteLine($"Processed rows {startRow} to {endRow}");
}

Este patrón es especialmente relevante para leer ficheros Excel de gran tamaño en C#, como los ficheros SII con decenas de miles de facturas del ejercicio.

¿Cómo cargar la DataTable de registros SII en una base de datos con SqlBulkCopy?

Una vez que se tiene el DataTable con los registros del SII, la forma más rápida de insertarlo en la base de datos de declaraciones es con SqlBulkCopy. Acepta un DataTable directamente y transmite filas por lotes sin crear sentencias INSERT individuales.

using IronXL;
using System.Data;
using Microsoft.Data.SqlClient;

WorkBook workbook = WorkBook.Load("orders.xlsx");
DataTable dataTable = workbook.DefaultWorkSheet.ToDataTable(true);

string connectionCadena = "Server=.;Database=OrdersDB;Trusted_Connection=True;";

using SqlConnection connection = new(connectionCadena);
connection.Open();

using SqlBulkCopy bulkCopy = new(connection);
bulkCopy.DestinationTableName = "dbo.Orders";
bulkCopy.BatchSize = 500;
bulkCopy.BulkCopyTimeout = 60;

// Map DataTable columns to database columns
bulkCopy.ColumnMappings.Add("OrderID", "OrderID");
bulkCopy.ColumnMappings.Add("CustomerName", "CustomerName");
bulkCopy.ColumnMappings.Add("TotalAmount", "TotalAmount");

bulkCopy.WriteToServer(dataTable);
Console.WriteLine("Bulk insert complete.");

Consideraciones sobre la asignación de columnas para registros AEAT

La colección ColumnMappings hace coincidir los nombres de las columnas DataTable con los de la base de datos. Las asignaciones explícitas son más seguras cuando el orden de las columnas del fichero SII difiere del esquema de la base de datos de cumplimiento. Si los datos incluyen información sujeta a la LOPDGDD (NIF de clientes, importes de operaciones), asegúrese de que la tabla de destino tenga los controles de acceso adecuados.

Para más información sobre cómo combinar IronXL con flujos de trabajo de bases de datos, la guía de importación de Excel en C# cubre escenarios adicionales, incluida la validación previa a la inserción. La documentación de SqlBulkCopy de Microsoft explica las opciones de procesamiento por lotes y la compatibilidad con transacciones.

¿Cuales son tus próximos pasos?

Ahora dispone de un conjunto completo de herramientas para exportar DataTable de registros SII a XLSX para la AEAT con IronXL en .NET, sin Office en servidores Linux/Docker:

  • Convertir una hoja de cálculo completa con worksheet.ToDataTable(true) para exportaciones con encabezados
  • Exportar rangos específicos (columnas necesarias según la LOPDGDD) con worksheet["A1:D20"].ToDataTable(true)
  • Convertir libros de varias hojas (modelos 303, 347, 390) con workbook.ToDataSet()
  • Escribir el contenido del DataTable de vuelta en XLSX con SetCellValue para presentaciones a la AEAT
  • Vincular DataTable a controles de revisión como DataGridView con una única asignación DataSource
  • Alimentar SqlBulkCopy directamente desde un DataTable para inserciones masivas en la BD de cumplimiento

Para profundizar en tus conocimientos de IronXL, explora estos temas relacionados:

Empieza con una licencia de prueba gratuita de IronXL para ejecutar estos ejemplos en tus propios proyectos. Cuando esté listo para la implementación en producción, adquiera una licencia o póngase en contacto con el equipo para orientación sobre licencias.

Primer Paso:
arrow pointer
Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien estructurados y visualmente atractivos.

...
Leer más

Artículos Relacionados

Key in blue circle

Obtenga su clave de prueba gratuita de 30 días al instante.

Your trial license will be sent to your email address

Sin limitaciones. 100 % desbloqueado. Sin tarjeta de crédito.

bullet_checkedNo se requiere tarjeta de crédito ni creación de cuentaSin limitaciones. 100 % desbloqueado. Sin tarjeta de crédito.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Reserve su Demostración en Vivo gratuita
Booking Badge

Confiado por millones de ingenieros en todo el mundo

Logos de clientes de Iron Software
Obtén tu Consulta Sin Compromiso
Completa el formulario a continuación o envía un correo a sales@ironsoftware.com
Tus detalles siempre serán mantenidos confidenciales.
Confiado por millones de ingenieros en todo el mundo
Logos de clientes de Iron Software
Obtenga su Clave de Prueba de 30 días gratis al instante.
No se requiere tarjeta de crédito ni creación de cuenta