Saltar al pie de página
USANDO IRONXL

Importar CSV de operaciones SII/AEAT a Excel con IronXL en C#: guía ASP.NET Core

Importar un archivo CSV en C# con ASP.NET Core implica leer un flujo de datos, analizar filas delimitadas y asignar cada registro a un objeto tipado, todo ello antes de poder hacer nada útil con los datos. En el contexto fiscal español, los ficheros CSV del SII (Suministro Inmediato de Información) de la AEAT son habituales: los sistemas contables exportan libros registro en CSV que luego hay que parsear, validar y transformar en XLSX o XML para su remisión a la AEAT. IronXL gestiona cada paso a través de una única API que funciona igual de bien con archivos CSV, XLSX y TSV, por lo que puedes dedicar tu tiempo a la lógica de compliance de tu aplicación en lugar de a casos extremos de división de cadenas.

Comienza tu prueba gratuita para seguir el proceso y probar estos ejemplos de código en tu propio Entorno.

¿Cómo instalar IronXL en un proyecto .NET para parsear CSV de operaciones SII?

Antes de escribir cualquier código de análisis, añade IronXL a tu proyecto. Abre la Consola del Administrador de paquetes en Visual Studio o un terminal en el directorio de tu proyecto y ejecuta uno de los siguientes comandos:

Install-Package IronXL.Excel
dotnet add package IronXL.Excel
Install-Package IronXL.Excel
dotnet add package IronXL.Excel
SHELL

El paquete está destinado a .NET 10, .NET 6+, .NET Framework 4.6.2+ y .NET Standard 2.0, por lo que se adapta a cualquier tipo de proyecto moderno. No es necesario instalar Microsoft Office en el servidor —esencial para los servicios de compliance que corren en Linux/Docker. Una vez restaurado el paquete, añada using IronXL; al principio de cualquier archivo que llame a la biblioteca.

Para obtener información detallada sobre las opciones de configuración, incluida la instalación global de herramientas y la configuración del pipeline de CI/CD, consulte la guía de instalación de IronXL .

¿Cómo importar un fichero CSV del SII/AEAT en ASP.NET Core?

Importar un archivo CSV del SII en .NET Core requiere leer el flujo de datos del servidor, analizar cada fila y asignar los valores a una clase de modelo. Los ficheros CSV del Suministro Inmediato de Información pueden contener campos con punto y coma como delimitador (formato habitual en España), valores de importes decimales con coma y fechas en formato español (dd/MM/yyyy). IronXL proporciona un método único que maneja archivos CSV junto con formatos de Excel sin configuración adicional.

El siguiente código muestra cómo cargar un archivo CSV utilizando el método WorkBook.LoadCSV de IronXL:

using IronXL;

// Load the CSV file directly using the full file path
var csv = WorkBook.LoadCSV("products.csv");
WorkSheet worksheet = csv.DefaultWorkSheet;

// Access CSV data by iterating through rows
foreach (var row in worksheet.Rows)
{
    string productName = row.Columns[1].StringValue;
    decimal price = row.Columns[2].DecimalValue;
    Console.WriteLine($"Product: {productName}, Price: {price}");
}
using IronXL;

// Load the CSV file directly using the full file path
var csv = WorkBook.LoadCSV("products.csv");
WorkSheet worksheet = csv.DefaultWorkSheet;

// Access CSV data by iterating through rows
foreach (var row in worksheet.Rows)
{
    string productName = row.Columns[1].StringValue;
    decimal price = row.Columns[2].DecimalValue;
    Console.WriteLine($"Product: {productName}, Price: {price}");
}
Imports IronXL

' Load the CSV file directly using the full file path
Dim csv = WorkBook.LoadCSV("products.csv")
Dim worksheet As WorkSheet = csv.DefaultWorkSheet

' Access CSV data by iterating through rows
For Each row In worksheet.Rows
    Dim productName As String = row.Columns(1).StringValue
    Dim price As Decimal = row.Columns(2).DecimalValue
    Console.WriteLine($"Product: {productName}, Price: {price}")
