Read and parse CSV files in C#/.NET

CSV (Comma-Separated Values) files remain one of the most widely used formats for data exchange between applications. Whether you’re processing financial data, user records, or analytics reports, efficiently reading CSV files in C# is a common task in .NET development.

In this comprehensive guide, we'll explore how to parse CSV files in C# using Spire.XLS for .NET, covering both direct reading and converting CSV to DataTable.


Install the C# CSV File Reader Library

While primarily designed for Excel files, Spire.XLS can also be used as a .NET CSV reader. It provides excellent support for CSV files, offering a range of features that make CSV processing efficient and straightforward.

The first step is to install the Spire.XLS package in your project. Here's how:

  • Open your project in Visual Studio
  • Right-click on your project in the Solution Explorer
  • Select "Manage NuGet Packages"
  • In the NuGet Package Manager, search for "Spire.XLS"
  • Click "Install" to add the package to your project

Alternatively, you can install it using the Package Manager Console:

PM> Install-Package Spire.XLS

This will add the necessary dependencies to your project, allowing you to use Spire.XLS classes.


Read a CSV File in C#

Let's start with the fundamentals: reading a simple CSV file and extracting its data. The C# code example below loads a CSV file, accesses its data, and prints the contents to the console in a tabular format.

using Spire.Xls;

namespace ReadCSV
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a workbook instance
            Workbook workbook = new Workbook();

            // Load the CSV file
            workbook.LoadFromFile("sample.csv", ",");

            // Get the first worksheet
            Worksheet sheet = workbook.Worksheets[0];

            // Get the used range
            CellRange range = sheet.AllocatedRange;

            // Iterate through rows and columns
            for (int row = 1; row <= range.RowCount; row++)
            {
                for (int col = 1; col <= range.ColumnCount; col++)
                {
                    // Get cell value
                    string cellValue = range[row, col].Value;
                    Console.Write(cellValue + "\t");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
}

Explanation:

  • Workbook class: Acts as a "container" for your CSV file in memory. Even though CSV isn’t a full Excel file, Spire.Xls treats it as a single-sheet workbook for consistency.
  • Workbook.LoadFromFile(): Loads the CSV file. The parameters are:
    • File path: "sample.csv".
    • Delimiter: "," (comma, default for CSV).
  • Worksheet.AllocatedRange: Retrieves only the cells that contain data.
  • CellRange[row, col].Value: Retrieves the value of a specific cell.

Result: CSV data printed in a clean, tab-separated format.

Read a CSV file to the console in C#

If you need a demo for reading CSV files in VB.NET, convert the code directly using the C# to VB.NET converter.


Read CSV into a DataTable in C#

A DataTable is a versatile in-memory data structure in .NET that simplifies data manipulation (e.g., filtering, sorting, or binding to UI components). Here’s how to load CSV data into a DataTable using Spire.XLS:

using Spire.Xls;
using System.Data;

namespace ReadCSV
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a workbook instance
            Workbook workbook = new Workbook();

            // Load the CSV file
            workbook.LoadFromFile("sample.csv", ",");

            // Get the first worksheet
            Worksheet worksheet = workbook.Worksheets[0];

            // Export data from the worksheet to a DataTable 
            DataTable dataTable = worksheet.ExportDataTable();

            // Get row and column count
            Console.WriteLine("\nConversion complete! DataTable information:");
            Console.WriteLine($"Number of columns: {dataTable.Columns.Count}");
            Console.WriteLine($"Number of rows: {dataTable.Rows.Count}");
            Console.WriteLine();

            // Print column names
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                Console.Write(dataTable.Columns[i].ColumnName + "  | ");
            }
            Console.WriteLine();
            Console.WriteLine("----------------------------------------------------------");

            // Print row data
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                for (int j = 0; j < dataTable.Columns.Count; j++)
                {                
                    string value = dataTable.Rows[i][j].ToString();

                    Console.Write(value + "\t");
                }
                Console.WriteLine(); 
            }
        }
    }
}

Explanation:

  • Worksheet.ExportDataTable(): Converts the entire CSV worksheet into a DataTable.
  • Metadata Access: DataTable.Columns.Count and DataTable.Rows.Count shows the size of your dataset, helping you verify that the import was successful.
  • Column Headers and Data Output: Iterates through to display column names and row data.

Result: Structured output with metadata, headers, and rows:

Convert a CSV file to a DataTable in C#

To analyze, calculate, or format the data, you can convert CSV to Excel in C#.


When to Use Each Method

Choose the right approach based on your goal:

Method Best For Use Case Example
Direct CSV Reading Quick data verification Checking if a CSV is loaded correctly.
Convert to DataTable Advanced data processing Filtering rows, sorting, or saving to SQL Server.

Conclusion​

Reading CSV files in C# is streamlined with Spire.XLS for .NET, and converting CSV data to a DataTable adds flexibility for data manipulation. Whether you’re working with small datasets or large files, Spire.XLS offers flexible options to meet your requirements.

The code examples in this guide are ready to use - just copy, paste, and adjust for your CSV file path. For more advanced features, refer to Spire.XLS’s official documentation.


FAQs (Common Questions)

Q1: Why choose Spire.XLS for CSV reading?

A: While the .NET Framework offers built-in StreamReader for CSV handling, Spire.XLS provides several distinct advantages:

  • No dependencies: Doesn't require Microsoft Excel or Office to be installed
  • High performance: Optimized for handling large CSV files efficiently
  • Flexibility: Multiple ways to read CSV data based on your needs
  • Cross-platform: Works with .NET Framework, .NET Core, .NET Standard, and Mono

Q2: Can I use a different delimiter (e.g., semicolon or tab)?

A: Yes. Replace the second parameter of LoadFromFile() method with your delimiter:

// For tab-delimited files
workbook.LoadFromFile("data.txt", "\t");

// For semicolon-delimited files
workbook.LoadFromFile("data.csv", ";");

// For pipe-delimited files
workbook.LoadFromFile("data.csv", "|");

Q3: Can I read specified rows or columns from a CSV file?

A: Yes. You can target a precise subset of your data by defining exact row and column boundaries. This is useful for extracting specific information (e.g., skipping headers, focusing on relevant columns) without processing the entire file.

For example:

// Define the specific range
int startRow = 2;   // Start from row 2 (skip header)
int endRow = 4;     // End at row 4
int startCol = 2;   // Start from column 2
int endCol = 6;     // End at column 6


