利用 NPOI Library 合併多個 Excel 檔
所謂合併多個 Excel 檔,是指可能有多張欄位相同的工作表 (Sheet),分散在多個活頁簿 (Workbook,一個實體 Excel 檔),使用者希望可以寫一支程式自由指定上傳的活頁簿,接著點個按鈕就能把多張工作表由上而下、一個接一個合併成為一張大工作表。這需求在仔細端詳教學文之後,估計利用 NPOI 函式庫來做應該是可行的,且似乎能夠省去一堆麻煩事,所以就來寫寫看吧!
預備知識以及環境設定就不提了,請自行參考上述教學文,網頁配置如下 (僅列重點):
<div>
<asp:FileUpload ID="FileUpload1" runat="server" /><br />
<asp:FileUpload ID="FileUpload2" runat="server" /><br />
<asp:FileUpload ID="FileUpload3" runat="server" /><br />
<asp:Button ID="MergeButton" runat="server" Text=" 合併讀取 " OnClick="MergeButton_Click" /><hr />
<asp:GridView ID="gvXLS" runat="server" BackColor="White" BorderColor="#336666" BorderStyle="Double"
BorderWidth="3px" CellPadding="4" GridLines="Horizontal">
<RowStyle BackColor="White" ForeColor="#333333" />
<FooterStyle BackColor="White" ForeColor="#333333" />
<PagerStyle BackColor="#336666" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#339966" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#336666" Font-Bold="True" ForeColor="White" />
</asp:GridView>
</div>
</form>
主要程式碼改寫自教學文,只修改小部分而已:
// using System.Data;
// using System.IO;
// using NPOI.HSSF.UserModel;
private void MergeData(Stream fileStream, DataTable dt)
{
HSSFWorkbook workbook = new HSSFWorkbook(fileStream);
HSSFSheet sheet = workbook.GetSheetAt(0);
HSSFRow headerRow = sheet.GetRow(0);
int cellCount = headerRow.LastCellNum;
if (dt.Rows.Count == 0)
{
// 首次執行仍未有資料,須先建立 Header
for (int i = headerRow.FirstCellNum; i < cellCount; i++)
{
DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);
dt.Columns.Add(column);
}
}
else
{
// TODO:檢查後續 sheet 欄位是否相符
}
int rowCount = sheet.LastRowNum + 1;
for (int i = (sheet.FirstRowNum + 1); i < rowCount; i++)
{
HSSFRow row = sheet.GetRow(i);
DataRow dataRow = dt.NewRow();
for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (row.GetCell(j) != null)
dataRow[j] = row.GetCell(j).ToString();
}
dt.Rows.Add(dataRow);
}
workbook = null;
sheet = null;
}
protected void MergeButton_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
foreach (Control c in Page.Form.Controls)
{
if (c.GetType().Equals(typeof(FileUpload)))
{
FileUpload f = c as FileUpload;
if (f.HasFile)
MergeData(f.FileContent, dt);
}
}
if (dt.Rows.Count > 0)
{
gvXLS.DataSource = dt;
gvXLS.DataBind();
}
}
這樣就可以了,接著準備三個活頁簿,資料如圖所示:
程式開起來,依次選取三個 Excel 檔、點合併讀取,實際執行效果可以看底下截圖:
嘖嘖嘖…除了讚嘆還是讚嘆!NPOI 果然是好物一枚,跟著教學文實作,可以說是毫無滯礙,更有一種難得的暢快感!你甚至不必在伺服器端安裝 Excel 程式、擔心 Excel 工作行程沒有釋放,也不必為了 x64 平台上沒有 Microsoft.Jet.OLEDB.4.0 這個 Provider 而懊惱,最讓人激賞的是沒寫幾行程式,輕輕鬆鬆就完成合併 Excel 的功能,簡單俐落到了極點。
以上只是最基本的示範,進一步的擴充好比說:在合理限度內讓使用者動態增加上傳檔數量,或者各活頁簿擁有的工作表數量不固定,通通一併處理,以及各工作表欄位是否相符等錯誤處理機制,甚至合併多個 Excel 檔之後還要寫到資料庫或其他進一步處理…這些就留給大家自行補強囉!
更新紀錄
- 《2010/2/25》追加範例檔下載:NPOI_Practice.rar