Next
$vbLabelText   $csharpLabel

Comprensión del método WorkBook.LoadCSV para datos de operaciones SII

El método WorkBook.LoadCSV lee el archivo CSV y crea una hoja de cálculo en la que cada línea se convierte en una fila y cada valor delimitado se convierte en una celda. IronXL detecta automáticamente el delimitador (coma, punto y coma o tabulación) y gestiona los campos entre comillas que contienen comas dentro del valor —lo que es especialmente útil para los CSV de la AEAT donde los nombres de razones sociales pueden contener comas.

Accesores de valores de celda como StringValue, DecimalValue, IntValue, y DateTimeValue manejan la conversión de tipos para evitar el análisis manual con int.TryParse o decimal.Parse. Cuando una celda está vacía o contiene un valor no reconocido, estos accesores devuelven el valor predeterminado del tipo en lugar de lanzar una excepción, lo que evita errores no controlados durante las operaciones de importación masiva del SII.

Este enfoque elimina el análisis manual de cadenas, propenso a errores, que requieren las implementaciones personalizadas, especialmente en casos extremos como comillas escapadas, finales de línea al estilo de Windows y valores de celda de varias líneas. Para obtener más detalles sobre los formatos compatibles y las opciones de delimitadores, consulte la documentación de IronXL CSV.

Importación de CSV de ASP: Guía completa para desarrolladores de C#: Imagen 1: Importación de un archivo CSV simple y lectura del resultado en la consola

¿Cómo se puede crear una clase de modelo para datos CSV del SII/modelo 347?

Para asignar datos CSV del SII a objetos fuertemente tipados se requiere una clase de modelo que refleje la estructura del fichero. En el contexto del modelo 347 (operaciones con terceros superiores a 3.005,06 €), los campos típicos incluyen NIF del tercero, razón social, importe total y ejercicio fiscal. Convierte datos de cadenas sin procesar en tipos específicos, como enteros, decimales y valores DateTime:

// Modelo para operaciones SII/modelo 347
public class OperacionAEAT
{
    public string NIF_Tercero { get; set; } = string.Empty;
    public string RazonSocial { get; set; } = string.Empty;
    public decimal ImporteTotal { get; set; }
    public int EjercicioFiscal { get; set; }
}
// Modelo para operaciones SII/modelo 347
public class OperacionAEAT
{
    public string NIF_Tercero { get; set; } = string.Empty;
    public string RazonSocial { get; set; } = string.Empty;
    public decimal ImporteTotal { get; set; }
    public int EjercicioFiscal { get; set; }
}
' Modelo para operaciones SII/modelo 347
Public Class OperacionAEAT
    Public Property NIF_Tercero As String = String.Empty
    Public Property RazonSocial As String = String.Empty
    Public Property ImporteTotal As Decimal
    Public Property EjercicioFiscal As Integer
End Class
$vbLabelText   $csharpLabel

Análisis de filas CSV de operaciones SII en colecciones tipadas

Una vez definida la clase de modelo, puede analizar registros CSV en una colección tipada. El siguiente ejemplo salta la fila de cabecera utilizando un índice de bucle y asigna cada fila posterior a un objeto OperacionAEAT:

using IronXL;

WorkBook workbook = WorkBook.LoadCSV("operaciones_sii_347.csv");
WorkSheet ws = workbook.DefaultWorkSheet;
var records = new List<OperacionAEAT>();

// Skip header row (index 0), iterate through data rows
for (int i = 1; i < ws.Rows.Count(); i++)
{
    var row = ws.Rows[i];
    var operacion = new OperacionAEAT
    {
        NIF_Tercero = row.Columns[0].StringValue,
        RazonSocial = row.Columns[1].StringValue,
        ImporteTotal = row.Columns[2].DecimalValue,
        EjercicioFiscal = row.Columns[3].IntValue
    };
    records.Add(operacion);
}