// Loop through rows and columns
for (int row = startRow; row <= endRow; row++)
{
   for (int col = startCol; col <= endCol; col++)
   {
      // Get cell value
      string cellValue = worksheet.Range[row, col].Value;
      Console.Write(cellValue + "\t"); 

Note: Spire.Xls uses 1-based indexing (like Excel), so the first row/column is numbered 1 (not 0).

Spire.PDFViewer for MAUI is a dedicated PDF viewing component tailored for .NET Multi-platform App UI (MAUI) frameworks. This guide will show you how to configure it in your .NET MAUI project, including environment setup, product installation, and core PDF viewing feature implementation.

1. Prerequisites & Environment Setup

Ensure your development environment meets the following requirements before you begin.

1.1 Required Software

  • IDE: Visual Studio 2022 (version 17.8 or later) for Windows, or Visual Studio 2022 for Mac (version 17.6 or later).
  • Target Frameworks:
    • Android 5.0 (API 21) or higher
    • Windows 11, or Windows 10 Version 1809 or higher

1.2 Install the .NET MAUI Workload

The .NET Multi-platform App UI development workload is mandatory for MAUI projects. Follow these steps to install it:

  • Open Visual Studio Installer:
    • Search for "Visual Studio Installer" in your Start Menu (usually under the "Visual Studio 2022" folder).
    • Alternatively, open Visual Studio, go to “Tools > Get Tools and Features”.
  • Modify Your Installation:
    • Click "Modify" next to your Visual Studio 2022 edition.
    • Navigate to the "Workloads" tab.
    • Check the box for ".NET Multi-platform App UI development".
    • Ensure the optional components you need are selected.
    • Click "Modify" to start the installation

Select the .NET MAUI workload in Visual Studio Installer

2. Create a New .NET MAUI Project

After installing MAUI, follow these steps to create a new .NET MAUI project:

2.1 Select the Project Template

  • Open Visual Studio and click “Create a new project”.
  • Search for "MAUI" and select the .NET MAUI App template (C#).
  • Click “Next” to proceed.

Choose the .NET MAUI App template

2.2 Configure Project Details

  • Enter a project name (e.g., "PdfViewerMauiApp") and choose a Save location.
  • Next, select .NET 7.0 or later (e.g., .NET 8.0) as the target framework.
  • Click “Create” to generate the project.

Select the .NET framework version

3. Install Spire.PDFViewer and Dependencies

To implement the PDF viewer in .NET MAUI, you need to install the dependent NuGet packages and add Spire.PDFViewer DLLs.

3.1 Install Dependent NuGet Packages

  • Go to “Tools > NuGet Package Manager > Package Manager Console”.
  • Run the following command to install all required packages at once:
Install-Package Microsoft.Win32.Registry -Version 5.0.0
Install-Package System.Security.Permissions -Version 4.7.0
Install-Package System.Text.Encoding.CodePages -Version 4.7.0
Install-Package System.Security.Cryptography.Pkcs -Version 4.7.0
Install-Package System.Security.Cryptography.Xml -Version 4.7.1
Install-Package HarfBuzzSharp -Version 8.3.0.1
Install-Package SkiaSharp -Version 3.116.1
Install-Package SkiaSharp.Views.Maui.Controls -Version 2.88.5
Install-Package System.Buffers -Version 4.5.1
Install-Package System.Memory -Version 4.5.5

3.2 Add Spire.PDFViewer DLLs

  • Download the Spire.PdfViewer package from the official website.
  • Unzip the downloaded file to a specified file path.
  • In Visual Studio’s Solution Explorer, right-click the project > Add > Project Reference.
  • Click “Browse”, navigate to the unzipped folder (BIN\NET7.0\windows10.0.19041.0), and add both:
    • Spire.PdfViewer.Maui.dll
    • Spire.Pdf.dll

Add dependencies and Spire.PDFViewer dlls

3.3 Restrict Target Platform to Windows

Currently, the Spire.PDFViewer for MAUI only supports the Windows platform. Therefore, it’s necessary to modify the project file (.csproj) to remove non-Windows target frameworks:

  • In Solution Explorer, right-click the project and select “Edit Project File”.
  • Locate the <TargetFrameworks> element and delete or comment out this line.
  • Save the file (Ctrl+S) and reload the project when prompted by Visual Studio.

Remove non-Windows target frameworks

4. Add PDF Viewer to the Project

4.1 Initialize Spire.PDFViewer

In “MauiProgram.cs”, add the .UseSpirePdfViewer() method in the MauiAppBuilder chain:

Add Spire.PDFViewer initialization code

4.2 Option 1: Use the Default PDF Viewer UI

For a quick setup with a pre-built toolbar (supports loading, zooming, and searching), use the minimal XAML configuration:

  • Replace the default XAML content of “MainPage.xaml” with the following:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:spire="clr-namespace:Spire.PdfViewer.Maui;assembly=Spire.PdfViewer.Maui"
             x:Class="PdfViewerMauiApp.MainPage"> <!-- Modify “PdfViewerMauiApp” to match your project name -->
    
    <Grid ColumnDefinitions="Auto, *" ColumnSpacing="0">
        <!-- Default PDF Viewer with built-in toolbar -->
        <spire:PdfViewer x:Name="PdfDocumentViewer1" Grid.Column="1" />
    </Grid>
</ContentPage>
  • Open “MainPage.xaml.cs” and ensure the namespace matches your project name:
namespace PdfViewerMauiApp; // Match the project name in the x:Class value

public partial class MainPage : ContentPage
{

    public MainPage()
    {
        InitializeComponent();
    }

}

Configure the default PDF viewer

When you run the project, a PDF viewer with a built-in toolbar (Home, Zoom, Find) will appear. You can load PDFs directly via the toolbar and use its default features.

Default Spire.PDFViewer with built-in toolbar

4.3 Option 2: Customize the UI Layout & Functionality

For a tailored experience (e.g., a dedicated "Load PDF" button or page navigation), design a custom layout and implement core logic.

Step 1: Design the Custom UI (MainPage.xaml)

Replace the default XAML content of “MainPage.xaml” with a two-column grid (left: control panel; right: PDF viewer):

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:spire="clr-namespace:Spire.PdfViewer.Maui;assembly=Spire.PdfViewer.Maui"
             x:Class="PdfViewerMauiApp.MainPage"> <!-- Modify “PdfViewerMauiApp” to match your project name -->
    
    <Grid ColumnDefinitions="Auto, *" ColumnSpacing="0">
        <!-- Left Control Panel -->
        <VerticalStackLayout Grid.Column="0" WidthRequest="220"
                           Padding="10" Spacing="10">
            <!-- Button to load PDF files -->
            <Button Text="Load PDF File"
                   Clicked="LoadFromFile_Clicked"
                   HeightRequest="40"/>

            <!-- Page Navigation: Entry + Button -->
            <HorizontalStackLayout Spacing="10">
                <Entry x:Name="pageEntry"
                       WidthRequest="100"
                       HeightRequest="40"
                       Keyboard="Numeric"
                       Placeholder="Page Number"/>

                <Button Text="Go To"
                       Clicked="GoPages_Clicked"
                       WidthRequest="80"
                       HeightRequest="40"/>
            </HorizontalStackLayout>
            <Label x:Name="lbl1" HeightRequest="30"/>
        </VerticalStackLayout>

        <!-- Right PDF Viewing Area -->
        <spire:PdfDocumentViewer x:Name="PdfDocumentViewer1" Grid.Column="1" />
    </Grid>
</ContentPage>

Step 2: Add Functionality (MainPage.xaml.cs)

Add event handlers in “MainPage.xaml.cs” to enable PDF loading and page navigation:

namespace PdfViewerMauiApp; // Match your project name

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        // Click event for the Load PDF File button
        private async void LoadFromFile_Clicked(object sender, EventArgs e)
        {
            try
            {
                // Restrict file picker to PDF files only
                var result = await FilePicker.PickAsync(new PickOptions
                {
                    FileTypes = FilePickerFileType.Pdf,
                    PickerTitle = "Choose a PDF file"
                });

                if (result != null)
                {
                    // Load the PDF file from the selected path
                    PdfDocumentViewer1.LoadFromFile(result.FullPath);

                }
            }
            catch (Exception ex)
            {
                // Display error message
                lbl1.Text = $"Loading failed: {ex.Message}";
            }
        }

        // Click event for page navigation button
        private void GoPages_Clicked(object sender, EventArgs e)
        {
             
            if (int.TryParse(pageEntry.Text, out int pageNumber) && pageNumber > 0)
            {
                    // Verify that the page number is within the valid range.
                if (pageNumber <= PdfDocumentViewer1.PageCount)
                 {
                        // Jump to a specific page number
                     PdfDocumentViewer1.GotoPage(pageNumber, true);
                     lbl1.Text = $"Navigated to Page: {pageNumber}/{PdfDocumentViewer1.PageCount}";
                 }
                 else
                 {
                     lbl1.Text = $"Out of Range (Max Page: {PdfDocumentViewer1.PageCount})";
                 }
             }
             else
             {
                 lbl1.Text = "Please enter a valid page number.";
             }
         }
     }

Step 3: Run the Project

Run the application, and test the PDF viewer functionality:

  • Click “Load PDF File” to select and open a PDF.

  • Enter a page number and click “Go To” to navigate to that page.

Custom PDF viewer with page navigation

Integrating Spire.PDFViewer into a .NET MAUI project enables developers to quickly add robust, user-friendly PDF viewing capabilities, including document loading, page navigation, and built-in/ custom UI controls. By following the steps outlined here, developers can avoid common pitfalls (e.g., version mismatches, missing dependencies) and deploy a functional PDF viewer in minimal time.

Write to Excel in C#

Excel remains one of the most widely used tools for managing and analyzing data due to its powerful features and user-friendly interface. In C# applications, developers often need to generate reports, export database results, or automate tasks by writing directly to Excel files.

To achieve this efficiently, developers often turn to third-party libraries. Spire.XLS for .NET makes it simple to write to Excel programmatically without relying on Microsoft Excel. With Spire.XLS, you can insert text, numbers, dates, formulas, or even bulk datasets such as arrays, DataTables, and lists into Excel worksheets. This provides a fast, flexible, and reliable way to automate Excel writing in C# applications.

On this page:

Getting Started with Spire.XLS for .NET

What’s Spire.XLS for .NET

Spire.XLS for .NET is a professional .NET Excel library developed by E-iceblue. It allows developers to write to Excel files in C# and perform a wide range of operations including creating, editing, reading, and exporting Excel documents—without requiring Microsoft Excel to be installed.

Key features include:

  • Write and update Excel files programmatically.
  • Support for Excel formats (XLS, XLSX, CSV, ODS).
  • Advanced features such as formulas, charts, pivot tables, and data validation.
  • Export Excel to PDF, HTML, and image formats.
  • High performance with large datasets, suitable for desktop, server, and web applications.

How to Install Spire.XLS for .NET

Option 1: Install via NuGet (recommended)

  • Open Visual Studio.
  • Navigate to Tools > NuGet Package Manager > Manage NuGet Packages for Solution.
  • Search for Spire.XLS and install it.

Or, install it directly using the Package Manager Console :

PM> Install-Package Spire.XLS

Option 2: Manual installation

Once installed, you’re ready to start writing to Excel in C#.

How to Create a New Excel File in C#

The first step is to create a new workbook and add a worksheet. Here’s how:

using Spire.Xls;

namespace CreateNewExcel
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a new workbook
            Workbook workbook = new Workbook();

            // Remove default worksheets
            workbook.Worksheets.Clear();

            // Add a worksheet
            Worksheet sheet = workbook.Worksheets.Add("Report");

            // Save the empty Excel file
            workbook.SaveToFile("NewExcelFile.xlsx", ExcelVersion.Version2016);
            workbook.Dispose();
        }
    }
}

At this point, you have created an empty Excel file with a worksheet named “Report”. Next, let’s write data into it.

Write Different Data Types to Excel Cells in C#

Spire.XLS allows you to write various data types directly to Excel cells. Below are common examples:

Write Text Values

sheet.Range["A1"].Text = "Hello Excel!";

Write Numeric Values

sheet.Range["A2"].NumberValue = 123.45;

Write Date and Time

sheet.Range["A3"].DateTimeValue = DateTime.Now;
sheet.Range["A3"].NumberFormat = "yyyy-mm-dd hh:mm";

Write Boolean Values

sheet.Range["A4"].BooleanValue = true;

Write TimeSpan Values

sheet.Range["A5"].TimeSpanValue = new TimeSpan(2, 30, 0); // 2 hours 30 minutes;
sheet.Range["A5"].NumberFormat = "[h]:mm:ss";

Insert Formulas

sheet.Range["A6"].Formula = "=SUM(A2,100)";

Insert HTML Formatted Strings

string htmlText = "<span style=\"font-family: Times New Roman; color: blue; font-size: 15pt;\">Hello
<strong>Spire.XLS</strong></span>";
sheet.Range["A7"].HtmlString = htmlText;

Write General Values Without Specific Type

sheet.Range["A8"].Value = "General Value";

Output:

C# Write various data types to Excel

You might also be interested in: How to Read Excel Files in C#

Write Bulk Data to Excel Sheets in C#

When dealing with larger datasets, writing values cell by cell isn’t efficient. Spire.XLS provides methods to insert arrays , and DataTables directly. Other data structures can be converted to arrays or DataTables before being written to the Excel sheet.

Write Arrays to Excel

Spire.XLS provides the Worksheet.InsertArray(string[] stringArray, int firstRow, int firstColumn, bool isVertical) method, allowing developers to insert one-dimensional or two-dimensional arrays into a specified range of cells in a worksheet.

string[,] data = {
    { "Name", "Age", "Country" },
    { "Alice", "30", "USA" },
    { "Bob", "28", "UK" },
    { "Charlie", "35", "Canada" }
};
sheet.InsertArray(data, 1, 1);

Output:

Insert Array to Excel in C#

Write DataTables to Excel

To import data from a DataTable to a worksheet, use the Worksheet.InsertDataTable(DataTable dataTable, bool columnHeaders, int firstRow, int firstColumn, bool transTypes) method.

using System.Data;

DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Product", typeof(string));
dt.Columns.Add("Price", typeof(double));

// Add rows
dt.Rows.Add(1, "Laptop", 1200.5);
dt.Rows.Add(2, "Tablet", 450.99);
dt.Rows.Add(3, "Phone", 799.0);

// Insert DataTable starting at cell A1
sheet.InsertDataTable(dt, true, 1, 1, true);

Output:

Insert DataTable to Excel in C#

On the contrary, you can export data from Excel to DataTable by using the ExportDataTable method of the Worksheet class.

Write Lists to Excel

While Spire.XLS does not provide a direct method for writing lists to Excel, you can convert lists to a DataTable and then use the InsertDataTable method to write the DataTable to Excel.

using Spire.Xls;
using System.Data;

namespace WriteListToExcel
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a Workbook instance
            Workbook workbook = new Workbook();

            // Remove default worksheets
            workbook.Worksheets.Clear();

            // Add a worksheet and name it
            Worksheet worksheet = workbook.Worksheets.Add("Students");

            // Create a list with student data
            List<Student> students = new List<Student>
            {
                new Student("Michael", "Johnson", 20, "Computer Science", 3.8),
                new Student("Sarah", "Williams", 22, "Mathematics", 3.6),
                new Student("Jessica", "Brown", 19, "Physics", 3.9),
                new Student("David", "Smith", 21, "Chemistry", 3.7),
                new Student("Emily", "Davis", 23, "Biology", 3.5)
            };

            // Convert the list to DataTable
            DataTable dataTable = ConvertListToDataTable(students);

            // Write DataTable to the worksheet
            worksheet.InsertDataTable(dataTable, true, 1, 1, true);

            // Set column width
            worksheet.AllocatedRange.ColumnWidth = 12;

            // Align content to left
            worksheet.AllocatedRange.HorizontalAlignment = HorizontalAlignType.Left;

            // Save to an Excel file
            workbook.SaveToFile("InsertStudents.xlsx", ExcelVersion.Version2016);

            // Dispose resources
            workbook.Dispose();
        }

        static DataTable ConvertListToDataTable(List<Student> students)
        {
            DataTable dataTable = new DataTable();

            // Add columns
            dataTable.Columns.Add("FirstName", typeof(string));
            dataTable.Columns.Add("LastName", typeof(string));
            dataTable.Columns.Add("Age", typeof(int));
            dataTable.Columns.Add("Major", typeof(string));
            dataTable.Columns.Add("GPA", typeof(double));

            // Add rows
            foreach (var student in students)
            {
                DataRow row = dataTable.NewRow();
                row["FirstName"] = student.FirstName;
                row["LastName"] = student.LastName;
                row["Age"] = student.Age;
                row["Major"] = student.Major;
                row["GPA"] = student.GPA;
                dataTable.Rows.Add(row);
            }

            return dataTable;
        }
    }

    class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string Major { get; set; }
        public double GPA { get; set; }

        public Student(string firstName, string lastName, int age, string major, double gpa)
        {
            FirstName = firstName;
            LastName = lastName;
            Age = age;
            Major = major;
            GPA = gpa;
        }
    }
}

Output:

Insert List to Excel in C#

Save and Export Excel Files

After writing data, you’ll want to save or export the Excel file. Spire.XLS supports multiple formats including XLSX, CSV, and PDF .

// Save as XLSX
workbook.SaveToFile("Output.xlsx", ExcelVersion.Version2016);

