前言

相信做过信息系统的朋友都会遇到EXCEL导入导出的相关开发,做过不少EXCEL导入导出后总结起来大致有如下几种方式实现:

  • ADO.NET的OldDb或ODBC连接EXCEL使用DataTable来读取数据。
  • Microsoft.Office.Interop.Excel用微软提供的组件操作WorkSheet对象。
  • 使用一些第三方的库比如Fast Excel、ExcelDataReader等等。

今天要向大家介绍的更简单的方式来实现日常开发的各种EXCEL导入导出需求。

简单导入

我们还是使用ADO.NET中的System.Data.OleDb做为底层,这种方式会很高效。先定义一个对象用来承载数据。

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

声明一个连接字符串模型如下

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

最后声明一个访问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; }
}

到这里准备工作就完成了,然后我们就能从数据源提取数据如下所示:

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

只要两行代码就能获取数据转成NET的对象,如果这里有一个能访问业务数据库的上下文就能直接导入数据,例如下面的临时代码:

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

到此我们都以一个很简单的方式就能完成从EXCEL提取并向数据库导入数据的工作。

万能导入

也许你会考虑到导入EXCEL的格式会很多,不能每次都来定义一个上下文和数据对象类,这里我们可以定义一种通用方式来读取EXCEL。

我们还是利用上面的连接字符串再定义一个通用的数据上下文。

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

接着我们利用C#的匿名对象来读取数据。

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

我们先定义一个匿名对象,其实就是以匿名形式声明了将要导入数据的字段,使用匿名类型还一个好处就是可以进行LINQ操作,例如上面的代码。

导出数据

导出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还支持许多数据库,欢迎大家试用。

Mego(04) - NET简单实现EXCEL导入导出的更多相关文章

  1. 有史以来功能最全,使用最简单的excel导入/导出工具

    Github地址:https://github.com/xuanbg/Utility. 还有其他一些福利,请各位园友自取. 构造方法 1.用于导出Excel文件 NpoiHelper(ExcelVer ...

  2. 简单excel导入导出

    import java.io.File;import java.io.IOException; import jxl.Cell;import jxl.Sheet;import jxl.Workbook ...

  3. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  4. Excel导入导出工具(简单、好用且轻量级的海量Excel文件导入导出解决方案.)

    Excel导入导出工具(简单.好用且轻量级的海量Excel文件导入导出解决方案.) 置顶 2019-09-07 16:47:10 $9420 阅读数 261更多 分类专栏: java   版权声明:本 ...

  5. Excel导入导出的业务进化场景及组件化的设计方案(上)

    1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候 ...

  6. 关于Excel导入导出的用例设计

    目前,为方便操作,很多系统都会增加批量导入导出的功能.文件导入导出一般格式都是excel.由于用户直接在excel在填写内容,无法控制填写的格 式,加上excel解析比较困难,所以一般涉及到excel ...

  7. Octopus——excel导入导出工具

    Octopus Octopus是一个简易的Excel导入导出工具.目前主要就两个功能: 导入:将excel中一行数据转换为指定的java对象,并通过指定的正则表达式检查合法性. 导出:按照给定的xml ...

  8. JeeSite中Excel导入导出

    在各种管理系统中,数据的导入导出是经常用到的功能,通常导入导出以Excel.CSV格式居多.如果是学习的过程中,最好是自己实现数据导入与导出的功能,然而在项目中,还是调用现成的功能比较好.近期一直使用 ...

  9. 土制Excel导入导出及相关问题探讨

    转载请注明出处https://www.cnblogs.com/funnyzpc/p/10392085.html 新的一年,又一个开始,不见收获,却见年龄,好一个猪年,待我先来一首里尔克的诗: < ...

随机推荐

  1. linu下C语言之BMP图片操作编程(下)

    前面提高了一个将BMP左转的程序,右转其实也是类似的操作,就不写了,这节,我们来实现,将一张BMP图进行灰度处理,代码贴上: #include <stdio.h> #include < ...

  2. android插件开发机制

    插件机制实质上就是由主体程序定义接口,然后由插件去实现这些接口,以达到功能模块化.Android系统是基于Linux内核的,其安全机制也继承了Linux的特性,再加上android framework ...

  3. RecyclerView下拉刷新上拉加载(三)—对Adapter的封装

    RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036 RecyclerView下拉刷 ...

  4. UNIX网络编程——客户/服务器程序设计示范(总结)

    (1)当系统负载较轻是,每来一个客户请求现场派生一个子进程为之服务的传统并发服务器程序模型就足够了.这个模型甚至可以与inetd结合使用,也就是inetd处理每个连接的接收.我们的其他意见是就重负荷运 ...

  5. (NO.00004)iOS实现打砖块游戏(三):游戏主场景和砖块

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 制作墙体 首先在SpriteBuilder中新建Wall.ccb ...

  6. Java进阶(三十二) HttpClient使用详解

    Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们 ...

  7. C++为什么要设计友元函数和友元类

    1. 首先要提一下java,比如java定义一个类1.class,会生成字节码.java有反射机制,可以找到类对象,直接修改类的私有属性.逐渐反射机制成为了一种标准,sun做成标准,JDK的API函数 ...

  8. UIActionSheet,UIAlertView技术分享

    UIActionSheet #import "FirstViewController.h" @interface FirstViewController ()<UIActio ...

  9. 经过一段的努力,终于成为CSDN博客专家,感谢大家支持

    感谢CSDN提供这么好的一个技术学习平台,通过各路大神的博客我成长了许多,同时也感谢支持我的朋友们,我会继续努力,用心去写好博客.还请继续关注我~ 谢谢!

  10. tomcat集群实现源码级别剖析

    随着互联网快速发展,各种各样供外部访问的系统越来越多且访问量越来越大,以前Web容器可以包揽接收-逻辑处理-响应整个请求生命周期的工作,现在为了构建让更多用户访问更强大的系统,人们通过不断地业务解耦. ...