// Filtrar solo las operaciones con importe > 3.005,06 € (umbral modelo 347)
var operacionesModelo347 = records.Where(o => o.ImporteTotal > 3005.06m).ToList();
Console.WriteLine($"Operaciones modelo 347: {operacionesModelo347.Count}");
using IronXL;

WorkBook workbook = WorkBook.LoadCSV("operaciones_sii_347.csv");
WorkSheet ws = workbook.DefaultWorkSheet;
var records = new List<OperacionAEAT>();

// Skip header row (index 0), iterate through data rows
for (int i = 1; i < ws.Rows.Count(); i++)
{
    var row = ws.Rows[i];
    var operacion = new OperacionAEAT
    {
        NIF_Tercero = row.Columns[0].StringValue,
        RazonSocial = row.Columns[1].StringValue,
        ImporteTotal = row.Columns[2].DecimalValue,
        EjercicioFiscal = row.Columns[3].IntValue
    };
    records.Add(operacion);
}

// Filtrar solo las operaciones con importe > 3.005,06 € (umbral modelo 347)
var operacionesModelo347 = records.Where(o => o.ImporteTotal > 3005.06m).ToList();
Console.WriteLine($"Operaciones modelo 347: {operacionesModelo347.Count}");
Imports IronXL

Dim workbook As WorkBook = WorkBook.LoadCSV("operaciones_sii_347.csv")
Dim ws As WorkSheet = workbook.DefaultWorkSheet
Dim records As New List(Of OperacionAEAT)()

' Skip header row (index 0), iterate through data rows
For i As Integer = 1 To ws.Rows.Count() - 1
    Dim row = ws.Rows(i)
    Dim operacion As New OperacionAEAT With {
        .NIF_Tercero = row.Columns(0).StringValue,
        .RazonSocial = row.Columns(1).StringValue,
        .ImporteTotal = row.Columns(2).DecimalValue,
        .EjercicioFiscal = row.Columns(3).IntValue
    }
    records.Add(operacion)
Next

' Filtrar solo las operaciones con importe > 3.005,06 € (umbral modelo 347)
Dim operacionesModelo347 = records.Where(Function(o) o.ImporteTotal > 3005.06D).ToList()
Console.WriteLine($"Operaciones modelo 347: {operacionesModelo347.Count}")
$vbLabelText   $csharpLabel

La colección operacionesModelo347 contiene ahora objetos tipados OperacionAEAT listos para operaciones de base de datos, generación del XLSX del modelo 347 o lógica de negocio adicional. Los accesores de valores de celda de IronXL gestionan la conversión de tipos automáticamente, incluyendo el manejo de valores nulos para los campos opcionales.

Tratamiento de campos opcionales y nulos en CSV del SII

Los archivos CSV del SII suelen contener celdas vacías o columnas opcionales. Los accesores de valor de IronXL devuelven valores predeterminados en lugar de excepciones cuando una celda está en blanco. Para los tipos nulos, puede utilizar una comprobación condicional:

// Reading an optional DateTime field
DateTime? lastUpdated = string.IsNullOrEmpty(row.Columns[4].StringValue)
    ? null
    : row.Columns[4].DateTimeValue;
// Reading an optional DateTime field
DateTime? lastUpdated = string.IsNullOrEmpty(row.Columns[4].StringValue)
    ? null
    : row.Columns[4].DateTimeValue;
' Reading an optional DateTime field
Dim lastUpdated As DateTime? = If(String.IsNullOrEmpty(row.Columns(4).StringValue), Nothing, row.Columns(4).DateTimeValue)
$vbLabelText   $csharpLabel

Este patrón mantiene tu código de importación defensivo sin envolver cada acceso a una celda en un bloque try-catch. Para obtener orientación sobre cómo manejar tipos de datos complejos y archivos de gran tamaño, consulte la documentación de IronXL WorkSheet.

¿Cómo se gestionan las cargas de ficheros CSV del SII en una API web?

