.net使用免費開源類庫操作Excel

摘要:本文介紹.NET使用免費開源類庫MyXls、Koogra、ExcelLibrary、ExcelPackage、EPPlus、LinqToExcel、NetOffice操作Excel,並提供示例代碼供參考。
本文並不是原創,原文地址:http://www.csharpwin.com/csharpspace/13006r5351.shtml
在這裏只是分享給大家。

主要找到以下類庫:

MyXls(http://sourceforge.net/projects/myxls/)
Koogra(http://sourceforge.net/projects/koogra/)
ExcelLibrary(http://code.google.com/p/excellibrary/)
ExcelPackage(http://excelpackage.codeplex.com/)
EPPlus(http://epplus.codeplex.com/)
LinqToExcel(http://code.google.com/p/linqtoexcel/)
NetOffice(http://netoffice.codeplex.com/) 需安裝Office Excel
從1-6的類庫均不需要安裝Office,不使用Office COM組件;而NetOffice需要安裝Office,它提供的是與Office COM組件差不多的功能。

注:本文僅簡單演示讀取與創建Excel。

準備測試代碼

首先,爲這些類庫準備一些測試代碼,用於之後的測試。

aspx主要代碼如下:

<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="上傳Excel"
οnclick="Button1_Click" />
<asp:Button ID="Button2" runat="server" Text="下載Excel"
οnclick="Button2_Click" />
<asp:GridView ID="GridView2" runat="server">
</asp:GridView>aspx.cs主要代碼如下:
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空間下,主要測試代碼如下:

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空間,主要測試代碼如下:

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空間,主要測試代碼如下:
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空間):

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空間,具體測試代碼如下:

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格式通吃了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章