C#使用NPOI讀寫excel
阿新 • • 發佈:2019-01-01
NPOI作為POI專案的.NET 版本,確實是能很方便的實現讀寫Excel,那麼本文就作為科普,從頭到尾實現以下通過NOPI 讀寫Excel吧!
首先需要下載NOPI,這裡是連結,下載最新版本就行http://npoi.codeplex.com/releases
本人下載的是2.1.3版本解壓開啟後
進入dotnet4就能找到我們需要的dll檔案,我測試時使用的環境是vs2010通過新增引用的方式,把dll檔案新增進工程就可以,當然只是簡單的讀寫Excel的話就不需要把所有的dll檔案都新增進來,我只添加了三個
在這裡為了方便演示我使用winform,同時添加了一個控制元件farpoint spread,關於這種控制元件的新增就不詳細說明了,在網上搜索就能找到新增後的結果如下
OK,接下來實現的就是各個按鈕的功能了,通過NOPI讀取資料主要是在第一個按鈕中實現,因此我只把第一的按鈕的程式碼寫上吧!
可以看出,主要用了一個函式,那麼我就來看看這個函式的實現private void button1_Click(object sender, EventArgs e) { if (this.openFileDialog1.ShowDialog() == DialogResult.OK) { this.textBox1.Text = this.openFileDialog1.FileName; TestExcelRead(this.openFileDialog1.FileName.Replace("\\","//"));//把"\"換成"//" } }
</pre><pre name="code" class="csharp">private void TestExcelRead(string file) { try { using (ExcelHelper excelHelper = new ExcelHelper(file)) { //第一引數:excel分頁名,第二個引數第一行是否是列名 DataTable dt = excelHelper.ExcelToDataTable("MySheet",false); this.ShowData(dt); } } catch (Exception ex) { Console.WriteLine("Exception: " + ex.Message); } }
當然這裡用了一個ExcelHelper類例項化了一個物件excelHelper,我們稍後再說這個類的實現我們還呼叫了一個ShowData函式用來在Spread上顯示函式非常簡單
private void ShowData(DataTable data)
{
if (data == null) return;
for (int i = 0; i < data.Rows.Count; ++i)
{
for (int j = 0; j < data.Columns.Count; ++j)
{
this.fpSpread1_Sheet1.Cells[i, j].Text = data.Rows[i][j].ToString();
}
}
}
就是將DataTable的資料寫到我們的控制元件中而已,接下來我們來看看核心的也就是ExcelHelper類
class ExcelHelper:IDisposable
{
private string fileName = null; //檔名
private IWorkbook workbook = null;
private FileStream fs = null;
private bool disposed;
public ExcelHelper(string fileName)
{
this.fileName = fileName;
disposed = false;
}
/// <summary>
/// 將excel中的資料匯入到DataTable中
/// </summary>
/// <param name="sheetName">excel工作薄sheet的名稱</param>
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
/// <returns>返回的DataTable</returns>
public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
{
ISheet sheet = null;
DataTable data = new DataTable();
int startRow = 0;
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);//讀取檔案
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = workbook.GetSheet(sheetName);//獲取檔案的分頁
if (sheet == null) //如果沒有找到指定的sheetName對應的sheet,則嘗試獲取第一個sheet
{
sheet = workbook.GetSheetAt(0);
}
}
else
{
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
int k = 0, cellCount = 0;
IRow firstRow = sheet.GetRow(0);//獲取第一行
while (firstRow == null)
{
firstRow = sheet.GetRow(++k);//排除空行,找到第一個有字元的行
}
if (isFirstRowColumn)//第一行是列名
{
cellCount = firstRow.LastCellNum; //一行最後一個cell的編號 即總的列數
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
}
startRow = sheet.FirstRowNum + 1;
}
else// 第一行不是列名
{
int max = 0;
for (int i = sheet.FirstRowNum; i <= sheet.LastRowNum; i++)// 找到所有行中最多字元
{
if (sheet.GetRow(i) == null)
continue;
max = (sheet.GetRow(i).LastCellNum > max) ? sheet.GetRow(i).LastCellNum : max;
}
cellCount = max;
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
DataColumn column = new DataColumn();
data.Columns.Add(column);
}
startRow = sheet.FirstRowNum;
}
//最後一列的標號
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)//將從檔案中獲取的資料儲存到DataTable中
{
IRow row = sheet.GetRow(i);
if (row == null)
{
continue; //沒有資料的行預設是null
}
DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理,沒有資料的單元格都預設是null
dataRow[j] = row.GetCell(j).ToString();
}
data.Rows.Add(dataRow);
}
}
return data;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (fs != null)
fs.Close();
}
fs = null;
disposed = true;
}
}
自此主要功能以闡述完畢,以下結果
不足:此程式碼對於各種情況的判斷考慮的還不是很到位,例如空檔案應該報錯,由於時間比較緊,所以先寫這些,還有spread這個控制元件還有Bug在這隻作為演示之用!