自从上次找到NPOI之后,根据园友提供的线索以及Google,又找到了一些开源免费的类库,所以都简单体验了一遍。

主要找到以下类库:

  1. MyXls(http://sourceforge.net/projects/myxls/)
  2. Koogra(http://sourceforge.net/projects/koogra/)
  3. ExcelLibrary(http://code.google.com/p/excellibrary/)
  4. ExcelPackage(http://excelpackage.codeplex.com/)
  5. EPPlus(http://epplus.codeplex.com/)
  6. LinqToExcel(http://code.google.com/p/linqtoexcel/)
  7. NetOffice(http://netoffice.codeplex.com/) 需安装Office Excel

从1-6的类库均不需要安装Office,不使用Office COM组件;而NetOffice需要安装Office,它提供的是与Office COM组件差不多的功能。

注:本文仅简单演示读取与创建Excel。

准备测试代码

首先,为这些类库准备一些测试代码,用于之后的测试。

aspx主要代码如下:

1
2
3
4
5
6
7
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="上传Excel"
    onclick="Button1_Click" />
    <asp:Button ID="Button2" runat="server" Text="下载Excel"
    onclick="Button2_Click" />
<asp:GridView ID="GridView2" runat="server">
</asp:GridView>

aspx.cs主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private void RenderToBrowser(MemoryStream ms, string fileName)
{
    if (Request.Browser.Browser == "IE")
        fileName = HttpUtility.UrlEncode(fileName);
    Response.AddHeader("Content-Disposition", "attachment;fileName=" + fileName);
    Response.BinaryWrite(ms.ToArray());
}
 
protected void Button1_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {//读取上传的文件绑定到GridView
        GridView1.DataSource = ReadByXXX(FileUpload1.FileContent);
        GridView1.DataBind();
    }
}
 
protected void Button2_Click(object sender, EventArgs e)
{
    DataTable table = new DataTable();
    table.Columns.Add("aa", typeof(string));
    table.Columns.Add("bb", typeof(string));
    table.Columns.Add("cc", typeof(string));
    for (int i = 0; i < 10; i++)
    {
        string a = DateTime.Now.Ticks.ToString();
        Thread.Sleep(1);
        string b = DateTime.Now.Ticks.ToString();
        Thread.Sleep(1);
        string c = DateTime.Now.Ticks.ToString();
        Thread.Sleep(1);
        table.Rows.Add(a, b, c);
    }
    //从DataTable创建Excel并下载
    RenderToBrowser(CreateByXXX(table), "test.xls");
}

MyXls

MyXls支持Office Excel 97-2003格式(Biff8格式),但目前并不支持formula即公式;网上流传的支持2007是错误的说法

使用它还需要注意的是,它与Office PIA一样,索引号是从1开始的。

另外不得不说的是,它的构造函数、Save方法、属性中的FileName让人看的眼花瞭乱,无所适从呐-_-。

主要使用的类型都位于org.in2bits.MyXls空间下,主要测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
MemoryStream CreateByMyXls(DataTable table)
{
    XlsDocument doc = new XlsDocument();
    Worksheet sheet = doc.Workbook.Worksheets.Add("Sheet1");
    int colCount = table.Columns.Count;
    for (int i = 1; i <= colCount; i++)
    {
        sheet.Cells.Add(1, i, table.Columns[i - 1].Caption);
    }
 
    int k = 2;
    foreach (DataRow row in table.Rows)
    {
        for (int i = 1; i <= colCount; i++)
        {
            sheet.Cells.Add(k, i, row[i - 1]);
        }
        k++;
    }
    MemoryStream ms = new MemoryStream();
    doc.Save(ms);
    return ms;
}
 
DataTable ReadByMyXls(Stream xlsStream)
{
    XlsDocument doc = new XlsDocument(xlsStream);
    DataTable table = new DataTable();
    Worksheet sheet = doc.Workbook.Worksheets[0];
    int colCount = sheet.Rows[1].CellCount;
    int rowCount = sheet.Rows.Count;
 
 
    for (ushort j = 1; j <= colCount; j++)
    {
        table.Columns.Add(new DataColumn(sheet.Rows[1].GetCell(j).Value.ToString()));
    }
 
    for (ushort i = 2; i < rowCount; i++)
    {
        DataRow row = table.NewRow();
        for (ushort j = 1; j <= colCount; j++)
        {
            row[j - 1] = sheet.Rows[i].GetCell(j).Value;
        }
        table.Rows.Add(row);
    }
 
    return table;
}

Koogra

Koogra支持Office 97-2003(Biff8)以及Office 2007以上(Xlsx)格式,但它仅提供读取功能,没有相关的创建Excel功能;另需要注意它的索引号又是从0开始的。

我在几台机器上测试不太稳定,即有的机器直接不能运行,没有深究什么问题。

操作xls格式的类型主要位于Net.SourceForge.Koogra.Excel空间,主要测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static DataTable ReadByKoogra(Stream xlsStream)
{
    DataTable table = new DataTable();
    Workbook book = new Workbook(xlsStream);
    Worksheet sheet = book.Sheets[0];
 
    Row headerRow = sheet.Rows[0];
    uint colCount = headerRow.Cells.MaxCol;
    uint rowCount = sheet.Rows.MaxRow;
    Row tempr = null;
    Cell tempc = null;
 
    for (ushort j = 0; j <= colCount; j++)
    {
        tempc = headerRow.Cells[j];
        if (tempc != null)
            table.Columns.Add(new DataColumn((tempc.Value ?? string.Empty).ToString()));
    }
 
    for (ushort i = 0; i <= rowCount; i++)
    {
        DataRow row = table.NewRow();
        tempr = sheet.Rows[i];
 
        for (ushort j = 0; j <= colCount; j++)
        {
            tempc = tempr.Cells[j];
            if (tempc != null)
                row[j] = tempc.Value;
        }
        table.Rows.Add(row);
    }
 
    return table;
}

操作XLSX格式的类型主要位于Net.SourceForge.Koogra.Excel2007空间,主要测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static DataTable ReadByKoogra(Stream xlsStream)
{
    DataTable table = new DataTable();
    Workbook book = new Workbook(xlsStream);
    Worksheet sheet = book.GetWorksheet(0);
 
    Row headerRow = sheet.GetRow(0);
    uint colCount = sheet.CellMap.LastCol;
    uint rowCount = sheet.CellMap.LastRow;
    Row tempr = null;
    ICell tempc = null;
 
    for (ushort j = 0; j <= colCount; j++)
    {
        tempc = headerRow.GetCell(j);
        if (tempc != null)
            table.Columns.Add(new DataColumn((tempc.Value ?? string.Empty).ToString()));
    }
 
    for (ushort i = 0; i <= rowCount; i++)
    {
        DataRow row = table.NewRow();
        tempr = sheet.GetRow(i);
 
        for (ushort j = 0; j <= colCount; j++)
        {
            tempc = tempr.GetCell(j);
            if (tempc != null)
                row[j] = tempc.Value;
        }
        table.Rows.Add(row);
    }
 
    return table;
}

ExcelLibrary

听说这是国人开发的,目前支持97-2003(biff8)格式,未来可能会支持xlsx格式。它使用二维数组的方式来操作,这种方式比较接近Office PIA,另外,它的索引号是从0开始的。

在测试时,创建出的Excel有时内容是空的,可能存在bug。

它提供了一个DataSetHelper的工具类,用于从DataTable/DataSet和WorkBook之间的转换,但这个工具类不支持对流的操作,所以还是自己写测试代码(ExcelLibrary空间):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
MemoryStream CreateByExcelLibrary(DataTable table)
{
    Workbook book = new Workbook();
    Worksheet sheet = new Worksheet("Sheet123");
     
    int colCount = table.Columns.Count;
    for (int i = 0; i < colCount; i++)
    {
        sheet.Cells[0, i] = new Cell(table.Columns[i].Caption);
    }
 
    int k = 1;
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < colCount; i++)
        {
            sheet.Cells[k, i] = new Cell(row[i]);
        }
        k++;
    }
    book.Worksheets.Add(sheet);
    MemoryStream ms = new MemoryStream();
    book.Save(ms);
    return ms;
}
 
DataTable ReadByExcelLibrary(Stream xlsStream)
{
    DataTable table = new DataTable();
    Workbook book = Workbook.Load(xlsStream);
    Worksheet sheet = book.Worksheets[0];
 
    int colCount = sheet.Cells.LastColIndex;
    int rowCount = sheet.Cells.LastRowIndex;
 
    for (ushort j = 0; j <= colCount; j++)
    {
        table.Columns.Add(new DataColumn(sheet.Cells[0, j].StringValue));
    }
 
    for (ushort i = 1; i <= rowCount; i++)
    {
        DataRow row = table.NewRow();
        for (ushort j = 0; j <= colCount; j++)
        {
            row[j] = sheet.Cells[i, j].Value;
        }
        table.Rows.Add(row);
    }
 
    return table;
}

ExcelPackage与EPPlus

ExcelPackage它主要支持OOXML即Office Open XML标准,Office 2007以上XLSX格式的读写;但它不支持对流的操作,仅支持对实体文件的操作。

EPPlus全称应该是ExcelPackage Plus,即ExcelPackage的增强版,它在ExcelPackage的基础上,增强了许多功能包括对流、Linq的支持,可以说相当不错。

它的索引号是从1开始的,主要使用的类型位于OfficeOpenXml空间,具体测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
MemoryStream CreateByExcelLibrary(DataTable table)
{
    using (ExcelPackage package = new ExcelPackage())
    {
        ExcelWorksheet sheet = package.Workbook.Worksheets.Add("sheet111");
 
        int colCount = table.Columns.Count;
        for (int i = 0; i < colCount; i++)
        {
            sheet.Cells[1, i + 1].Value = table.Columns[i].Caption;
        }
 
        int k = 2;
        foreach (DataRow row in table.Rows)
        {
            for (int i = 0; i < colCount; i++)
            {
                sheet.Cells[k, i + 1].Value = row[i];
            }
            k++;
        }
 
        MemoryStream ms = new MemoryStream();
        package.SaveAs(ms);
        return ms;
    }
}
 
DataTable ReadByExcelLibrary(Stream xlsStream)
{
    DataTable table = new DataTable();
    using (ExcelPackage package = new ExcelPackage(xlsStream))
    {
        ExcelWorksheet sheet = package.Workbook.Worksheets[1];
 
        int colCount = sheet.Dimension.End.Column;
        int rowCount = sheet.Dimension.End.Row;
 
        for (ushort j = 1; j <= colCount; j++)
        {
            table.Columns.Add(new DataColumn(sheet.Cells[1, j].Value.ToString()));
        }
 
        for (ushort i = 2; i <= rowCount; i++)
        {
            DataRow row = table.NewRow();
            for (ushort j = 1; j <= colCount; j++)
            {
                row[j - 1] = sheet.Cells[i, j].Value;
            }
            table.Rows.Add(row);
        }
    }
 
    return table;
}

LinqToExcel,NetOffice…

至于LinqToExcel,只能说是颗糖而已,不支持对流的操作,实在是无爱啊,不多说。

NetOffice提供与Office PIA相似的功能,又需要安装Office,实在不适合在web场景中使用,所以也不多说。

结尾

对于Excel 97-2003格式,还是用NPOI最好,API设计比较好(上面这些类库又是0又是1的索引号和二维数组实在让人好晕);而对于2007(xlsx)以上版本,可以使用EPPlus;这样基本所有的Excel格式通吃了。

当然这只是免费的方案,对于不缺大洋的,用Apose.Cell等强大的商业解决方案又是另一回事了。

另,由于各个类库容量较大,就不提供下载了,若要测试请自行下载类库复制代码~_~。

使用开源免费类库在.net中操作Excel的更多相关文章

  1. 一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)

    在目前的软件项目中,都会较多的使用到对文档的操作,用于记录和统计相关业务信息.由于系统自身提供了对文档的相关操作,所以在一定程度上极大的简化了软件使用者的工作量. 在.NET项目中如果用户提出了相关文 ...

  2. 免费高效实用的.NET操作Excel组件NPOI(.NET组件介绍之六)

    很多的软件项目几乎都包含着对文档的操作,前面已经介绍过两款操作文档的组件,现在介绍一款文档操作的组件NPOI. NPOI可以生成没有安装在您的服务器上的Microsoft Office套件的Excel ...

  3. j2e中操作EXCEL

    在j2e中操作excel,无非2种情况,在这里我贴部分代码做个例子就OK,不管是导入和导出都是操作的都是流 1,导入,浏览器输入EXCEL到java后台解析 package action; impor ...

  4. C#项目中操作Excel文件——使用NPOI库

    转载自:http://blog.csdn.net/dcrmg/article/details/52356236# 感谢-牧野- 实际C#项目中经常会涉及到需要对本地Excel文件进行操作,特别是一些包 ...

  5. python中操作excel数据

    python操作excel,python有提供库 本文介绍openpyxl,他只支持新型的excell( xlsx)格式,读取速度还可以 1.安装 pip install openpyxl 2.使用 ...

  6. Asp.net中操作Excel的代码解析

    一 . 使用Excel对象模型创建Excel文档: 1.创建简单的文档 try { 3 //创建Excel程序对象 Microsoft.Office.Interop.Excel.Application ...

  7. MySQL 中操作excel表格总结

    最近在负责一个项目的落地工作,需要每天导出客户通讯录进行统计各地区注册用户数.使用用户数.未使用用户数.注册不符合规范的用户等等操作,刚开始用户数量比较少,直接在excel中筛选查询就行,但是随着用户 ...

  8. python中操作excel数据 封装成一个类

    本文用python中openpyxl库,封装成excel数据的读写方法 from openpyxl import load_workbook from openpyxl.worksheet.works ...

  9. 详解免费高效实用的.NET操作Excel组件NPOI(转)

    有时间研究一下NPOI http://www.cnblogs.com/pengze0902/p/6150070.html

随机推荐

  1. Java程序,JDK的安装、环境的配置

    打开文件包,找到jdk-8u111-windows-x64  (64位)  双击打开安装界面 路径自行更改;(不可使用中文字段)新建一个文件夹放后面这个安装包 二.设置环境变量 右键我的电脑-属性-高 ...

  2. JDBC增删改查和查唯一的完整代码

    第一部分代码(实体类) package com.wf.entity; public class Hehe{ private int hehe_id; private String hehe_name; ...

  3. Mybatis批量添加对象List

    1.对应的xml文件: <!--批量添加--><insert id="insertStandardItemInfo" parameterType="ha ...

  4. log4j在javaWeb项目中的使用

    在前边的文章中对log4j的配置文件进行了说明,今天介绍如何在普通的javaWeb项目中使用log4j. 在日常的开发过程中,日志使用的很频繁,我们可以利用日志来跟踪程序的错误,程序运行时的输出参数等 ...

  5. 配置云服务器 FTP 服务

    自己配置的环境: OS: 阿里云 CentOS 6.5 >>Begin: 1. 登录到阿里云服务器(如何登录阿里云服务器), 在root权限下, 通过如下命令安装 vsftp [root@ ...

  6. Java接口之间的继承

    /** * Created by xfyou on 2016/11/3. * 多接口之间的继承 */ public class HorrorShow { static void u(Monster b ...

  7. Java final类

    如果说整个类都是final(在它的定义前冠以final关键字),就表明自己不希望从这个类继承,或者不允许其他任何人采取这种操作.换言之,出于这样或那样的原因,我们的类肯定不需要进行任何改变:或者出于安 ...

  8. 网上图书商城2--Category模块

    sql CREATE TABLE `t_category` ( `cid` char(32) NOT NULL, `cname` varchar(50) DEFAULT NULL, `pid` cha ...

  9. java集合-hashCode

    hashCode 的作用 在 Java 集合中有两类,一类是 List,一类是 Set 他们之间的区别就在于 List 集合中的元素师有序的,且可以重复,而 Set 集合中元素是无序不可重复的.对于 ...

  10. Rational Rose :从用例图开始

    前置条件:安装Rational Rose 2003 找开Rose工具,选择用例视图  Use Case View 先看看这个视图下面都有哪些工具,都能做一些什么: 下面详细说一下: 用例视图下面有工具 ...