La creación de un punto final de API que acepte cargas de archivos CSV del SII desde un navegador requiere la combinación de IFormFile de ASP.NET Core con las capacidades de análisis de IronXL. El siguiente código muestra una implementación completa del controlador que analiza el fichero CSV del SII cargado y devuelve una respuesta JSON con los registros de operaciones:

using IronXL;
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[ApiController]
public class CsvController : ControllerBase
{
    [HttpPost("upload")]
    public async Task<IActionResult> UploadCsv(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("Please upload a valid CSV file.");

        try
        {
            using var stream = new MemoryStream();
            await file.CopyToAsync(stream);
            stream.Position = 0;

            WorkBook workbook = WorkBook.Load(stream, "csv");
            WorkSheet ws = workbook.DefaultWorkSheet;
            var records = new List<Product>();

            // Skip header row, iterate through data rows
            for (int i = 1; i < ws.Rows.Count(); i++)
            {
                var row = ws.Rows[i];
                records.Add(new Product
                {
                    Id = row.Columns[0].IntValue,
                    Name = row.Columns[1].StringValue,
                    Price = row.Columns[2].DecimalValue,
                    Quantity = row.Columns[3].IntValue
                });
            }

            return Ok(new
            {
                message = "Import successful",
                count = records.Count,
                data = records
            });
        }
        catch (Exception ex)
        {
            return BadRequest($"Error processing file: {ex.Message}");
        }
    }
}
using IronXL;
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[ApiController]
public class CsvController : ControllerBase
{
    [HttpPost("upload")]
    public async Task<IActionResult> UploadCsv(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("Please upload a valid CSV file.");

        try
        {
            using var stream = new MemoryStream();
            await file.CopyToAsync(stream);
            stream.Position = 0;

            WorkBook workbook = WorkBook.Load(stream, "csv");
            WorkSheet ws = workbook.DefaultWorkSheet;
            var records = new List<Product>();

            // Skip header row, iterate through data rows
            for (int i = 1; i < ws.Rows.Count(); i++)
            {
                var row = ws.Rows[i];
                records.Add(new Product
                {
                    Id = row.Columns[0].IntValue,
                    Name = row.Columns[1].StringValue,
                    Price = row.Columns[2].DecimalValue,
                    Quantity = row.Columns[3].IntValue
                });
            }

            return Ok(new
            {
                message = "Import successful",
                count = records.Count,
                data = records
            });
        }
        catch (Exception ex)
        {
            return BadRequest($"Error processing file: {ex.Message}");
        }
    }
}
Imports IronXL
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Imports System.Threading.Tasks

<Route("api/[controller]")>
<ApiController>
Public Class CsvController
    Inherits ControllerBase

    <HttpPost("upload")>
    Public Async Function UploadCsv(file As IFormFile) As Task(Of IActionResult)
        If file Is Nothing OrElse file.Length = 0 Then
            Return BadRequest("Please upload a valid CSV file.")
        End If

        Try
            Using stream As New MemoryStream()
                Await file.CopyToAsync(stream)
                stream.Position = 0

                Dim workbook As WorkBook = WorkBook.Load(stream, "csv")
                Dim ws As WorkSheet = workbook.DefaultWorkSheet
                Dim records As New List(Of Product)()

                ' Skip header row, iterate through data rows
                For i As Integer = 1 To ws.Rows.Count() - 1
                    Dim row = ws.Rows(i)
                    records.Add(New Product With {
                        .Id = row.Columns(0).IntValue,
                        .Name = row.Columns(1).StringValue,
                        .Price = row.Columns(2).DecimalValue,
                        .Quantity = row.Columns(3).IntValue
                    })
                Next

                Return Ok(New With {
                    .message = "Import successful",
                    .count = records.Count,
                    .data = records
                })
            End Using
        Catch ex As Exception
            Return BadRequest($"Error processing file: {ex.Message}")
        End Try
    End Function
End Class
$vbLabelText   $csharpLabel