// Save as CSV
workbook.SaveToFile("Output.csv", ",", Encoding.UTF8);

// Export as PDF
workbook.SaveToFile("Output.pdf", FileFormat.PDF);

For web applications, you can also save to a MemoryStream :

using (MemoryStream ms = new MemoryStream())
{
    workbook.SaveToStream(ms, FileFormat.Version2016);
    // Write to Response in ASP.NET if needed
}

Common Issues and Solutions

1. Incorrect Date or Time Format

Issue: Dates/times appear as serial numbers.

Solution :

  • Apply a proper number format to the cell:
sheet.Range["A1"].DateTimeValue = DateTime.Now;
sheet.Range["A1"].NumberFormat = "yyyy-mm-dd hh:mm";

2. Data Overwriting or Misaligned

Issue : Writing arrays or DataTables overwrites existing data unintentionally.

Solution :

  • Check firstRow and firstColumn parameters in InsertArray() or InsertDataTable().
  • Use separate worksheets or offset ranges if necessary.

3. Large Dataset Performance Issues

Issue : Writing thousands of rows is slow.

Solution :

  • Use bulk writing methods instead of looping cell by cell.
  • Apply styles after inserting data to avoid repeated formatting overhead.

4. Formula Not Calculating Correctly

Issue : Excel formulas inserted via sheet.Range["A1"].Formula do not return expected results.

Solution :

  • Ensure the formula syntax is correct for Excel (e.g., =SUM(A2:A10)).
  • Call workbook.CalculateAllValue() to update all formulas before saving if needed.

Conclusion

Writing to Excel in C# doesn’t have to be complex. With Spire.XLS for .NET , you can seamlessly write different data types—whether individual values or large datasets—into Excel worksheets. The library also provides support for styling, formulas, and advanced formatting, ensuring your Excel files are not only accurate but also presentation-ready.

By using efficient bulk-writing techniques like arrays and DataTables, you can handle both small and large data operations with ease. If your goal is to write to Excel files quickly and reliably , Spire.XLS gives you the tools you need—without the overhead of Microsoft Excel.

FAQs

Q1. Can I write to an existing Excel file with Spire.XLS?

Yes. Use workbook.LoadFromFile("file.xlsx") to open an existing file, then modify and save it.

Q2. Does Spire.XLS require Microsoft Excel to be installed?

No. It’s a standalone library that works without Excel.

Q3. Can Spire.XLS handle large Excel files with thousands of rows?

Yes. It’s optimized for high performance with large datasets.

Q4. How do I format cells while writing data?

You can style cells using properties like font, color, borders, and alignment:

sheet.Range["A1"].Style.Font.IsBold = true;
sheet.Range["A1"].Style.Color = Color.Yellow;
sheet.Range["A1"].Style.HorizontalAlignment  = HorizontalAlignType.Left;

Get a Free License

To fully experience the capabilities of Spire.XLS for .NET without any evaluation limitations, you can request a free 30-day trial license.

Create PDF in ASP.NET Core

Creating PDFs in ASP.NET applications is a common requirement, whether you're generating invoices, reports, forms, or exporting dynamic content. To streamline this process, you can utilize Spire.PDF for .NET, a professional and lightweight library that enables developers to easily create and manipulate PDF documents programmatically, without the need for complex APIs or third-party printer drivers.

In this tutorial, we’ll show you how to create PDF documents in an ASP.NET Core Web application using Spire.PDF for .NET, with examples of creating a PDF from scratch and converting HTML to PDF.

On this page:

Why Use Spire.PDF for .NET?

There are many ways to create PDF in ASP.NET, but most involve trade-offs: some depend on printer drivers, others have limited layout control, and many require heavy third-party frameworks. Spire.PDF for .NET offers a more streamlined approach. It’s a dedicated .NET library that handles the majority of PDF creation and manipulation tasks on its own, without external tools.

Key advantages include:

  • No Adobe dependency – Generate and manage PDFs without Acrobat installed.
  • Full-featured PDF toolkit – Beyond creation, you can edit, merge, split, protect, or annotate PDFs.
  • High-fidelity rendering – Preserve fonts, CSS, images, and layouts when exporting content.
  • ASP.NET ready – Compatible with both ASP.NET Web Forms/MVC and ASP.NET Core projects.
  • Flexible generation options – Create PDFs from scratch, images, or streams.

(Note: HTML-to-PDF conversion requires a lightweight external plugin such as Qt WebEngine.)

Step-by-Step: Generate PDF in ASP.NET Core Web App

Step 1. Create a New ASP.NET Core Web App

  • Open Visual Studio .
  • Select Create a new project .
  • Choose ASP.NET Core Web App (Model-View-Controller) → Click Next .
  • Enter a project name, e.g., PdfDemoApp.
  • Select your target framework (e.g., . NET 6 , 7 , or 8 ).
  • Click Create .

Step 2. Install Spire.PDF via NuGet

  • Right-click on your project → Manage NuGet Packages .
  • Search for Spire.PDF .
  • Install the package Spire.PDF (latest stable version).

Or install using the Package Manager Console :

Install-Package Spire.PDF

Step 3. Add a Controller for PDF Generation

  • Right-click on the Controllers folder → Add → Controller → MVC Controller – Empty .
  • Name it: PdfController.cs.
  • Replace the default code with this:
using Microsoft.AspNetCore.Mvc;
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

namespace PdfDemoApp.Controllers
{
    public class PdfController : Controller
    {
        public IActionResult CreatePdf()
        {
            // Create a new PDF document
            PdfDocument doc = new PdfDocument();
            PdfPageBase page = doc.Pages.Add(PdfPageSize.A4, new PdfMargins(40));

            // Draw text on the page
            PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 25f);
            PdfSolidBrush brush = new PdfSolidBrush(Color.Black);
            page.Canvas.DrawString("Hello from ASP.NET Core!", font, brush, 10, 50);

            // Save to memory stream
            using (MemoryStream ms = new MemoryStream())
            {
                doc.SaveToStream(ms);
                doc.Close();
                ms.Position = 0;

                // Return PDF file
                return File(ms.ToArray(), "application/pdf", "Generated.pdf");
            }
        }
    }
}

Step 4: (Optional) Add a Button or Link in Your View

Open Views/Home/Index.cshtml (or whichever view is your homepage).

Add a button or link like this:

<div>
    <a asp-controller="Pdf" asp-action="CreatePdf" class="btn btn-primary">
        Create PDF from Scratch
    </a>
</div>

This uses ASP.NET Core tag helpers to generate the correct route (/Pdf/CreatePdf).

Step 5. Run and Test

  • Press F5 to run your app.
  • On the home page, click the "Create PDF from Scratch" button. This will call the CreatePdf method in PdfController and trigger a download of the generated PDF.
  • If you didn’t add the button, you can still run the CreatePdf method directly by visiting this URL in your browser:

https://localhost:xxxx/Pdf/CreatePdf

(where xxxx is your local port number).

Output:

Create PDF from ASP.NET Core

In addition to text, Spire.PDF supports adding a wide range of elements to PDF, such as images, shapes, tables, lists, hyperlinks, annotations, and watermarks. For more details and advanced usage, check the .NET PDF Tutorials.

Create PDF from HTML in ASP.NET Core

Spire.PDF allows you to convert HTML content directly into PDF files. This feature is particularly useful for generating invoices, reports, receipts, or exporting styled web pages with consistent formatting.

To render HTML as PDF, Spire.PDF relies on an external rendering engine. You can choose between Qt WebEngine or Google Chrome . In this guide, we’ll use Qt WebEngine .

Setup the Qt plugin:

  1. Download the Qt WebEngine plugin for your operating system:

  2. Extract the package to obtain the plugins directory, e.g.: C:\plugins-windows-x64\plugins

  3. Register the plugin path inyour code:

HtmlConverter.PluginPath = @"C:\plugins-windows-x64\plugins";

Once the plugin is ready, you can follow the steps from the previous section and add the code snippet below to your controller to generate PDF output from HTML content.

using Microsoft.AspNetCore.Mvc;
using Spire.Additions.Qt;
using Spire.Pdf.Graphics;
using System.Drawing;

namespace PdfDemoApp.Controllers
{
    public class PdfController : Controller
    {
        [HttpGet]
        public IActionResult HtmlToPdf()
        {
            // Example HTML string
            string html = @"
                <html>
                  <head>
                    <style>
                      body { font-family: Arial, sans-serif; }
                      h1 { color: #2563eb; }
                    </style>
                  </head>
                  <body>
                    <h1>ASP.NET Core: Create PDF from HTML</h1>
                    <p>This PDF was generated using the Qt-based converter.</p>
                  </body>
                </html>";

            // Path to the Qt plugin folder
            // ⚠️ Ensure this folder exists on your server/deployment environment
            string pluginPath = @"C:\plugins-windows-x64\plugins";
            HtmlConverter.PluginPath = pluginPath;

            // Create a temp file path (on server side)
            string tempFile = Path.GetTempFileName();

            // Convert HTML string → PDF using Qt
            HtmlConverter.Convert(
                html,
                tempFile,
                enableJavaScript: true,
                timeout: 100000,                        // milliseconds
                pageSize: new SizeF(595, 842),          // A4 page size in points
                margins: new PdfMargins(40),            // 40pt margins
                LoadHtmlType.SourceCode                 // Load from HTML string
            );

            // Read the generated PDF into memory
            byte[] fileBytes = System.IO.File.ReadAllBytes(tempFile);

            // Clean up temp file
            System.IO.File.Delete(tempFile);

            // Return PDF to browser as download
            return File(fileBytes, "application/pdf", "HtmlToPdf.pdf");
        }
    }
}

Output:

Create PDF from HTML ASP.NET

This example converts inline HTML into a properly formatted PDF. You can also load external HTML files or URLs - see our detailed guide on Convert HTML to PDF in C# for more information.

Best Practices for ASP.NET PDF Generation

  • Use memory streams instead of disk storage for performance and scalability.
  • Cache static PDFs (like terms & conditions or forms) to reduce server load.
  • Use HTML-to-PDF for dynamic reports with CSS styling.
  • Consider templates (like Word-to-PDF with Spire.Doc) when documents have complex layouts.
  • Secure sensitive PDFs with password protection or access permissions.

Conclusion

With Spire.PDF for .NET, you can easily generate PDF in ASP.NET Core applications. Whether you’re creating PDFs from scratch or performing HTML-to-PDF conversion in C# , Spire.PDF provides a reliable, developer-friendly solution—no external dependencies required.

If you also need to generate PDFs from Word documents, that feature is available via Spire.Doc for .NET, another product in the Spire family. Together, they cover the full range of PDF document generation scenarios.

By integrating these tools, developers can streamline workflows, reduce reliance on Adobe or other third-party components, and ensure consistent, professional-quality output. This makes your ASP.NET PDF solutions more scalable, maintainable, and ready for enterprise use.

FAQs

Q1. Do I need Adobe Acrobat installed on the server?

No. Spire.PDF is a standalone library and works independently of Adobe Acrobat.

Q2. Can I generate PDFs from both raw content and HTML?

Yes. You can build documents programmatically (drawing text, shapes, tables) or convert HTML pages to PDF.

Q3. Can I convert Word documents to PDF with Spire.PDF?

No. Word-to-PDF is supported by Spire.Doc for .NET, not Spire.PDF. You can use them together if your project requires it.

Q4. How can I protect generated PDFs?

Spire.PDF supports setting passwords, permissions, and digital signatures for document security.

Q5. Does Spire.PDF support ASP.NET Framework?

Yes. It works with both ASP.NET Core and ASP.NET Framework.

Get a Free License

To fully experience the capabilities of Spire.PDF for .NET without any evaluation limitations, you can request a free 30-day trial license.

C# PDF & bytes workflow overview

Working with PDFs as byte arrays is common in C# development. Developers often need to store PDF documents in a database, transfer them through an API, or process them entirely in memory without touching the file system. In such cases, converting between PDF and bytes using C# becomes essential.

This tutorial explains how to perform these operations step by step using Spire.PDF for .NET. You will learn how to convert a byte array to PDF, convert a PDF back into a byte array, and even edit a PDF directly from memory with C# code.

Jump right where you need

Why Work with Byte Arrays and PDFs in C#?

Using byte[] as the transport format lets you avoid temporary files and makes your code friendlier to cloud and container environments.

