NET simply implements 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 imported directly, 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

导出EXCEL也是个比较麻烦的事,首先你需要写表头,然后再写入数据,可能在不同的场景下你需要重要写导出的代码这个在使用Microsoft.Office.Interop.Excel导出时特别严重。这里我们还是用上面的数据上下文来导出数据。
首先我们先创建一些数据用于导出。

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
});

我们需要创建一个空白的EXCEL文件,这里不声明代码了。
最后就是写入表头和内容:

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

同样的匿名对象也是同样可以如此操作,
创建数据

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();

写入数据

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();
}

复杂EXCEL导入

通过上面的代码已经可以满足大多数的开发需求,不过业务需求永远无止境,不知道下面EXCEL导入案例大家是否有遇到。
客户需要一次导入上万条订单加明细数据,在正式导入到数据库之前还要在系统界面上浏览确认及修改,确认无误后才发命令写入到数据库。(最麻烦的是这是个基于WEB的系统)。

上传EXCEL是少不了的,但是浏览修改会麻烦一点,不过基于良好的用户体验需要把EXCEL保存在服务器的临时位置,然后分页向用户显示数据并提供修改功能,最后当用户确认后才提交到数据库。
首先我们先创建一个相对复杂的数据上下文。

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; }
}

这里忽略数据类的定义,这里的数据间关系是订单有多个明细,订单关系一个客户,明细关系一个产品,对于EXCEL而言这已经很复杂了。
不过在这里你可以很容易的查询所有订单及订单明细,过滤加分页向用户显示数据,如下所示

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();
}

我们直接上个图来证明下数据的正确性。

以上代码都已上传Github

以上都是基于Mego框架实现的对EXCEL操作,当然Mego还支持许多数据库,欢迎大家试用。

http://news.hmb6894.cn/
http://news.zis3531.cn/
http://news.cyj2776.cn/
http://news.bpj4889.cn/
http://news.dvu3043.cn/
http://news.vrc3090.cn/
http://news.ecx0415.cn/
http://news.oyt3985.cn/
http://news.mfu9569.cn/
http://news.lev2249.cn/
http://news.bdw7316.cn/
http://news.yyf8629.cn/
http://news.baq6972.cn/
http://news.xcd5039.cn/
http://news.bed0568.cn/
http://news.hzg6462.cn/
http://news.dec9975.cn/
http://news.hyt6211.cn/
http://news.ysz1764.cn/
http://news.xah7645.cn/
http://news.rlo9176.cn/
http://news.iaz8522.cn/
http://news.mng2781.cn/
http://news.axs9870.cn/
http://news.csv7317.cn/
http://news.kpq2047.cn/
http://news.igm8568.cn/
http://news.cgn5379.cn/
http://news.axz7045.cn/
http://news.rfz4575.cn/
http://news.cxb4532.cn/
http://news.qri2046.cn/
http://news.zps7191.cn/
http://news.zcl0267.cn/
http://news.ozn1702.cn/
http://news.zbb7727.cn/
http://news.vtl3405.cn/
http://news.zht3189.cn/
http://news.zzl7747.cn/
http://news.abd5921.cn/
http://news.hch9349.cn/
http://news.hwp3498.cn/
http://news.wll1115.cn/
http://news.rol3427.cn/
http://news.akb6775.cn/
http://news.giy4971.cn/
http://news.tyo9948.cn/
http://news.uzh3227.cn/
http://news.mfc7569.cn/
http://news.otm3953.cn/
http://news.ewh1005.cn/
http://news.iip1291.cn/
http://news.dyg4913.cn/
http://news.ase4727.cn/
http://news.uqx4260.cn/
http://news.sif0574.cn/
http://news.sdb0307.cn/
http://news.thg4282.cn/

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326754015&siteId=291194637