Configuración del punto final y del formulario multiparte

Para que la acción [HttpPost("upload")] acepte la carga de archivos, el proyecto debe admitir datos de formulario multiparte. En Program.cs para una configuración mínima de la API, asegúrese de haber llamado a builder.Services.AddControllers() y app.MapControllers(). Se puede acceder al punto final en /api/csv/upload.

Cuando realice pruebas desde un formulario del navegador, establezca el atributo enctype del formulario en multipart/form-data y utilice un elemento de entrada de archivo. Para clientes de API como Postman, seleccione "form-data" en el cuerpo de la solicitud, añada una clave denominada file y adjunte el archivo CSV. El controlador devuelve un objeto JSON que contiene el recuento de registros y la matriz de datos analizados, que JavaScript del lado del cliente puede consumir inmediatamente.

ASP Import CSV: A Complete C# Developer's Guide: Imagen 2 - Salida exitosa con los datos leídos del archivo CSV importado

Validación del tipo de archivo CSV del SII antes del análisis

Antes de pasar el flujo a IronXL, valida la extensión del archivo para rechazar las cargas que no sean CSV:

var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
if (extension != ".csv" && extension != ".txt")
    return BadRequest("Only CSV files are accepted.");
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
if (extension != ".csv" && extension != ".txt")
    return BadRequest("Only CSV files are accepted.");
Dim extension As String = Path.GetExtension(file.FileName).ToLowerInvariant()
If extension <> ".csv" AndAlso extension <> ".txt" Then
    Return BadRequest("Only CSV files are accepted.")
End If
$vbLabelText   $csharpLabel

Esta comprobación evita que los datos binarios malformados lleguen al analizador y proporciona un mensaje de error claro a los usuarios de la API. Puede ampliar esta validación para comprobar el tipo MIME utilizando file.ContentType para una aplicación más estricta.

¿Cómo guardar datos CSV del SII en una base de datos respetando la LOPDGDD?

Tras analizar los ficheros CSV del SII en objetos tipados, lo habitual es guardar los registros en una base de datos. Antes de la inserción, aplique los principios de minimización de datos de la LOPDGDD: solo guarde los campos estrictamente necesarios para el cumplimiento fiscal, eliminando datos personales superfluos. El siguiente ejemplo amplía el patrón de capa de servicio mediante el uso de AddRangeAsync de Entity Framework Core para inserciones masivas:

using IronXL;

public class CsvImportService
{
    private readonly AppDbContext _context;

    public CsvImportService(AppDbContext context)
    {
        _context = context;
    }

    public async Task<int> ImportProductsAsync(Stream csvStream)
    {
        WorkBook workbook = WorkBook.LoadCSV(csvStream);
        WorkSheet ws = workbook.DefaultWorkSheet;
        var products = new List<Product>();

        foreach (var row in ws.Rows.Skip(1))
        {
            products.Add(new Product
            {
                Id = row.Columns[0].IntValue,
                Name = row.Columns[1].StringValue,
                Price = row.Columns[2].DecimalValue,
                Quantity = row.Columns[3].IntValue
            });
        }

        await _context.Products.AddRangeAsync(products);
        return await _context.SaveChangesAsync();
    }
}
using IronXL;

public class CsvImportService
{
    private readonly AppDbContext _context;

    public CsvImportService(AppDbContext context)
    {
        _context = context;
    }

    public async Task<int> ImportProductsAsync(Stream csvStream)
    {
        WorkBook workbook = WorkBook.LoadCSV(csvStream);
        WorkSheet ws = workbook.DefaultWorkSheet;
        var products = new List<Product>();

        foreach (var row in ws.Rows.Skip(1))
        {
            products.Add(new Product
            {
                Id = row.Columns[0].IntValue,
                Name = row.Columns[1].StringValue,
                Price = row.Columns[2].DecimalValue,
                Quantity = row.Columns[3].IntValue
            });
        }

        await _context.Products.AddRangeAsync(products);
        return await _context.SaveChangesAsync();
    }
}
Imports IronXL