  • Database storage (BLOB): Persist PDFs as raw bytes; hydrate only when needed.
  • Web APIs: Send/receive PDFs over HTTP without touching disk.
  • In-memory processing: Transform or watermark PDFs entirely in streams.
  • Security & isolation: Limit file I/O, reduce temp-file risks.

Getting set up: before running the examples, add the NuGet package of Spire.PDF for .NET so the API surface is available in your project.

Install-Package Spire.PDF

Once installed, you can load from byte[] or Stream, edit pages, and write outputs back to memory or disk—no extra converters required.

Convert Byte Array to PDF in C#

When an upstream service (e.g., an API or message queue) hands you a byte[] that represents a PDF, you often need to materialize it as a document for further processing or for a one-time save to disk. With Spire.PDF for .NET, this is a direct load operation—no intermediate temp file.

Scenario & approach: we’ll accept a byte[] (from DB/API), construct a PdfDocument in memory, optionally validate basic metadata, and then save the document.

using Spire.Pdf;
using System.IO;

class Program
{
    static void Main()
    {
        // Example source: byte[] retrieved from DB/API
        byte[] pdfBytes = File.ReadAllBytes("Sample.pdf"); // substitute with your source

        // 1) Load PDF from raw bytes (in memory)
        PdfDocument doc = new PdfDocument();
        doc.LoadFromBytes(pdfBytes);

        // 2) (Optional) inspect basic info before saving or further processing
        // int pageCount = doc.Pages.Count;

        // 3) Save to a file
        doc.SaveToFile("Output.pdf");
        doc.Close();
    }
}

The diagram below illustrates the byte[] to PDF conversion workflow:

bytes loaded into PdfDocument and saved as PDF in C# with Spire.PDF

What the code is doing & why it matters:

  • LoadFromBytes(byte[]) initializes the PDF entirely in memory—perfect for services without write access.
  • You can branch after loading: validate pages, redact, stamp, or route elsewhere.
  • SaveToFile(string) saves the document to disk for downstream processing or storing.

Convert PDF to Byte Array in C#

In the reverse direction, converting a PDF to a byte[] enables database writes, caching, or streaming the file through an HTTP response. Spire.PDF for .NET writes directly to a MemoryStream, which you can convert to a byte array with ToArray().

Scenario & approach: load an existing PDF, push the document into a MemoryStream, then extract the byte[]. This pattern is especially useful when returning PDFs from APIs or persisting them to databases.

using Spire.Pdf;
using System.IO;

class Program
{
    static void Main()
    {
        // 1) Load a PDF from disk, network share, or embedded resource
        PdfDocument doc = new PdfDocument();
        doc.LoadFromFile("Input.pdf");

        // 2) Save to a MemoryStream for fileless output
        byte[] pdfBytes;
        using (var ms = new MemoryStream())
        {
            doc.SaveToStream(ms);
            pdfBytes = ms.ToArray();
        }

        doc.Close();

        // pdfBytes now contains the full document (ready for DB/API)
        // e.g., return File(pdfBytes, "application/pdf");
    }
}

The diagram below shows the PDF to byte[] conversion workflow:

PDF loaded into PdfDocument, saved to MemoryStream, then bytes in C#

Key takeaways after the code:

  • SaveToStream → ToArray is the standard way to obtain a PDF as bytes in C# without creating temp files.
  • This approach scales for large PDFs; the only limit is available memory.
  • Great for ASP.NET: return the byte array directly in your controller or minimal API endpoint.

If you want to learn more about working with streams, check out our guide on loading and saving PDF documents via streams in C#.

Create and Edit PDF Directly from a Byte Array

The real power comes from editing PDFs fully in memory. You can load from byte[], add text or images, stamp a watermark, fill form fields, and save the edited result back into a new byte[]. This enables fileless pipelines and is well-suited for microservices.

Scenario & approach: we’ll load a PDF from bytes, draw a small text annotation on page 1 (stand-in for any edit operation), and emit the edited document as a fresh byte array.

using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
using System.IO;

class Program
{
    static void Main()
    {
        // Source could be DB, API, or file — represented as byte[]
        byte[] inputBytes = File.ReadAllBytes("Input.pdf");

        // 1) Load in memory
        var doc = new PdfDocument();
        doc.LoadFromBytes(inputBytes);

        // 2) Edit: write a small marker on the first page
        PdfPageBase page = doc.Pages[0];
        page.Canvas.DrawString(
            "Edited in memory",
            new PdfFont(PdfFontFamily.Helvetica, 12f),
            PdfBrushes.DarkBlue,
            new PointF(100, page.Size.Height - 100)
        );

        // 3) Save the edited PDF back to byte[]
        byte[] editedBytes;
        using (var ms = new MemoryStream())
        {
            doc.SaveToStream(ms);
            editedBytes = ms.ToArray();
        }

        doc.Close();

        // editedBytes can now be persisted or returned by an API
    }
}

The image below shows the edited PDF page:

Edited PDF page with insrted text using C# in bytes

After-code insights:

  • The same pattern works for text, images, watermarks, annotations, and form fields.
  • Keep edits idempotent (e.g., check if you already stamped a page) for safe reprocessing.
  • For ASP.NET, this is ideal for on-the-fly stamping or conditional redaction before returning the response.

For a step-by-step tutorial on building a PDF from scratch, see our article on creating PDF documents in C#.

Advantages of Using Spire.PDF for .NET

A concise view of why this API pairs well with byte-array workflows:

Concern What you get with Spire.PDF for .NET
I/O flexibility Load/save from file path, Stream, or byte[] with the same PdfDocument API.
In-memory editing Draw text/images, manage annotations/forms, watermark, and more—no temp files.
Service-friendly Clean integration with ASP.NET endpoints and background workers.
Scales to real docs Handles multi-page PDFs; you control memory via streams.
Straightforward code Minimal boilerplate; avoids manual byte fiddling and fragile interop.

Conclusion

You’ve seen how to convert byte array to PDF in C#, how to convert PDF to byte array, and how to edit a PDF directly from memory—all with concise code. Keeping everything in streams and byte[] simplifies API design, accelerates response times, and plays nicely with databases and cloud hosting. Spire.PDF for .NET gives you a consistent, fileless workflow that’s easy to extend from quick conversions to full in-memory document processing.

If you want to try these features without limitations, you can request a free 30-day temporary license. Alternatively, you can explore Free Spire.PDF for .NET for lightweight PDF tasks.

FAQ

Can I create a PDF from a byte array in C# without saving to disk?

Yes. Load from byte[] with LoadFromBytes, then either save to a MemoryStream or return it directly from an API—no disk required.

How do I convert PDF to byte array in C# for database storage?

Use SaveToStream on PdfDocument and call ToArray() on the MemoryStream. Store that byte[] as a BLOB (or forward it to another service).

Can I edit a PDF that only exists as a byte array?

Absolutely. Load from bytes, apply edits (text, images, watermarks, annotations, form fill), then save the result back to a new byte[].

Any tips for performance and reliability?

Dispose streams promptly, reuse buffers when appropriate, and create a new PdfDocument per operation/thread. For large files, stream I/O keeps memory usage predictable.

Scan QR codes and barcodes in ASP.NET Core using C# and Spire.Barcode

Many business applications today need the ability to scan barcodes and QR codes in ASP.NET environments. From ticket validation and payment processing to inventory management, an ASP.NET QR code scanner or barcode reading feature can greatly improve efficiency and accuracy for both web and enterprise systems.

This tutorial demonstrates how to build a complete solution to scan barcodes in ASP.NET with C# code using Spire.Barcode for .NET. We’ll create an ASP.NET Core web application that can read both QR codes and various barcode formats from uploaded images, delivering high recognition accuracy and easy integration into existing projects.

Guide Overview


1. Project Setup

Step 1: Create the Project

Create a new ASP.NET Core Razor Pages project, which will serve as the foundation for the scanning feature. Use the following command to create a new project or manually configure it in Visual Studio:

dotnet new webapp -n QrBarcodeScanner
cd QrBarcodeScanner

Step 2: Install Spire.Barcode for .NET

Install the Spire.Barcode for .NET NuGet package, which supports decoding a wide range of barcode types with a straightforward API. Search for the package in the NuGet Package Manager or use the command below to install it:

dotnet add package Spire.Barcode

Spire.Barcode for .NET offers built-in support for both QR codes and multiple barcode formats such as Code128, EAN-13, and Code39, making it suitable for ASP.NET Core integration without requiring additional image processing libraries. To find out all the supported barcode types, refer to the BarcodeType API reference.

You can also use Free Spire.Barcode for .NET for smaller projects.


2. Implementing QR Code and Barcode Scanning Feature with C# in ASP.NET

A reliable scanning feature involves two main parts:

  1. Backend logic that processes and decodes uploaded images.
  2. A simple web interface that lets users upload files for scanning.

We will first focus on the backend implementation to ensure the scanning process works correctly, then connect it to a minimal Razor Page frontend.

Backend: QR & Barcode Scanning Logic with Spire.Barcode

The backend code reads the uploaded file into memory and processes it with Spire.Barcode, using either a memory stream or a file path. The scanned result is then returned. This implementation supports QR codes and other barcode types without requiring format-specific logic.

Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Spire.Barcode;

public class IndexModel : PageModel
{
    [BindProperty]
    public IFormFile Upload { get; set; }  // Uploaded file

    public string Result { get; set; }     // Scanning result
    public string UploadedImageBase64 { get; set; } // Base64 string for preview

    public void OnPost()
    {
        if (Upload != null && Upload.Length > 0)
        {
            using (var ms = new MemoryStream())
            {
                // Read the uploaded file into memory
                Upload.CopyTo(ms);

                // Convert the image to Base64 for displaying in HTML <img>
                UploadedImageBase64 = "data:" + Upload.ContentType + ";base64," +
                                      Convert.ToBase64String(ms.ToArray());

                // Reset the stream position before scanning
                ms.Position = 0;

                // Scan the barcode or QR code from the stream
                try
                {
                    string[] scanned = BarcodeScanner.Scan(ms);
                    // Return the scanned result
                    Result = scanned != null && scanned.Length > 0
                        ? string.Join(", ", scanned)
                        : "No code detected.";
                }
                catch (Exception ex)
                {
                    Result = "Error while scanning: " + ex.Message;
                }
            }
        }
    }
}

Explanation of Key Classes and Methods

  • BarcodeScanner: A static class in Spire.Barcode that decodes images containing QR codes or barcodes.
  • BarcodeScanner.Scan(Stream imageStream): Scans an uploaded image directly from a memory stream and returns an array of decoded strings. This method scans all barcodes in the given image.
  • Supplementary methods (optional):
    • BarcodeScanner.Scan(string imagePath): Scans an image from a file path.
    • BarcodeScanner.ScanInfo(string imagePath): Scans an image from a file path and returns additional barcode information such as type, location, and data.

These methods can be used in different ways, depending on the application requirements.

Frontend: QR & Barcode Upload & Scanning Result Interface

The following page design provides a simple upload form where users can submit an image containing a QR code or barcode. Once uploaded, the image is displayed along with the recognized result, which can be copied with a single click. The layout is intentionally kept minimal for fast testing, yet styled for a clear and polished presentation.

Index.cshtml

@page
@model IndexModel
@{
    ViewData["Title"] = "QR & Barcode Scanner";
}

<div style="max-width:420px;margin:40px auto;padding:20px;border:1px solid #ccc;border-radius:8px;background:#f9f9f9;">
    <h2>QR & Barcode Scanner</h2>
    <form method="post" enctype="multipart/form-data" id="uploadForm">
        <input type="file" name="upload" accept="image/*" required onchange="this.form.submit()" style="margin:10px 0;" />
    </form>

