Mego(04) - NET简单实现EXCEL导入导出

前言

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

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

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

简单导入

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

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#

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

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

原文地址:https://www.cnblogs.com/CarefreeXT/p/8988264.html

时间: 2024-11-03 22:35:29

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

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

前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴.经过思考,认为一百个客户在录入excel的时候,就会有一百个格式版本,所以在实现这个功能之前,所以要统一excel的格式.于是提供了一个通用excel模版的下载功能.当所有客户用模版录入好数据再上传到系统,后端对excel进行解析,然后再持久化到数据库. 概述: 此工具类的几大特点 1.基本导入导出

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

1:前言 看过我文章的网友们都知道,通常前言都是我用来打酱油扯点闲情的. 自从写了上面一篇文章之后,领导就找我谈话了,怕我有什么想不开. 所以上一篇的(下)篇,目前先不出来了,哪天我异地二次回忆的时候,再分享分享. 话说最近外面IT行情飞涨还咋的,人都飞哪去了呢,听说各地的军情都进入紧急状态了. 回归下正题,今天就抽点时间,写写技术文,和大伙分享一下近年在框架设计上的取的一些技术成果. 2:项目背景 在针对运营商(移动.联通.电信.铁塔)的信息类的系统中,由于相关的从业人员习惯于Excel的办公

开发指南专题十五:JEECG微云快速开发平台EXCEL导入导出

 开发指南专题十五:JEECG微云快速开发平台EXCEL导入导出 14.EXCEL导入导出 Excel的导入导出抽取通用功能,简化大家对POI的操作,对实体对象进行简单的注解配置就可以完成导入导出,模板的使用更是可以让打造漂亮的Excle报表,从而使大家从重复的工作中解脱出来,更加关注与业务的处理. 14.1注解介绍    注解名 作用对象 描述 是否必须 Excel 字段 对Excel字段的cell属性设置 是 ExcelCollection 字段 对集合对象进行标记表示一对多导出 否 E

java jxl excel 导入导出的 总结(建立超链接,以及目录sheet的索引)

最近项目要一个批量导出功能,而且要生成一个单独的sheet页,最后后面所有sheet的索引,并且可以点击进入连接.网上搜索了一下,找到一个方法,同时把相关的excel导入导出操作记录一下!以便以后使用! 简单先写一下目录的建立的主要代码,测试用的 List ls = new ArrayList();//报表名称列表  ls.add("BB_BB03");  ls.add("BB_BB05");  ls.add("BB_BB06"); try { 

excel 导入导出测试点

目前,为方便操作,很多系统都会增加批量导入导出的功能.文件导入导出一般格式都是excel.由于用户直接在excel在填写内容,无法控制填写的格 式,加上excel解析比较困难,所以一般涉及到excel导入导出功能测试起来都较为繁杂.现将常用设计用例总结如下. 批量导入 一.模板检查测试 一般excel导入功能,都会提供模板下载功能. 1.模板只有一个文件 模板只有一个文件时,比较简单,检查一下模板和预期是否一致即可. 2.模板是一个压缩包 模板是压缩包时,需要检查一下压缩包中文件是否齐全,每一个

利用反射实现通用的excel导入导出

如果一个项目中存在多种信息的导入导出,为了简化代码,就需要用反射实现通用的excel导入导出 实例代码如下: 1.创建一个 Book类,并编写set和get方法 1 package com.bean; 2 3 public class Book { 4 private int id; 5 private String name; 6 private String type; 7 // public int a; 8 9 public String getType() { 10 System.ou

excel导入导出优化

对于上一篇excel中出现的问题,在excel导入导出中都做了优化.还是eclipse+jdk1.8,但是这个项目是一个web项目,需要配合Tomcat服务器,并且使用了SSH框架, I/O操作过多 首先,对于I/O操作过多,那么就不像之前一样,一条一条的添加或者更新;而且凑齐一堆,也就是一个list集合,然后统一的批量保存. 使用SessionFactory获取当前的session,然后调用session的persist方法,保存实体.只是设置了一个批量的量值.每到30条数据,就将缓存同步到数

POI实现excel导入导出

1.分析excel import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.Ce

[Utils]POI实现excel导入导出

1.分析excel 2.poi工具类 import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.s