Public Class CsvImportService
    Private ReadOnly _context As AppDbContext

    Public Sub New(context As AppDbContext)
        _context = context
    End Sub

    Public Async Function ImportProductsAsync(csvStream As Stream) As Task(Of Integer)
        Dim workbook As WorkBook = WorkBook.LoadCSV(csvStream)
        Dim ws As WorkSheet = workbook.DefaultWorkSheet
        Dim products As New List(Of Product)()

        For Each row In ws.Rows.Skip(1)
            products.Add(New Product With {
                .Id = row.Columns(0).IntValue,
                .Name = row.Columns(1).StringValue,
                .Price = row.Columns(2).DecimalValue,
                .Quantity = row.Columns(3).IntValue
            })
        Next

        Await _context.Products.AddRangeAsync(products)
        Return Await _context.SaveChangesAsync()
    End Function
End Class
$vbLabelText   $csharpLabel

Integración del servicio en la inyección de dependencias

Registrar CsvImportService en Program.cs para que el controlador pueda solicitarlo mediante inyección de constructor:

builder.Services.AddScoped<CsvImportService>();
builder.Services.AddScoped<CsvImportService>();
$vbLabelText   $csharpLabel

A continuación, actualiza el constructor del controlador para que acepte el servicio y llame a ImportProductsAsync en lugar de construir la lista en línea. Esta separación mantiene las acciones del controlador delgadas y mueve la lógica de acceso a datos a una clase de servicio comprobable. Entity Framework Core agrupa por lotes la llamada AddRangeAsync en una sola sentencia INSERT por lote, lo que funciona bien con ficheros CSV del SII que contienen miles de filas de operaciones.

Para importaciones muy grandes (decenas de miles de filas, habitual en el libro registro del SII de empresas con alto volumen), considere el uso de EF Core's Bulk Extensions o una sentencia SQL BULK INSERT para reducir los viajes de ida y vuelta a la base de datos.

¿Cómo se exportan datos de vuelta a CSV o XLSX con IronXL para remisión AEAT?

IronXL no se limita a leer archivos CSV, sino que también los escribe. El método SaveAsCsv exporta cualquier hoja de cálculo a un archivo CSV, útil para generar informes o enviar datos a sistemas posteriores —como el sistema de carga de operaciones en el portal de la AEAT para el modelo 347. Para remisiones en XLSX al Banco de España o a la CNMV, use SaveAs con formato XLSX:

using IronXL;

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLS);
WorkSheet ws = workbook.DefaultWorkSheet;

// Write headers
ws["A1"].Value = "Id";
ws["B1"].Value = "Name";
ws["C1"].Value = "Price";

// Write data rows
ws["A2"].Value = 1;
ws["B2"].Value = "Widget A";
ws["C2"].Value = 9.99;

ws["A3"].Value = 2;
ws["B3"].Value = "Widget B";
ws["C3"].Value = 14.49;

// Save as CSV
workbook.SaveAsCsv("export.csv");
Console.WriteLine("CSV export complete.");
using IronXL;

WorkBook workbook = WorkBook.Create(ExcelFileFormat.XLS);
WorkSheet ws = workbook.DefaultWorkSheet;

// Write headers
ws["A1"].Value = "Id";
ws["B1"].Value = "Name";
ws["C1"].Value = "Price";

// Write data rows
ws["A2"].Value = 1;
ws["B2"].Value = "Widget A";
ws["C2"].Value = 9.99;

ws["A3"].Value = 2;
ws["B3"].Value = "Widget B";
ws["C3"].Value = 14.49;

// Save as CSV
workbook.SaveAsCsv("export.csv");
Console.WriteLine("CSV export complete.");
Imports IronXL

Dim workbook As WorkBook = WorkBook.Create(ExcelFileFormat.XLS)
Dim ws As WorkSheet = workbook.DefaultWorkSheet