    @if (!string.IsNullOrEmpty(Model.UploadedImageBase64))
    {
        <div style="margin-top:15px;text-align:center;">
            <img src="/@Model.UploadedImageBase64" style="width:300px;height:300px;object-fit:contain;border:1px solid #ddd;background:#fff;" />
        </div>
    }

    @if (!string.IsNullOrEmpty(Model.Result))
    {
        <div style="margin-top:15px;padding:10px;background:#e8f5e9;border-radius:6px;">
            <b>Scan Result:</b>
            <p id="scanText">@Model.Result</p>
            <button type="button" onclick="navigator.clipboard.writeText(scanText.innerText)" style="background:#28a745;color:#fff;padding:6px 10px;border:none;border-radius:4px;">Copy</button>
        </div>
    }
</div>

Below is a screenshot showing the scan page after successfully recognizing both a QR code and a Code128 barcode, with the results displayed and a one-click copy button available.

ASP.NET Core QR code and Code128 barcode scan page with recognized results and copy button

This ASP.NET Core application can scan QR codes and other barcodes from uploaded images. If you're looking to generate QR codes or barcodes, check out How to Generate QR Codes in ASP.NET Core.


3. Testing and Troubleshooting

After running the application, test the scanning feature with:

  • A QR code image containing a URL or plain text.
  • A barcode image such as Code128 or EAN-13.

If recognition fails:

  • Ensure the image has good contrast and minimal distortion.
  • Use images of reasonable resolution (not excessively large or pixelated).
  • Test with different file formats such as JPG, PNG, or BMP.
  • Avoid images with reflections, glare, or low lighting.
  • When scanning multiple barcodes in one image, ensure each code is clearly separated to improve recognition accuracy.

A good practice is to maintain a small library of sample QR codes and barcodes to test regularly after making code changes.


4. Extending to Other .NET Applications

The barcode scanning logic in this tutorial works the same way across different .NET application types — only the way you supply the image file changes. This makes it easy to reuse the core decoding method, BarcodeScanner.Scan(), in various environments such as:

  • ASP.NET Core MVC controllers or Web API endpoints
  • Desktop applications like WinForms or WPF
  • Console utilities for batch processing

Example: Minimal ASP.NET Core Web API Endpoint — receives an image file via HTTP POST and returns decoded results as JSON:

[ApiController]
[Route("api/[controller]")]
public class ScanController : ControllerBase
{
    [HttpPost]
    public IActionResult Scan(IFormFile file)
    {
        if (file == null) return BadRequest("No file uploaded");
        using var ms = new MemoryStream();
        file.CopyTo(ms);
        ms.Position = 0;
        string[] results = BarcodeScanner.Scan(ms);
        return Ok(results);
    }
}

Example: Console application — scans a local image file and prints the decoded text:

string[] result = BarcodeScanner.Scan(@"C:\path\to\image.png");
Console.WriteLine(string.Join(", ", result));

This flexibility makes it simple for developers to quickly add QR code and barcode scanning to new projects or extend existing .NET applications.


5. Conclusion

This tutorial has shown how to implement a complete QR code and barcode scanning solution in ASP.NET Core using Spire.Barcode for .NET. From receiving uploaded images to decoding and displaying the results, the process is straightforward and adaptable to a variety of application types. With this approach, developers can quickly integrate reliable scanning functionality into e-commerce platforms, ticketing systems, document verification tools, and other business-critical web applications.

For more advanced scenarios, Spire.Barcode for .NET provides additional features such as customizing the recognition process, handling multiple image formats and barcode types, and more. Apply for a free trial license to unlock all the advanced features.

Download Spire.Barcode for .NET today and start building your own ASP.NET barcode scanning solution.

Perform OCR on Scanned PDFs in C#

Optical Character Recognition (OCR) technology has become essential for developers working with scanned documents and image-based PDFs. In this tutorial, you learn how to perform OCR on PDFs in C# to extract text from scanned documents or images within a PDF using the Spire.PDF for .NET and Spire.OCR for .NET libraries. By transferring scanned PDFs into editable and searchable formats, you can significantly improve your document management processes.

Table of Contents :

Why OCR is Needed for Scanned PDFs?

Scanned PDFs are essentially image files —they contain pictures of text rather than actual selectable and searchable text content. When you scan a paper document or receive an image-based PDF, the text exists only as pixels , making it impossible to edit, search, or extract. This creates significant limitations for businesses and individuals who need to work with these documents digitally.

OCR technology solves this problem by analyzing the shapes of letters and numbers in scanned images and converting them into machine-readable text. This process transforms static PDFs into usable, searchable, and editable documents—enabling text extraction, keyword searches, and seamless integration with databases and workflow automation tools.

In fields such as legal, healthcare, and education, where large volumes of scanned documents are common, OCR plays a crucial role in document digitization, making important data easily accessible and actionable.

Setting Up: Installing Required Libraries

Before we dive into the code, let's first set up our development environment with the necessary components: Spire.PDF and Spire.OCR . Spire.PDF handles PDF operations, while Spire.OCR performs the actual text recognition.

Step 1. Install Spire.PDF and Spire.OCR via NuGet

To begin, open the NuGet Package Manager in Visual Studio, and search for "Spire.PDF" and "Spire.OCR" to install them in your project. Alternatively, you can use the Package Manager Console :

Install-Package Spire.PDF
Install-Package Spire.OCR

Step 2. Download OCR Models:

Spire.OCR requires pre-trained language models for text recognition. Download the appropriate model files for your operating system (Windows, Linux, or MacOS) and extract them to a directory (e.g., D:\win-x64).

Important Note : Ensure your project targets x64 platform (Project Properties > Build > Platform target) as Spire.OCR only supports 64-bit systems.

Set platform target to x64.

Performing OCR on Scanned PDFs in C#

With the necessary libraries installed, we can now perform OCR on scanned PDFs. Below is a sample code snippet demonstrating this process.

using Spire.OCR;
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;

namespace OCRPDF
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create an instance of the OcrScanner class
            OcrScanner scanner = new OcrScanner();

            // Configure the scanner
            ConfigureOptions configureOptions = new ConfigureOptions
            {
                ModelPath = @"D:\win-x64", // Set model path
                Language = "English"        // Set language
            };

            // Apply the configuration options
            scanner.ConfigureDependencies(configureOptions);

            // Load a PDF document
            PdfDocument doc = new PdfDocument();
            doc.LoadFromFile(@"C:\Users\Administrator\Desktop\Input5.pdf");

            // Iterate through all pages
            for (int i = 0; i < doc.Pages.Count; i++)
            {
                // Convert page to image
                Image image = doc.SaveAsImage(i, PdfImageType.Bitmap);

                // Convert the image to a MemoryStream
                using (MemoryStream stream = new MemoryStream())
                {
                    image.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                    stream.Position = 0; // Reset the stream position

                    // Perform OCR on the image stream
                    scanner.Scan(stream, OCRImageFormat.Png);
                    string pageText = scanner.Text.ToString();

                    // Save extracted text to a separate file
                    string outputTxtPath = Path.Combine(@"C:\Users\Administrator\Desktop\Output", $"Page-{i + 1}.txt");
                    File.WriteAllText(outputTxtPath, pageText);
                }
            }

            // Close the document
            doc.Close();
        }
    }
}

Key Components Explained :

  1. OcrScanner Class : This class is crucial for performing OCR. It provides methods to configure and execute the scanning operation.
  2. ConfigureOptions Class : This class is used to set up the OCR scanner's configurations. The ModelPath property specifies the path to the OCR model files, and the Language property allows you to specify the language for text recognition.
  3. PdfDocument Class : This class represents the PDF document. The LoadFromFile method loads the PDF file that you want to process.
  4. Image Conversion : Each PDF page is converted to an image using the SaveAsImage method. This is essential because OCR works on image files.
  5. MemoryStream : The image is saved into a MemoryStream , allowing us to perform OCR without saving the image to disk.
  6. OCR Processing : The Scan method performs OCR on the image stream. The recognized text can be accessed using the Text property of the OcrScanner instance.
  7. Output : The extracted text is saved to a text file for each page.

Output :

Perform OCR on a PDF document in C#

To extract text from searchable PDFs, refer to this guide: Automate PDF Text Extraction Using C#

Extracting Text from Images within PDFs in C#

In addition to processing entire PDF pages, you can also extract text from images embedded within PDFs. Here’s how:

using Spire.Pdf;
using Spire.Pdf.Utilities;
using Spire.OCR;
using System.Drawing;

namespace OcrImageFromPdf
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a PdfDocument object
            PdfDocument doc = new PdfDocument();

            // Load a PDF document
            doc.LoadFromFile(@"C:\Users\Administrator\Desktop\AI.pdf");

            // Create a PdfImageHelper object
            PdfImageHelper imageHelper = new PdfImageHelper();

            // Create an instance of the OcrScanner class
            OcrScanner scanner = new OcrScanner();

            // Configure the scanner
            ConfigureOptions configureOptions = new ConfigureOptions
            {
                ModelPath = @"D:\win-x64", // Set model path
                Language = "English"        // Set language
            };
            scanner.ConfigureDependencies(configureOptions);

            // Declare an int variable
            int m = 0;

            // Iterate through the pages
            for (int i = 0; i < doc.Pages.Count; i++)
            {
                // Get a specific page
                PdfPageBase page = doc.Pages[i];

                // Get all image information from the page 
                PdfImageInfo[] imageInfos = imageHelper.GetImagesInfo(page);

                // Iterate through the image information
                for (int j = 0; j < imageInfos.Length; j++)
                {
                    // Get a specific image information
                    PdfImageInfo imageInfo = imageInfos[j];

                    // Get the image
                    Image image = imageInfo.Image;

                    // Convert the image to a MemoryStream
                    using (MemoryStream stream = new MemoryStream())
                    {
                        image.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                        stream.Position = 0; // Reset the stream position

                        // Perform OCR on the image stream
                        scanner.Scan(stream, OCRImageFormat.Png);
                        string imageText = scanner.Text.ToString();

                        // Save the OCR result to a text file
                        string outputTxtPath = Path.Combine(@"C:\Users\Administrator\Desktop\Output", $"Image-Text-{m + 1}.txt");
                        File.WriteAllText(outputTxtPath, imageText);

                        m++;
                    }
                }
            }

            // Dispose resources
            doc.Dispose();
        }
    }
}

Key Components Explained :

  1. PdfImageHelper Class : This class is essential for extracting images from a PDF page. It provides methods to retrieve image information such as GetImagesInfo , which returns an array of PdfImageInfo objects.
  2. PdfImageInfo Class : Each PdfImageInfo object contains properties related to an image, including the actual Image object that can be processed further.
  3. Image Processing : Similar to the previous example, each image is saved to a MemoryStream for OCR processing.
  4. Output : The extracted text from each image is saved to a separate text file.

Output:

Extract text from images in PDF in C#

Wrapping Up

By combining Spire.PDF with Spire.OCR , you can seamlessly transform scanned PDFs and image-based documents into fully searchable and editable text. Whether you need to process entire pages or extract text from specific embedded images, the approach is straightforward and flexible.

This OCR integration not only streamlines document digitization but also enhances productivity by enabling search, copy, and automated data extraction. In industries where large volumes of scanned documents are the norm, implementing OCR with C# can significantly improve accessibility, compliance, and information retrieval speed.

FAQs

Q1. Can I perform OCR on non-English PDFs?

Yes, Spire.OCR supports multiple languages. You can set the Language property in ConfigureOptions to the desired language.

Q2. What should I do if the output is garbled or incorrect?

Check the quality of the input PDF images. If the images are blurry or have low contrast, OCR may struggle to recognize text accurately. Consider enhancing the image quality before processing.

Q3. Can I extract text from images embedded within a PDF?

Yes, you can. Use a helper class to extract images from each page and then apply OCR to recognize text.

