Mego(04) - NET simple implementation of EXCEL import and export

foreword

I believe that friends who have done information systems will encounter related development of EXCEL import and export. After doing a lot of EXCEL import and export, it can be summarized in the following ways:

  • ADO.NET's OldDb or ODBC connection EXCEL uses DataTable to read data.
  • Microsoft.Office.Interop.Excel uses components provided by Microsoft to manipulate WorkSheet objects.
  • Use some third-party libraries such as Fast Excel, ExcelDataReader, etc.

Today, I will introduce to you a simpler way to achieve various EXCEL import and export requirements for daily development.

simple import

We still use System.Data.OleDb in ADO.NET as the bottom layer, which is very efficient. First define an object to carry data.
c# public class Product { public int Id { get; set; } public string Code { get; set; } public string Name { get; set; } public int Category { get; set; } public bool IsValid { get; set; } }c#
then declares a connection string model as follows

private const string conStr =
    @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0 Xml;HDR=YES'";

Finally declare a context for accessing EXCEL

public class ExcelContext : DbContext
{
    public ExcelContext(string filename)
        : base(string.Format(conStr, filename), "System.Data.OleDb.Excel")
    {
        this.Configuration.EnableAutoConversionStorageTypes = true;
    }
    public DbSet<Product> Products { get; set; }
}

The preparation work is complete here, and then we can extract data from the data source as follows:

using (var context = new ExcelContext("sample.xls"))
{
    var data = context.Products.ToArray();
}

It only takes two lines of code to get the data and convert it into a NET object. If there is a context that can access the business database, the data can be directly imported, such as the following temporary code:

using (var context = new OracleContext())
{
    context.Products.AddRange(data);
    context.Executor.Execute();
}

So far, we can complete the work of extracting data from EXCEL and importing data into the database in a very simple way.

Universal import

Maybe you will consider that there are many formats for importing EXCEL, and you cannot define a context and data object class every time. Here we can define a general way to read EXCEL.
We still use the above connection string to define a general data context.

public class AnonymouExcelContext : DbContext
{
    public AnonymouExcelContext(string filename)
        : base(string.Format(conStr, filename), "System.Data.OleDb.Excel")
    {
        this.Configuration.EnableAutoConversionStorageTypes = true;
    }
}

Then we use the anonymous object of C# to read the data.

using (var context = new ExcelContext("sample.xls"))
{
    var item = new { Id = 1, Name = "P", IsValid = false };
    var data = context.Set(item, "Products").Where(a => a.Id > 20).ToArray();
}

We first define an anonymous object, which is actually an anonymous declaration of the fields to be imported. Another advantage of using anonymous types is that LINQ operations can be performed, such as the above code.

export data

Exporting EXCEL is also a troublesome thing. First, you need to write the header, and then write the data. Maybe in different scenarios, you need to write the exported code. This is especially serious when using Microsoft.Office.Interop.Excel to export. Here we still use the above data context to export data.
First let's create some data for export.

Random r = new Random();
var products = Enumerable.Range(0, 1000).Select(i => new Product()
{
    Id = i,
    Name = "Product " + i.ToString(),
    Category = r.Next(1, 10),
    Code = "P" + i.ToString(),
    IsValid = true
});

We need to create a blank EXCEL file, no code is declared here.
Finally, write the header and content:

using (var context = new ExcelContext(filename))
{
    var operate = context.Database.Manager.CreateTable<Product>();
    context.Executor.Execute(operate);//创建表头
    context.Products.AddRange(products);
    context.Executor.Execute();//写入数据
}

The same anonymous object can also be operated in the same way,
creating data

Random r = new Random();
var items = Enumerable.Range(0, 1000).Select(i => new
{
    Id = i,
    Name = "Product " + i.ToString(),
    Category = r.Next(1, 10),
    IsValid = true
}).ToArray();

data input

using (var context = new ExcelContext(filename))
{
    var item = items[0];
    var operate = context.Database.Manager.CreateTable(item.GetType(),
        DbName.NameOnly("Sheet1$"));
    context.Executor.Execute(operate);
    context.Set(item, "[Sheet1$]").AddRange(items);
    context.Executor.Execute();
}

Complex EXCEL import

Most of the development needs can be met through the above code, but the business needs are endless. I wonder if you have encountered the following EXCEL import cases.
Customers need to import tens of thousands of orders plus detailed data at a time. Before officially importing them into the database, they need to browse, confirm and modify on the system interface. After confirming that there is no error, they can send commands to write to the database. (The most troublesome is that this is a WEB-based system).

Uploading EXCEL is indispensable, but browsing and modifying will be a little troublesome. However, based on a good user experience, it is necessary to save EXCEL in a temporary location on the server, and then display the data to the user on a page and provide the modification function, and finally submit it to the database after the user confirms.
First we create a relatively complex data context.

internal class ComplexContext : DbContext
{
    public ComplexContext(string filename)
        : base(string.Format(conStr, filename), "System.Data.OleDb.Excel")
    {
        this.Configuration.EnableAutoConversionStorageTypes = true;
    }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Product> Products { get; set; }
}

The definition of the data class is ignored here. The relationship between the data here is that the order has multiple details, the order is related to a customer, and the details are related to a product. For EXCEL, this is already very complicated.
However, here you can easily query all orders and order details, filter and add tabs to display data to users, as shown below

using (var context = new ComplexContext("sample.xls"))
{
    var query = from a in context.Orders.Include(a=>a.Details)
                where a.Id > 4
                select a;
    var items = query.Take(10).Skip(20).ToArray();
}

We go directly to the previous figure to prove the correctness of the data.

The above code has been uploaded to Github .

The above are all EXCEL operations based on the Mego framework . Of course, Mego also supports many databases. You are welcome to try it out.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325233076&siteId=291194637