' Write headers
ws("A1").Value = "Id"
ws("B1").Value = "Name"
ws("C1").Value = "Price"

' Write data rows
ws("A2").Value = 1
ws("B2").Value = "Widget A"
ws("C2").Value = 9.99

ws("A3").Value = 2
ws("B3").Value = "Widget B"
ws("C3").Value = 14.49

' Save as CSV
workbook.SaveAsCsv("export.csv")
Console.WriteLine("CSV export complete.")
$vbLabelText   $csharpLabel

El archivo exportado utiliza delimitadores de coma de forma predeterminada. Para los archivos delimitados por punto y coma, comunes en las localizaciones europeas y en los ficheros CSV de la AEAT, llame a SaveAsCsv("export.csv", ";") con un argumento delimitador explícito. También puede guardar en un MemoryStream y devolver el resultado como una descarga de archivo desde un punto final de la API utilizando File(stream, "text/csv", "export.csv").

Para obtener información completa sobre las opciones de exportación, consulte la documentación de IronXL sobre guardar y exportar.

¿Por qué IronXL es mejor que el análisis manual de CSV para ficheros SII/AEAT?

El análisis manual de archivos CSV parece sencillo hasta que te encuentras con casos extremos habituales en los ficheros del SII: valores que contienen comas entre comillas (nombres de razones sociales), delimitadores de punto y coma (formato europeo AEAT), saltos de línea incrustados en una celda, comillas de escape y marcas de orden de bytes al principio de los archivos UTF-8. Manejar todo esto correctamente en un bucle StreamReader personalizado requiere pruebas significativas y un mantenimiento continuo.

IronXL aborda todos estos casos de forma interna. La comparación de los dos enfoques muestra claras ventajas:

IronXL frente a StreamReader manual para el análisis de CSV del SII/AEAT en C#
Capacidad IronXL Manual de StreamReader
Detección automática de delimitadores (coma, punto y coma — formato AEAT) No -- debe configurarse manualmente
Manejo de campos entrecomillados (razones sociales con comas) Integrado Requiere lógica personalizada
Conversión de tipos (int, decimal, DateTime) Accesores integrados Requiere llamadas a Parse/TryParse
Valores de celda de varias líneas Gestionado automáticamente Difícil de implementar correctamente
Gestión de la lista de materiales (BOM) Automático Requiere configuración de StreamReader
Compatibilidad con el formato Excel (XLSX, XLS) — para remisión AEAT en XLSX Misma API Requiere una biblioteca independiente
Exportar a CSV con delimitador europeo (;) Método SaveAsCsv con argumento delimitador Requiere lógica de escritura independiente

Coherencia entre formatos para compliance fiscal

Una de las ventajas prácticas de IronXL es que el mismo WorkBook.Load y patrón de iteración de hojas de trabajo funciona para archivos XLSX, XLS, ODS y CSV. Si su aplicación de compliance fiscal necesita aceptar tanto CSV del SII como XLSX del modelo 303 o del modelo 347, puede cambiar de formato sin modificar la lógica de análisis. Pase el flujo de archivos a WorkBook.Load y IronXL detectará el formato automáticamente basándose en la firma del archivo.

Esta API multiformato te permite escribir y probar una sola ruta de código en lugar de mantener implementaciones separadas para CSV y Excel. Para obtener una lista completa de los formatos compatibles, consulte la página de formatos de archivo compatibles con IronXL.

Consideraciones de rendimiento para ficheros CSV grandes del SII

Para ficheros CSV del SII de menos de 100 MB, IronXL funciona bien sin necesidad de ajustes. Para archivos más grandes (empresas con alto volumen de operaciones en el SII), considere estas estrategias:

  • Cargue el archivo desde una ruta en lugar de copiarlo en un MemoryStream para reducir la asignación de memoria.
  • Procese las filas por lotes al insertarlas en una base de datos, en lugar de recopilar todos los registros antes de la primera inserción.
  • Utilice ws.Rows.Skip(1) con LINQ para evitar materializar la fila de encabezado como un objeto de operación.