Q4. Can Spire.OCR handle handwritten text in PDFs?

Spire.OCR is primarily optimized for printed text. Handwriting recognition typically has lower accuracy.

Q5. Do I need to install additional language models for OCR?

Yes, Spire.OCR requires pre-trained language model files. Download and configure the appropriate models for your target language before performing OCR.

Get a Free License

To fully experience the capabilities of Spire.PDF for .NET and Spire.OCR for .NET without any evaluation limitations, you can request a free 30-day trial license.

Convert Excel to JSON and vice versa in C# Step-by-Step Guide

Excel files are widely used to enter, organize, and present tabular data, while JSON is commonly used by APIs and applications to exchange structured data between systems. Converting between these formats allows developers to import spreadsheet data into applications and export application data to Excel for reporting, analysis, or sharing.

In this tutorial, you’ll learn how to convert Excel to JSON and JSON to Excel in C# using Spire.XLS for .NET.

What We Will Cover:

Why Convert Between Excel and JSON?

Converting data between Excel (.xlsx or .xls) and JSON formats is a standard requirement in .NET applications for the following development tasks:

  • Data Ingestion: Parses business-generated spreadsheets into standard server-side objects for backend processing.
  • API Integration: Formats tabular data into standard JSON payloads required by web APIs and microservices.
  • Frontend Serialization: Transforms structured server-side data into lightweight JSON format for consumption by web clients and JavaScript frameworks.
  • NoSQL Storage: Prepares relational or tabular spreadsheet data for direct migration into document databases like MongoDB or Cosmos DB.
  • Automated Reporting: Converts dynamic JSON application data into readable Excel reports for end users.

Prerequisites and Package Installation

Before you begin, ensure your development environment meets these specific requirements.

  • Visual Studio (2019 or later recommended)
  • .NET Environment: .NET Framework 4.0+, .NET Core 3.1+, or .NET 5.0+.
  • NuGet Packages:

Installing the Required NuGet Packages

Option 1: Using .NET Package Manager Console

Open your project in Visual Studio and run the following commands in the Package Manager Console:

Install-Package Spire.XLS
Install-Package Newtonsoft.Json

Option 2: Using .NET CLI

For cross-platform developers using terminal-based environments, execute the following commands inside the project's root folder:

dotnet add package Spire.XLS
dotnet add package Newtonsoft.Json

Basic Excel to JSON Conversion in C# .NET

Starting with Spire.XLS for .NET 15.11.3, developers can export an Excel workbook directly to JSON by calling the SaveToFile() method.

This method is suitable when you want to convert the whole workbook and do not need to customize the generated JSON structure.

Steps to Convert an Excel Workbook to JSON

  1. Instantiate a new Workbook object.
  2. Use LoadFromFile() to load your Excel workbook.
  3. Call SaveToFile() and specify FileFormat.Json as the output format to export the workbook to JSON.

Complete Code Example

using System;
using Spire.Xls;

namespace ConvertExcelToJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputFile = @"Sample.xlsx";
            string outputFile = @"output.json";

            try
            {
                // Create a Workbook object
                using (Workbook workbook = new Workbook())
                {
                    // Load the Excel file
                    workbook.LoadFromFile(inputFile);

                    // Save the entire workbook into a single JSON file
                    // Supported in Spire.XLS 15.11.3 and later
                    workbook.SaveToFile(outputFile, FileFormat.Json);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error during conversion: {ex.Message}");
            }
        }
    }
}

The Output JSON:

The converted JSON structure corresponds to the Excel data as follows:

  • Worksheet name → Becomes a key in the outermost JSON object.
  • Data in each worksheet → Becomes an array, where each object represents a single row.
  • Header row values → Become the default field names for each data object.

The JSON converted from Excel in C#

Advanced Excel to JSON Conversion Scenarios

While saving the entire workbook to JSON is convenient, there are scenarios where you need more control—such as converting only a specific worksheet, cell range, or customizing the JSON output format. Spire.XLS provides flexible approaches to achieve these custom conversions.

Worksheet to JSON

To convert only a specific worksheet rather than the entire workbook, copy the target worksheet to a new workbook and then save that workbook as JSON.

Steps to Convert a Specific Worksheet to JSON

  1. Load the source workbook using LoadFromFile().
  2. Get the target worksheet by its index or name.
  3. Create a new Workbook object for the output.
  4. Use the Worksheets.AddCopy() method to copy the target worksheet to the new workbook.
  5. Call SaveToFile() with FileFormat.Json on the new workbook.

Complete Code Example

using System;
using Spire.Xls;

namespace ConvertWorksheetToJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputFile = @"Sample.xlsx";
            string outputFile = @"sheet_output.json";

            try
            {
                using (Workbook sourceWorkbook = new Workbook())
                {
                    sourceWorkbook.LoadFromFile(inputFile);

                    // Access the first worksheet by index (or by name: sourceWorkbook.Worksheets["sheetName"])
                    Worksheet targetSheet = sourceWorkbook.Worksheets[0];

                    using (Workbook newWorkbook = new Workbook())
                    {
                        // Remove default worksheets from the new workbook
                        newWorkbook.Worksheets.Clear();

                        // Copy the target worksheet into the new workbook
                        newWorkbook.Worksheets.AddCopy(targetSheet);

                        // Save the single worksheet as JSON
                        newWorkbook.SaveToFile(outputFile, FileFormat.Json);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }
}

Cell Range to JSON

If you only need to export a portion of worksheet data—such as a specific table or range—copy the desired range to a new workbook and then save the result file as JSON.

Steps to Convert a Cell Range to JSON

  1. Load the source workbook.
  2. Get the target worksheet containing the data.
  3. Define the range you want to export (e.g., worksheet.Range["A1:D3"]).
  4. Instantiate a new Workbook object.
  5. Copy the range data to a new worksheet in the new workbook with Worksheet.Copy().
  6. Call SaveToFile() with FileFormat.Json to save the new workbook as a .json file.

Complete Code Example

using System;
using Spire.Xls;

namespace ConvertExcelToJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputFile = @"Sample.xlsx";
            string outputFile = @"range_output.json";

            try
            {
                using (Workbook sourceWorkbook = new Workbook())
                {
                    sourceWorkbook.LoadFromFile(inputFile);
                    Worksheet sourceWorksheet = sourceWorkbook.Worksheets[0];

                    // Define the range to export (e.g., A1:D3)
                    CellRange sourceRange = sourceWorksheet.Range["A1:D3"];

                    using (Workbook targetWorkbook = new Workbook())
                    {
                        // Remove the default worksheets
                        targetWorkbook.Worksheets.Clear(); 

                        // Add a worksheet for the selected range
                        Worksheet targetWorksheet = targetWorkbook.Worksheets.Add("RangeData"); 

                        // Create a destination range with the same dimensions
                        CellRange destinationRange = targetWorksheet.Range["A1:D3"]; 

                        // Copy values and styles to the new workbook
                        sourceWorksheet.Copy(sourceRange, destinationRange, true);

                        // Export the isolated range to JSON
                        targetWorkbook.SaveToFile(outputFile, FileFormat.Json);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error exporting cell range: {ex.Message}");
            }
        }
    }
}

Customize JSON Output Formatting

The SaveToFile() method provides a quick conversion, but the output format is fixed. If you need greater control over the JSON output, export the worksheet data to a DataTable with ExportDataTable() and serialize it with Newtonsoft.Json. This allows you to customize property names, null handling, date formats, and indentation.

Steps for Custom JSON Output Formatting

  1. Load the Excel File.
  2. Access the worksheet and export its data to a DataTable using ExportDataTable().
  3. Configure JsonSerializerSettings to define formatting rules (camelCase, null handling, date format, etc.).
  4. Serialize the DataTable using JsonConvert.SerializeObject() with the settings.
  5. Save the JSON string to a file.

Complete Code Example

using System;
using System.Data;
using System.IO;
using Spire.Xls;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace ConvertExcelToJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            string excelFilePath = @"Sample.xlsx";
            string jsonOutputPath = "custom_output.json";

            try
            {
                using (Workbook workbook = new Workbook())
                {
                    workbook.LoadFromFile(excelFilePath);
                    Worksheet worksheet = workbook.Worksheets[0];

                    // Convert tabular data directly into an in-memory DataTable structure
                    DataTable dataTable = worksheet.ExportDataTable(worksheet.AllocatedRange, true);

                    // Define custom JSON serialization rules
                    JsonSerializerSettings settings = new JsonSerializerSettings
                    {
                        Formatting = Formatting.Indented, // Structured, readable format
                        ContractResolver = new CamelCasePropertyNamesContractResolver(), // camelCase naming conventions
                        NullValueHandling = NullValueHandling.Ignore, // Omit null fields from output string
                        DateFormatString = "yyyy-MM-dd" // Explicit date string overrides
                    };

                    // Serialize the data structure to string with settings applied
                    string jsonResult = JsonConvert.SerializeObject(dataTable, settings);

                    // Write string payload out to target destination
                    File.WriteAllText(jsonOutputPath, jsonResult);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error during custom serialization: {ex.Message}");
            }
        }
    }
}

Explanation of Customization Options

Setting Purpose
Formatting = Formatting.Indented Produces human‑readable JSON with line breaks and indentation.
CamelCasePropertyNamesContractResolver Applies camelCase naming to compatible column names, which is a common convention in JSON APIs.
NullValueHandling = NullValueHandling.Ignore Omits values represented as null or DBNull.Value.
DateFormatString = "yyyy-MM-dd" Formats values represented as DateTime or DateTimeOffset.

Note on Column Names with Spaces:
When Excel headers contain spaces (e.g., "First Name"), the generated JSON keys will retain those spaces. Consumers must use bracket notation (obj["First Name"]) instead of dot notation. For cleaner camelCase property names, normalize the DataTable column names by iterating DataTable.Columns — e.g., remove spaces or apply a custom naming convention before serialization.

You can further customize the output by adding custom JsonConverter implementations, modifying date handling, or using different ContractResolver strategies. For more details, refer to the Newtonsoft.Json documentation.

How to Convert JSON to Excel in C# .NET

To convert JSON to Excel, deserialize the JSON data into a DataTable, then insert the table into an Excel worksheet.

Steps to Import JSON into Excel

  1. Load the JSON data from a file, API response, or string variable.
  2. Use Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>() to convert the JSON data to a DataTable.
  3. Instantiate a new Workbook object.
  4. Use InsertDataTable() to transfer data to a worksheet in the new workbook.
  5. Style headers and data cells for better readability.
  6. Save the new workbook as an Excel file.

Complete Code Example

using System;
using System.Data;
using System.Drawing;
using Spire.Xls;
using Newtonsoft.Json;

namespace ConvertJSONToExcel
{
    class Program
    {
        static void Main(string[] args)
        {
            // Sample JSON array
            string jsonInput = @"
            [
                {""Name"":""John Smith"",""Age"":30,""Department"":""Sales"",""StartDate"":""2020-05-12"",""FullTime"":true},
                {""Name"":""Jane Doe"",""Age"":25,""Department"":""Marketing"",""StartDate"":""2021-09-01"",""FullTime"":false},
                {""Name"":""Michael Lee"",""Age"":40,""Department"":""IT"",""StartDate"":""2018-03-15"",""FullTime"":true},
                {""Name"":""Emily Davis"",""Age"":35,""Department"":""Finance"",""StartDate"":""2019-07-20"",""FullTime"":true}
            ]";

            string excelOutputPath = "output.xlsx";

            try
            {
                // Deserialize the JSON array into a DataTable
                DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(jsonInput);

                using (Workbook workbook = new Workbook())
                {
                    Worksheet worksheet = workbook.Worksheets[0];

                    // Insert the data and column headers starting at cell A1
                    worksheet.InsertDataTable(dataTable, true, 1, 1);

                    // --- Define Header Styles ---
                    CellStyle headerStyle = workbook.Styles.Add("HeaderStyle");
                    headerStyle.Font.IsBold = true;
                    headerStyle.Font.Size = 12;
                    headerStyle.Font.Color = Color.White;
                    headerStyle.Color = Color.DarkBlue;
                    headerStyle.HorizontalAlignment = HorizontalAlignType.Center;
                    headerStyle.VerticalAlignment = VerticalAlignType.Center;

                    // Apply the style to the header row
                    int colCount = dataTable.Columns.Count;
                    worksheet.Range[1, 1, 1, colCount].CellStyleName = "HeaderStyle";

                    // --- Define Data Row Styles ---
                    CellStyle dataStyle = workbook.Styles.Add("DataStyle");
                    dataStyle.HorizontalAlignment = HorizontalAlignType.Center;
                    dataStyle.VerticalAlignment = VerticalAlignType.Center;
                    dataStyle.Borders[BordersLineType.EdgeLeft].LineStyle = LineStyleType.Thin;
                    dataStyle.Borders[BordersLineType.EdgeRight].LineStyle = LineStyleType.Thin;
                    dataStyle.Borders[BordersLineType.EdgeTop].LineStyle = LineStyleType.Thin;
                    dataStyle.Borders[BordersLineType.EdgeBottom].LineStyle = LineStyleType.Thin;

                    // Apply the style to data rows
                    int rowCount = dataTable.Rows.Count;
                    worksheet.Range[2, 1, rowCount + 1, colCount].CellStyleName = "DataStyle";

                    // Autofit column widths
                    worksheet.AllocatedRange.AutoFitColumns();

                    // Save the workbook as an XLSX file 
                    workbook.SaveToFile(excelOutputPath, ExcelVersion.Version2016);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Conversion exception thrown: {ex.Message}");
            }
        }
    }
}

The Excel file converted from JSON in C#

Handling Wrapped or Nested JSON

The direct DataTable deserialization works best with a flat JSON array. If the records are wrapped inside a root object or contain nested objects and arrays, extract and flatten the required values before converting them to a DataTable.

For example, the following JSON string contains both a root wrapper and nested data:

string jsonInput = @"
{
  ""status"": ""success"",
  ""data"": [
    {
      ""Name"": ""John Smith"",
      ""Department"": {
        ""Id"": 10,
        ""Name"": ""Sales""
      },
      ""Skills"": [
        ""Negotiation"",
        ""CRM""
      ]
    },
    {
      ""Name"": ""Jane Doe"",
      ""Department"": {
        ""Id"": 20,
        ""Name"": ""Marketing""
      },
      ""Skills"": [
        ""Content Writing"",
        ""Analytics""
      ]
    }
  ]
}";

The following method extracts the data array, flattens the nested values, and returns a DataTable:

using System.Data;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

private static DataTable ConvertNestedJsonToDataTable(string jsonInput)
{
    // Parse either a root object or a root array.
    JToken rootToken = JToken.Parse(jsonInput);

    // Accept a root array or an array stored in the "data" property.
    JArray records = rootToken as JArray
        ?? ((rootToken as JObject)?["data"] as JArray)
        ?? throw new InvalidDataException(
            "The JSON does not contain a valid record array.");

    // Flatten nested objects and arrays into tabular fields.
    var flattenedRecords = records.Select(record => new
    {
        Name = (string)record["Name"] ?? string.Empty,

        // Convert the nested Department object into separate columns.
        DepartmentId = (int?)record["Department"]?["Id"],
        DepartmentName =
            (string)record["Department"]?["Name"] ?? string.Empty,

        // Join the Skills array into a comma-separated string.
        Skills = string.Join(
            ", ",
            record["Skills"]?.Values<string>()
                ?? Enumerable.Empty<string>())
    });

    // Convert the flattened records into a DataTable.
    string flattenedJson =
        JsonConvert.SerializeObject(flattenedRecords);

    DataTable dataTable =
        JsonConvert.DeserializeObject<DataTable>(flattenedJson);

    if (dataTable == null || dataTable.Columns.Count == 0)
        throw new InvalidDataException(
            "The JSON contains no tabular records.");

    return dataTable;
}

The returned DataTable can then be inserted into a worksheet using InsertDataTable():

DataTable nestedTable = ConvertNestedJsonToDataTable(jsonInput);
worksheet.InsertDataTable(nestedTable, true, 1, 1);

Note: This mapping is based on the structure of the sample JSON. For other JSON schemas, adjust the selected properties and output columns accordingly.

Tips and Best Practices

When converting between Excel and JSON, following these best practices will help ensure data integrity and usability:

  • Validate Data Types: Ensure that data types (dates, numbers, booleans) are correctly formatted to avoid issues during conversion.
  • Handle Empty Cells: Decide how to treat empty cells (convert to null, omit, or use default values) to maintain data integrity.
  • Use Consistent Naming Conventions: Standardize column names in Excel for clear and consistent JSON keys.
  • Test Thoroughly: Always test the conversion processes to ensure valid JSON output and accurate Excel representation.
  • Include Headers: When converting JSON to Excel, always insert headers for improved readability and usability.

FAQs

Do I need Microsoft Excel installed to use these examples?

No. Spire.XLS is a standalone .NET library that reads, writes, and converts Excel files without any dependency on Microsoft Office or Excel Interop.

Can I convert older .xls (97–2003) files as well as .xlsx to JSON?

Yes. LoadFromFile() automatically detects the file format, so the same code works for both .xls and .xlsx sources.

Can I convert nested JSON to Excel?

JsonConvert.DeserializeObject<DataTable>() works with flat JSON arrays. For nested JSON, flatten the structure into a simple list of objects before calling InsertDataTable().

Does this approach work in ASP.NET Core or other cross-platform .NET apps?

Yes. Spire.XLS supports .NET Framework, .NET Core, and .NET 5–10, so the same code runs in console apps, ASP.NET Core services, and cross-platform (Linux/macOS) environments.

Conclusion

This tutorial demonstrated how to convert Excel workbooks, individual worksheets, and cell ranges to JSON, as well as how to import JSON data into Excel in C#. By combining Spire.XLS with Newtonsoft.Json, you can handle both straightforward conversions and scenarios that require custom formatting or nested data processing.

Get a Free License

To fully experience the capabilities of Spire.XLS for .NET without any evaluation limitations, you can request a free 30-day trial license.

Generate QR Code in ASP.NET C# using Spire.Barcode for .NET – Tutorial Overview

QR codes have become a standard feature in modern web applications, widely used for user authentication, contactless transactions, and sharing data like URLs or contact information. For developers working with ASP.NET, implementing QR code generation using C# is a practical requirement in many real-world scenarios.

In this article, you’ll learn how to generate QR codes in ASP.NET using Spire.Barcode for .NET. We’ll walk through a complete example based on an ASP.NET Core Web App (Razor Pages) project, including backend logic and a simple UI to display the generated code. The same approach can be easily adapted to MVC, Web API, and Web Forms applications.

Article Overview


1. Project Setup and Dependencies

Prerequisites

To follow along, make sure you have:

  • Visual Studio 2019 or newer
  • .NET 6 or later
  • ASP.NET Core Web App (Razor Pages Template)
  • NuGet package: Spire.Barcode for .NET

Install Spire.Barcode for .NET

Install the required library using NuGet Package Manager Console:

Install-Package Spire.Barcode

Spire.Barcode is a fully self-contained .NET barcode library that supports in-memory generation of QR codes without external APIs. You can also use Free Spire.Barcode for .NET for smaller projects.


2. Generate QR Code in ASP.NET Using C#

This section describes how to implement QR code generation in an ASP.NET Core Web App (Razor Pages) project. The example includes a backend C# handler that generates the QR code using Spire.Barcode for .NET, and a simple Razor Page frontend for user input and real-time display.

Step 1: Add QR Code Generation Logic in PageModel

The backend logic resides in the Index.cshtml.cs file. It processes the form input, generates a QR code using Spire.Barcode, and returns the result as a Base64-encoded image string that can be directly embedded in HTML.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Spire.Barcode;

public class IndexModel : PageModel
{
    [BindProperty]
    public string InputData { get; set; }

    public string QrCodeBase64 { get; set; }

    public void OnPost()
    {
        if (!string.IsNullOrWhiteSpace(InputData))
        {
            QrCodeBase64 = GenerateQrCodeBase64(InputData);
        }
    }
    
    private string GenerateQrCodeBase64(string input)
    {
        var settings = new BarcodeSettings
        {
            Type = BarCodeType.QRCode,            // QR code type
            Data = input,                         // Main encoded data
            Data2D = input,                       // Required for 2D barcode, usually same as Data
            QRCodeDataMode = QRCodeDataMode.Byte, // Byte mode (supports multilingual content)
            QRCodeECL = QRCodeECL.M,              // Medium error correction (15%)
            X = 3,                                // Module size (affects image dimensions)
            ShowText = false,                     // Hide default barcode text
            ShowBottomText = true,                // Show custom bottom text
            BottomText = input                    // Bottom text to display under the QR code
        };

        var generator = new BarCodeGenerator(settings);
        using var ms = new MemoryStream();
        var qrImage = generator.GenerateImage();
        qrImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return Convert.ToBase64String(ms.ToArray());
    }
}

Key Components:

  • BarcodeSettings: Specifies the QR code's core configuration, such as type (QRCode), data content, encoding mode, and error correction level.

  • BarCodeGenerator: Takes the settings and generates the QR code image as a System.Drawing.Image object using the GenerateImage() method.

  • Base64 Conversion: Converts the image to a Base64 string so it can be directly embedded into the HTML page without saving to disk.

This approach keeps the entire process in memory, making it fast, portable, and suitable for serverless or cloud-hosted applications.

Step 2: Create the Razor Page for User Input and QR Code Display and Download

The following Razor markup in the Index.cshtml file defines a form for entering text or URLs, displays the generated QR code upon submission, and provides a button to download the QR code image.

@page
@model IndexModel
@{
    ViewData["Title"] = "QR Code Generator";
}

<h2>QR Code Generator</h2>

<form method="post">
    <label for="InputData">Enter text or URL:</label>
    <input type="text" id="InputData" name="InputData" style="width:300px;" required />
    <button type="submit">Generate QR Code</button>
</form>

@if (!string.IsNullOrEmpty(Model.QrCodeBase64))
{
    <div style="margin-top:20px">
        <img src="data:image/png;base64,@Model.QrCodeBase64" alt="QR Code" />
        <br />
        <a href="data:image/png;base64,@Model.QrCodeBase64" download="qrcode.png">Download QR Code</a>
    </div>
}

The Base64-encoded image is displayed directly in the browser using a data: URI. This eliminates the need for file storage and allows for immediate rendering and download.

The following screenshot shows the result after submitting text input.

Generated QR Code displayed on Razor Page in ASP.NET Core

If you need to scan QR codes instead, please refer to How to Scan QR Codes in C#.


3. Customize QR Code Output

Spire.Barcode provides several customization options through the BarcodeSettings class to control the appearance and behavior of the generated QR code:

Property Function Example
QRCodeDataMode Text encoding mode QRCodeDataMode.Byte
QRCodeECL Error correction level QRCodeECL.H (high redundancy)
X Module size (resolution) settings.X = 6
ImageWidth/Height Control dimensions of QR image settings.ImageWidth = 300
ForeColor Set QR code color settings.ForeColor = Color.Blue
ShowText Show or hide text below barcode settings.ShowText = false
BottomText Custom text to display below barcode settings.BottomText = "Scan Me"
ShowBottomText Show or hide the custom bottom text settings.ShowBottomText = true
QRCodeLogoImage Add a logo image to overlay at QR code center settings.QRCodeLogoImage = System.Drawing.Image.FromFile("logo.png");

These properties help you tailor the appearance of your QR code for branding, readability, or user interaction purposes.

To explore more QR code settings, refer to the BarcodeSettings API reference.


4. Apply Logic in MVC, Web API, and Web Forms

The same QR code generation logic used in Razor Pages can also be reused in other ASP.NET frameworks such as MVC, Web API, and Web Forms.

MVC Controller Action

In an MVC project, you can add a Generate action in a controller (e.g., QrController.cs) to generate and return the QR code image directly:

public class QrController : Controller
{
    public ActionResult Generate(string data)
    {
        var settings = new BarcodeSettings
        {
            Type = BarCodeType.QRCode,
            Data = data,
            QRCodeDataMode = QRCodeDataMode.Byte,
            QRCodeECL = QRCodeECL.M,
            X = 5
        };

        var generator = new BarCodeGenerator(settings);
        using var ms = new MemoryStream();
        generator.GenerateImage().Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return File(ms.ToArray(), "image/png");
    }
}

This method returns the QR code as a downloadable PNG file, ideal for server-side rendering.

Web API Endpoint

For Web API, you can define a GET endpoint in a controller such as QrApiController.cs that responds with the generated image stream:

[ApiController]
[Route("api/[controller]")]
public class QrApiController : ControllerBase
{
    [HttpGet("generate")]
    public IActionResult GetQr(string data)
    {
        var settings = new BarcodeSettings
        {
            Type = BarCodeType.QRCode,
            Data = data
        };

        var generator = new BarCodeGenerator(settings);
        using var ms = new MemoryStream();
        generator.GenerateImage().Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return File(ms.ToArray(), "image/png");
    }
}

This approach is suitable for frontends built with React, Vue, Angular, or any JavaScript framework.

Web Forms Code-Behind

In ASP.NET Web Forms, you can handle QR code generation in the code-behind of a page like Default.aspx.cs:

protected void btnGenerate_Click(object sender, EventArgs e)
{
    var settings = new BarcodeSettings
    {
        Type = BarCodeType.QRCode,
        Data = txtInput.Text
    };

    var generator = new BarCodeGenerator(settings);
    using var ms = new MemoryStream();
    generator.GenerateImage().Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    imgQR.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(ms.ToArray());
}

The generated image is embedded directly into an asp:Image control using a Base64 data URI.


5. Conclusion

With Spire.Barcode for .NET, you can seamlessly generate and customize QR codes across all ASP.NET project types — Razor Pages, MVC, Web API, or Web Forms. The solution is fully offline, fast, and requires no third-party API.

Returning images as Base64 strings simplifies deployment and avoids file management. Whether you're building authentication tools, ticketing systems, or contact sharing, this approach is reliable and production-ready.


FAQs

Q: Does Spire.Barcode support Unicode characters like Chinese or Arabic?

A: Yes. Use QRCodeDataMode.Byte for full Unicode support.

Q: Can I adjust QR code size and color?

A: Absolutely. Use properties like X, ForeColor, and ImageWidth.

Q: Is this solution fully offline?

A: Yes. It works without any external API calls or services.

Q: Can I expose this QR logic via API?

A: Yes. Use ASP.NET Web API to serve generated images to client apps.

Exporting data from a database to Excel using C#

Exporting data from a database to Excel using C# is a frequent requirement in business applications—be it for internal reporting, audit logs, data migration, or ad-hoc analysis. Excel's portability and familiarity make it a go-to format for sharing structured data with both technical and non-technical users.

In this guide, you'll learn how to export database records to Excel using C# and Spire.XLS for .NET. We’ll walk through retrieving data from a SQL Server database and writing it into a well-formatted Excel file. The same workflow applies to other relational databases such as SQLite, MySQL, or Oracle with only minimal adjustments.

Table of Contents:


Prerequisites and Environment Setup

Before we dive into code, ensure your development environment is ready:

  • .NET Version: .NET Framework or .NET Core / .NET 6 / .NET 8

  • IDE: Visual Studio (Community or higher)

  • Database: A relational database (e.g., SQL Server, SQLite, MySQL, Oracle). This tutorial uses SQL Server Express as the example. By default, the connection uses Windows Authentication, but you can switch to SQL Authentication if needed.

  • Libraries:

Sample Data

In the following examples, we'll use a simple Employees table stored in SQL Server Express. Here's the SQL script to create and populate it:

CREATE TABLE Employees (
    Id INT PRIMARY KEY IDENTITY,
    Name NVARCHAR(100) NOT NULL,
    Department NVARCHAR(50) NOT NULL,
    Position NVARCHAR(50),
    HireDate DATE NOT NULL,
    Salary DECIMAL(10, 2) NOT NULL,
    IsFullTime BIT NOT NULL
);

INSERT INTO Employees (Name, Department, Position, HireDate, Salary, IsFullTime) VALUES
('Alice Johnson', 'Human Resources', 'HR Manager', '2018-05-01', 5500.00, 1),
('Bob Smith', 'IT', 'Software Engineer', '2020-09-15', 7200.50, 1),
('Charlie Lee', 'Finance', 'Accountant', '2019-11-20', 6300.75, 0),
('Diana Chen', 'Marketing', 'Content Specialist', '2021-02-10', 4800.00, 1);

If you're using another database system like MySQL or SQLite, just adjust the SQL syntax and connection string accordingly. The export logic remains the same.


Exporting Data from SQL Database to Excel in C#

Let’s walk through how to retrieve data from a database and export it to an Excel file using Spire.XLS for .NET.

Step 1: Connect to the SQL Server Database

We start by establishing a connection to the database using SqlConnection. Here's an example connection string targeting SQL Server Express:

string connectionString = @"Data Source=YourServer\SQLEXPRESS;Initial Catalog=YourDatabaseName;Integrated Security=True;";

The above connection string uses Windows Authentication (Integrated Security=True). If you prefer SQL Server Authentication, replace it with: User ID=yourUsername;Password=yourPassword;Encrypt=True;TrustServerCertificate=True;

Make sure that your SQL Server Express instance is running, and that the specified database and table exist.

Step 2: Retrieve Data into a DataTable

To make the data ready for export, we use SqlDataAdapter to fill a DataTable with the results of a SQL query:

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

DataTable dataTable = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    string query = "SELECT * FROM Employees";
    using (SqlDataAdapter adapter = new SqlDataAdapter(query, conn))
    {
        adapter.Fill(dataTable);
    }
}

Spire.XLS can directly import data from a DataTable using InsertDataTable, which makes it ideal for structured exports from relational databases.

Step 3: Export the DataTable to Excel Using Spire.XLS

Once the DataTable is populated, we can use Spire.XLS to write its contents into a new Excel worksheet:

using Spire.Xls;

// Create a new workbook
Workbook workbook = new Workbook();
// Clear the default sheets and create a new one
workbook.Worksheets.Clear();
Worksheet sheet = workbook.Worksheets.Add("Employees");

// Insert data starting from row 1, column 1, and include column headers
sheet.InsertDataTable(dataTable, true, 1, 1);

// Save the workbook as an Excel xlsx file
workbook.SaveToFile("Employees.xlsx", ExcelVersion.Version2013);

Key classes and methods used:

  • Workbook: The main entry point for creating or loading Excel files.
  • Worksheet: Represents a single sheet in the workbook. Use workbook.Worksheets[] to access a sheet, or Worksheets.Add() to add more.
  • InsertDataTable(DataTable dataTable, bool columnHeaders, int firstRow, int firstColumn):
    • columnHeaders = true tells Spire.XLS to write column names as the first row.
    • firstRow, firstColumn specify where the data begins (1-based index).
  • Workbook.SaveToFile(string fileName, ExcelVersion version): Saves the workbook to a file. Spire.XLS supports saving Excel workbooks to various formats, including .xlsx, .xls, and .csv. You can also save to a stream using SaveToStream().

Here’s what the resulting Excel file looks like with the raw data exported from the database.

Excel file exported from SQL database using C#


Step 4: Format the Excel Output (Optional but Recommended)

While the data is already exported, applying some formatting can significantly improve readability for end users:

// Write data to Excel, including column names, starting at row 1, column 1
sheet.InsertDataTable(dataTable, true, 1, 1);

// Make header row bold and highlight with background color
sheet.Rows[0].Style.Font.IsBold = true;
sheet.Rows[0].Style.Font.Size = 14;
sheet.Rows[0].Style.HorizontalAlignment = HorizontalAlignType.Center;
sheet.Rows[0].Style.Color = System.Drawing.Color.LightGray;

// Format data rows
for (int i = 1; i < sheet.Rows.Count(); i++)
{
    CellRange dataRow = sheet.Rows[i];
    dataRow.Style.Font.Size = 12;
    dataRow.Style.HorizontalAlignment = HorizontalAlignType.Left;
}

// Set font name
sheet.AllocatedRange.Style.Font.FontName = "Arial";

// Set borders
sheet.AllocatedRange.BorderAround(LineStyleType.Thin, System.Drawing.Color.Black);
sheet.AllocatedRange.BorderInside(LineStyleType.Medium, System.Drawing.Color.Black);

// Auto-fit columns
sheet.AllocatedRange.AutoFitColumns();

Here's what the Excel file looks like after formatting.

Excel file exported from SQL database using C# with formatting

Spire.XLS provides full access to cell styles, fonts, colors, borders, alignment, and more—making it suitable for generating production-quality Excel reports.

If you need advanced number formatting, learn how to set number formats for Excel cells using C#.


Alternative Approaches to Read Data

The export process relies on having a DataTable, but how you populate it can vary based on your application architecture:

A. Using Entity Framework (ORM)

If you use EF Core or EF6, you can load data via LINQ and manually insert it into Excel:

var employees = dbContext.Employees.ToList();

To export, either convert this list into a DataTable, or use a loop to write rows manually using sheet.Range[row, col].Value = value.

B. Using Stored Procedures

Stored procedures allow encapsulating SQL logic. You can execute them using SqlCommand and fill the result into a DataTable:

SqlCommand cmd = new SqlCommand("GetEmployees", conn);
cmd.CommandType = CommandType.StoredProcedure;

C. Reading from SQLite

For lightweight scenarios, replace the connection string and class:

using (SQLiteConnection conn = new SQLiteConnection("Data Source=mydb.db"))

Export logic remains identical—fill a DataTable and use InsertDataTable.

D. Reading from MySQL or Oracle

Same pattern applies—just change the connection class:

using (MySqlConnection conn = new MySqlConnection("server=localhost;uid=root;pwd=123;database=test"))

Make sure to install the appropriate ADO.NET data provider (e.g., Microsoft.Data.SqlClient, Microsoft.Data.Sqlite, or MySql.Data) via NuGet when connecting to different databases.

As long as you populate a DataTable, Spire.XLS handles the Excel generation the same way.

You may also like: How to Import Data from Excel to Database – learn how to complete the full data exchange cycle using Spire.XLS.


Common Issues and Troubleshooting

Issue Solution
Excel file opens empty Ensure the DataTable has data before calling InsertDataTable()
Access denied on save Check folder permissions or file path conflicts
Connection fails Verify your database server, credentials, and connection string
Special characters not displaying Use NVARCHAR in SQL and Unicode-compatible fonts in Excel
Login failed or authentication error Check authentication method: use Integrated Security=True for Windows, or provide User ID and Password for SQL Authentication.

Conclusion

Exporting a database to Excel in C# can be done efficiently using Spire.XLS for .NET. By retrieving data into a DataTable and exporting it with InsertDataTable(), you can automate reporting and data extraction without needing Microsoft Office installed.

This solution can also be integrated into scheduled tasks, background services, or web applications for automated report generation.

To unlock all features during development or testing, you can apply for a free 30-day temporary license. For smaller projects, Free Spire.XLS for .NET may also be sufficient.


FAQ

How do I export SQL to Excel in C#?

Use SqlConnection to retrieve data into a DataTable, and export it using Spire.XLS’s InsertDataTable() method.

Can I use this method with SQLite or MySQL?

Yes. Just change the connection type and query, then pass the resulting DataTable to Spire.XLS.

Do I need Excel installed to use Spire.XLS?

No. Spire.XLS is a standalone library and does not require Microsoft Excel on the machine.

Can I export multiple tables to Excel?

Yes. Use Workbook.Worksheets.Add() to create additional worksheets, and export each DataTable separately.

Page 3 of 95
page 3