La guía de rendimiento de IronXL abarca optimizaciones adicionales para escenarios de importación de gran volumen, incluyendo el procesamiento paralelo y los modos de streaming.

¿Cuales son tus próximos pasos?

Ahora dispones de un patrón de trabajo para cada etapa de la importación de ficheros CSV del SII/AEAT en ASP.NET Core: instalación de la biblioteca en entornos Linux/Docker, carga de archivos desde el disco o flujos cargados, asignación de filas a objetos de modelo tipados (operaciones SII, datos modelo 347), aplicación de filtros LOPDGDD antes de la inserción en base de datos, almacenamiento de registros con Entity Framework Core y exportación de datos de vuelta a CSV o XLSX para remisión a la AEAT, al Banco de España o a la CNMV.

Para ampliar esta base, explore estos recursos:

Con IronXL en su proyecto, la adición de soporte para cargas XLSX junto con CSV del SII no requiere cambios de código adicionales — la misma llamada WorkBook.Load maneja ambos. Esa coherencia significa que puede ampliar el conjunto de funciones de su punto final de importación de forma incremental a medida que crecen los requisitos de compliance fiscal de su aplicación.

Preguntas Frecuentes

¿Cómo puedo importar ficheros CSV del SII de la AEAT en ASP.NET Core con IronXL?

Con IronXL puede importar ficheros CSV del SII (Suministro Inmediato de Información) en ASP.NET Core usando WorkBook.LoadCSV. IronXL detecta automáticamente el delimitador (coma o punto y coma europeo), gestiona campos con comillas y mapea los valores a objetos tipados con NIF, razón social e importe.

¿Cuáles son los beneficios de usar IronXL para importar CSV del modelo 347 de la AEAT?

IronXL ofrece detección automática de delimitadores (incluyendo el punto y coma europeo usado en ficheros AEAT), conversión de tipos integrada, compatibilidad con Linux/Docker sin Office, y una API unificada para CSV, XLSX y XLS — ideal para aplicaciones de compliance del modelo 347.

¿Cómo se aplica la LOPDGDD al importar CSV del SII con IronXL?

Tras parsear el CSV del SII con IronXL, filtre los campos del objeto de modelo para eliminar datos personales que no sean estrictamente necesarios para el cumplimiento fiscal antes de insertar en la base de datos. Esto aplica el principio de minimización de datos de la LOPDGDD.

¿Puede IronXL parsear datos CSV del SII en objetos de clase modelo tipados?

Sí, IronXL puede parsear datos CSV del SII en objetos de clase de modelo con campos como NIF_Tercero, RazonSocial, ImporteTotal y EjercicioFiscal, usando accesores StringValue, DecimalValue e IntValue para conversión automática de tipos.

¿Cómo ayuda IronXL con la exportación de datos del SII a XLSX para remisión al Banco de España?

IronXL permite exportar los datos CSV del SII procesados a XLSX mediante SaveAs. Para remisiones al Banco de España o la CNMV que requieren formato XLSX, use WorkBook.Create(ExcelFileFormat.XLSX) y SaveAs. Para CSV con delimitador europeo, use SaveAsCsv('export.csv', ';').

¿Es posible devolver registros CSV del SII como JSON usando IronXL?

Sí, con IronXL puedes parsear los registros CSV del SII a objetos tipados y devolverlos como JSON desde un controlador ASP.NET Core, lo que es útil para portales web de compliance fiscal o para integración con sistemas de remisión a la AEAT.

¿IronXL admite importaciones de ficheros CSV grandes del SII (alto volumen de operaciones)?

Sí, IronXL está diseñado para manejar importaciones de archivos CSV de gran tamaño. Para empresas con alto volumen de operaciones en el SII, procese las filas por lotes usando ws.Rows.Skip(1) con LINQ y AddRangeAsync de Entity Framework Core para inserciones masivas eficientes.

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 ...

Leer más

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame