EXCEL 類別 - 透過 OLEDB 來存取 EXCEL 檔案
透過 OLEDB 來存取 EXCEL 檔案,若要存取 EXCEL 2007 之後的版本,請務必要安裝 Microsoft Access Database Engine 2010 或 2013 版。
程式經由登錄檔 HKLM\SOFTWARE\ODBC\ODBCINST.INI\Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb) 來判斷是否已安裝新版 ACE.OLEDB 的驅動程式,在讀取舊版EXCEL檔案時會優先使用新版的驅動程式,當讀取新版EXCEL檔時,若無安裝新版驅動時,則會回傳無法建立檔案的訊息。
提供的方法:
CreateXlsFile - 建立 EXCEL 檔案,可以將 DataGridView/DataSet / DataTable 匯出為 EXCEL 檔案
GetAllSheetName - 取回 EXCEL 檔中所有 Sheet 的名稱
InsertSheetData - 將 DataGridView/DataSet / DataTable 附加到 EXCEL 檔案中,成為 Sheet 資料。
ReadXlsFile - 將 EXCEL 檔案中所有的 Sheet 資料讀入到 DataSet ,或是指定 Sheet 資料讀入到 DataTable 。
ReadXlsFirstShee - 將 EXCEL 檔案中第一個 Sheet 資料讀入到 DataTable。
using System;
using System.Data;
using System.Data.OleDb;
using System.Windows.Forms;
namespace Utility
{
/// <summary>
/// EXCEL 檔案處理類別
/// </summary>
/// <remarks>
/// 系統會自行偵測目前可以使用的驅動程式。<br/>
/// 當匯出格式為 Excel 97~2003 時,先採用 ACE.OLEDB 12.0 的驅動程式,沒有安裝時則會改用 Jet.OLEDB 4.0 的驅動程式。<br />
/// 當匯出格式為 Excel 2007+ 時,則只會採用 ACE.OLEDB 12.0 的驅動程式,沒有安裝時則無法建立檔案。
/// </remarks>
public class EXCEL
{
/// <summary>
/// 定義 Excel 檔案格式類別
/// </summary>
/// <remarks>支援的 EXCEL 格式。</remarks>
public enum ExcelMode
{
/// <summary>
/// Excel 97 ~ 2003
/// </summary>
Excel97_2003 = 1,
/// <summary>
/// Excel 2007 ~ 2010
/// </summary>
Excel2007_2010 = 2
}
/// <summary>
/// 取回 OLEDB 的連線字串
/// </summary>
/// <param name="ExcelFileMode">EXCEL 檔案格式</param>
private static string OleDBConnectionString(ExcelMode ExcelFileMode)
{
Microsoft.Win32.RegistryKey regHKLM = My.Computer.Registry.LocalMachine.OpenSubKey("SOFTWARE\\ODBC\\ODBCINST.INI");
string strReturn = "";
if (ExcelFileMode == ExcelMode.Excel97_2003)
{
if (regHKLM.OpenSubKey("Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)") == null)
{
strReturn = "Data Source='{0}'; Provider='Microsoft.Jet.OLEDB.4.0'; Extended Properties='Excel 8.0; HDR=No; IMEX=0;'";
}
else
{
strReturn = "Data Source='{0}'; Provider='Microsoft.ACE.OLEDB.12.0'; Extended Properties='Excel 8.0; HDR=No; IMEX=0;'";
}
}
else
{
if (regHKLM.OpenSubKey("Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)") == null)
{
strReturn = "";
}
else
{
strReturn = "Data Source='{0}'; Provider='Microsoft.ACE.OLEDB.12.0'; Extended Properties='Excel 12.0 Xml; HDR=No; IMEX=0;'";
}
}
return strReturn;
}
/// <summary>
/// 取回 EXCEL 的所有 SheetName
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <remarks>讀取 Excel 檔案,傳回所有活頁簿的名稱。</remarks>
/// <returns>所有活頁簿名稱</returns>
public static string[] GetAllSheetName(string ExcelFileName, ExcelMode ExcelFileMode)
{
if (ExcelFileName.Trim() == "") return null;
if (!My.Computer.FileSystem.FileExists(ExcelFileName)) return null;
OleDbConnection conXLS = new OleDbConnection();
DataTable tmpTable = new DataTable();
string[] strReturn;
conXLS.ConnectionString = string.Format(OleDBConnectionString(ExcelFileMode), ExcelFileName);
if (conXLS.ConnectionString == "")
{
conXLS.Dispose();
return null;
}
try
{
conXLS.Open();
tmpTable = conXLS.GetSchema("TABLES");
conXLS.Dispose();
}
catch
{
conXLS.Dispose();
return null;
}
if ((tmpTable == null) || (tmpTable.Rows.Count == 0)) return null;
for (int i = 0; i < tmpTable.Rows.Count; i++) { tmpTable.Rows[i]["Table_Name"] = (tmpTable.Rows[i]["Table_Name"].ToString().Replace("'", "")).Replace("$", ""); }
tmpTable.AcceptChanges();
tmpTable = tmpTable.DefaultView.ToTable(true, new string[] { "Table_Name" });
strReturn = new string[tmpTable.Rows.Count];
for (int i = 0; i < tmpTable.Rows.Count; i++) { strReturn[i] = tmpTable.Rows[i]["Table_Name"].ToString(); }
return strReturn;
}
#region 建立 EXCEL 檔案
/// <summary>
/// 產生 EXCEL 檔案 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="ExportDataTable">輸出的資料表</param>
/// <remarks>將資料表(DataTable)匯出到指定的 EXCEL 檔案,如果檔案存在將會被覆寫。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataTable ExportDataTable)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, ExportDataTable, false);
}
/// <summary>
/// 產生 EXCEL 檔案 (DataGridView)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="GridViewData">匯出的資料檢視表</param>
/// <remarks>將資料表(DataTable)匯出到指定的 EXCEL 檔案,如果檔案存在將會被覆寫。<br />
/// 欄位名稱使用資料欄(Column)的標題(HeaderText)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// 資料欄設定為不顯示時,也不會匯出該欄位。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataGridView GridViewData)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, GridViewData, false);
}
/// <summary>
/// 產生 EXCEL 檔案 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="ExportDataTable">輸出的資料表</param>
/// <param name="InsertMode">附加資料</param>
/// <remarks>將資料表(DataTable)匯出並附加到指定的 EXCEL 檔案,如果檔案不存在則會自動新增檔案。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataTable ExportDataTable, bool InsertMode)
{
if (ExcelFileName.Trim() == "") return false;
if (My.Computer.FileSystem.FileExists(ExcelFileName))
{
try { if (!InsertMode) My.Computer.FileSystem.DeleteFile(ExcelFileName); }
catch { return false; }
}
return InsertSheetData(ExcelFileName, ExcelFileMode, "Sheet1", ExportDataTable);
}
/// <summary>
/// 產生 EXCEL 檔案 (DataGridView)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="GridViewData">匯出的資料檢視表</param>
/// <param name="InsertMode">附加資料</param>
/// <remarks>將資料表(DataTable)匯出並附加到指定的 EXCEL 檔案,如果檔案不存在則會自動新增檔案。<br />
/// 欄位名稱使用資料欄(Column)的標題(HeaderText)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// 資料欄設定為不顯示時,也不會匯出該欄位。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataGridView GridViewData, bool InsertMode)
{
if (ExcelFileName.Trim() == "") return false;
if (My.Computer.FileSystem.FileExists(ExcelFileName))
{
try { if (!InsertMode) My.Computer.FileSystem.DeleteFile(ExcelFileName); }
catch { return false; }
}
return InsertSheetData(ExcelFileName, ExcelFileMode, "Sheet1", GridViewData);
}
/// <summary>
/// 產生 EXCEL 檔案 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="UseTableNameForSheetName">使用資料表名稱為活頁簿名稱</param>
/// <param name="ExportDataTable">輸出的資料表</param>
/// <remarks>將資料表(DataTable)匯出到指定的 EXCEL 檔案,並使用資料表名稱做為活頁簿(SheetName)名稱。<br />
/// 如果檔案存在將會被覆寫,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, Boolean UseTableNameForSheetName, DataTable ExportDataTable)
{
if (UseTableNameForSheetName)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, ExportDataTable, ExportDataTable.TableName, false);
}
else
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, ExportDataTable, false);
}
}
/// <summary>
/// 產生 EXCEL 檔案 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="UseTableNameForSheetName">使用資料表名稱為活頁簿名稱</param>
/// <param name="ExportDataTable">輸出的資料表</param>
/// <param name="InsertMode">附加資料</param>
/// <remarks>將資料表(DataTable)匯出並附加到指定的 EXCEL 檔案,使用資料表名稱做為活頁簿(SheetName)名稱。<br />
/// 如果檔案不存在則會自動新增檔案,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, bool UseTableNameForSheetName, DataTable ExportDataTable, bool InsertMode)
{
if (UseTableNameForSheetName)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, ExportDataTable, ExportDataTable.TableName, true);
}
else
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, ExportDataTable, true);
}
}
/// <summary>
/// 產生 EXCEL 檔案,使用指定活頁簿名稱 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="ExportDataTable">輸出的資料表</param>
/// <param name="SheetName">活頁簿名稱</param>
/// <remarks>將資料表(DataTable)匯出到指定的 EXCEL 檔案並使用指定的活頁簿名稱(SheetName)。<br />
/// 如果檔案存在將會被覆寫,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataTable ExportDataTable, string SheetName)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, ExportDataTable, SheetName, false);
}
/// <summary>
/// 產生 EXCEL 檔案,使用指定活頁簿名稱 (DataGridView)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="GridViewData">匯出的資料檢視表</param>
/// <param name="SheetName">活頁簿名稱</param>
/// <remarks>將資料表(DataTable)匯出到指定的 EXCEL 檔案並使用指定的活頁簿名稱(SheetName)。<br />
/// 如果檔案存在將會被覆寫,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(HeaderText)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// 資料欄設定為不顯示時,也不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataGridView GridViewData, string SheetName)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, GridViewData, SheetName, false);
}
/// <summary>
/// 產生 EXCEL 檔案,使用指定活頁簿名稱 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="ExportDataTable">輸出的資料表</param>
/// <param name="SheetName">活頁簿名稱</param>
/// <param name="InsertMode">附加資料</param>
/// <remarks>將資料表(DataTable)匯出並附加到指定的 EXCEL 檔案,並使用指定的活頁簿名稱(SheetName)。<br />
/// 如果檔案不存在則會自動新增檔案,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataTable ExportDataTable, string SheetName, bool InsertMode)
{
if (My.Computer.FileSystem.FileExists(ExcelFileName))
{
try { if (!InsertMode) My.Computer.FileSystem.DeleteFile(ExcelFileName); }
catch { return false; }
}
return InsertSheetData(ExcelFileName, ExcelFileMode, SheetName, ExportDataTable);
}
/// <summary>
/// 產生 EXCEL 檔案,使用指定活頁簿名稱 (DataGridView)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="GridViewData">匯出的資料檢視表</param>
/// <param name="SheetName">活頁簿名稱</param>
/// <param name="InsertMode">附加資料</param>
/// <remarks>將資料表(DataTable)匯出並附加到指定的 EXCEL 檔案,並使用指定的活頁簿名稱(SheetName)。<br />
/// 如果檔案不存在則會自動新增檔案,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(HeaderText)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// 資料欄設定為不顯示時,也不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, DataGridView GridViewData, string SheetName, bool InsertMode)
{
if (My.Computer.FileSystem.FileExists(ExcelFileName))
{
try { if (!InsertMode) My.Computer.FileSystem.DeleteFile(ExcelFileName); }
catch { return false; }
}
return InsertSheetData(ExcelFileName, ExcelFileMode, SheetName, GridViewData);
}
/// <summary>
/// 產生 EXCEL 檔案 (DataSet)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="UseTableNameForSheetName">使用資料表名稱為活頁簿名稱</param>
/// <param name="ExportDataSet">輸出的資料集</param>
/// <remarks>將資料集(DataSet)匯出到指定的 EXCEL 檔案,並使用資料表名稱做為活頁簿(SheetName)名稱。<br />
/// 如果檔案存在將會被覆寫,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, bool UseTableNameForSheetName, DataSet ExportDataSet)
{
return CreateXlsFile(ExcelFileName, ExcelFileMode, UseTableNameForSheetName, ExportDataSet, false);
}
/// <summary>
/// 產生 EXCEL 檔案 (DataSet)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="UseTableNameForSheetName">使用資料表名稱為活頁簿名稱</param>
/// <param name="ExportDataSet">輸出的資料集</param>
/// <param name="InsertMode">附加資料</param>
/// <remarks>將資料集(DataSet)匯出並附加到指定的 EXCEL 檔案,並使用資料表(DataTable)的名稱為活頁簿名稱(SheetName)。<br />
/// 如果檔案不存在則會自動新增檔案,活頁簿有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功產生檔案</returns>
public static bool CreateXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, bool UseTableNameForSheetName, DataSet ExportDataSet, bool InsertMode)
{
if (My.Computer.FileSystem.FileExists(ExcelFileName))
{
try { if (!InsertMode) My.Computer.FileSystem.DeleteFile(ExcelFileName); }
catch { return false; }
}
string strSheetName;
int intCount = 1;
for (int i = 0; i < ExportDataSet.Tables.Count; i++)
{
if (UseTableNameForSheetName)
{
if ((ExportDataSet.Tables[i].TableName == null) || (ExportDataSet.Tables[i].TableName.Trim() == ""))
{
strSheetName = "Sheet" + intCount.ToString();
intCount++;
}
else
{
strSheetName = ExportDataSet.Tables[i].TableName.Trim();
}
}
else
{
strSheetName = "Sheet" + intCount.ToString();
intCount++;
}
if (!InsertSheetData(ExcelFileName, ExcelFileMode, strSheetName, ExportDataSet.Tables[i])) return false;
}
return true;
}
#endregion
#region 活頁簿(Sheet)處理
/// <summary>
/// 插入活頁簿資料,使用指定 Sheet 名稱 (DataGridView)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="SheetName">活頁簿名稱</param>
/// <param name="GridViewData">匯出的資料檢視表</param>
/// <remarks>將資料檢視表的資料匯出,並使用指定的活頁簿名稱。<br />
/// 如果有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(HeaderText)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// 資料欄設定為不顯示時,也不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功匯出資料</returns>
public static bool InsertSheetData(string ExcelFileName, ExcelMode ExcelFileMode, string SheetName, DataGridView GridViewData)
{
if ((ExcelFileName.Trim() == "") || (SheetName.Trim() == "")) return false;
if ((GridViewData == null) || (GridViewData.Rows.Count == 0) || (GridViewData.Columns.Count == 0)) return false;
SheetName = SheetName.Trim() == "" ? "Sheet1" : SheetName.Trim();
SheetName = NormalizeFieldName(SheetName);
SheetName = CheckSheetName(ExcelFileName, ExcelFileMode, SheetName);
if (SheetName.Length > 31) return false;
OleDbConnection conXLS = new OleDbConnection();
OleDbCommand cmdXLS = new OleDbCommand();
string strXLS = "", strXLSBody = "";
try
{
conXLS.ConnectionString = string.Format(OleDBConnectionString(ExcelFileMode), ExcelFileName);
if (conXLS.ConnectionString == "")
{
conXLS.Dispose();
return false;
}
conXLS.Open();
strXLS = "Create Table [" + SheetName + "] ";
strXLSBody = "";
for (int i = 0; i < GridViewData.Columns.Count; i++)
{
if (GridViewData.Columns[i].HeaderText.Trim() == "") continue;
if (!GridViewData.Columns[i].Visible) continue;
strXLSBody = strXLSBody == "" ? "" : strXLSBody + ", ";
strXLSBody += "[" + NormalizeFieldName(GridViewData.Columns[i].HeaderText.Trim()) + "] ";
if (GridViewData.Columns[i].ValueType == typeof(DateTime))
{
strXLSBody += "Date";
}
else if ((GridViewData.Columns[i].ValueType == typeof(int)) || (GridViewData.Columns[i].ValueType == typeof(Int16))
|| (GridViewData.Columns[i].ValueType == typeof(Int32)) || (GridViewData.Columns[i].ValueType == typeof(Int64))
|| (GridViewData.Columns[i].ValueType == typeof(long)) || (GridViewData.Columns[i].ValueType == typeof(decimal))
|| (GridViewData.Columns[i].ValueType == typeof(Decimal)))
{
strXLSBody += "Integer";
}
else if ((GridViewData.Columns[i].ValueType == typeof(Single)) || (GridViewData.Columns[i].ValueType == typeof(Double)) || (GridViewData.Columns[i].ValueType == typeof(double)))
{
strXLSBody += "Decimal";
}
else
{
strXLSBody += "NVarChar";
}
}
cmdXLS.Connection = conXLS;
cmdXLS.CommandType = CommandType.Text;
cmdXLS.CommandText = strXLS + "(" + strXLSBody + ")";
cmdXLS.ExecuteNonQuery();
if (ExcelFileMode == ExcelMode.Excel97_2003)
{
strXLS = "INSERT INTO [" + SheetName + "$] VALUES (";
}
else
{
strXLS = "INSERT INTO [" + SheetName + "] VALUES (";
}
for (int i = 0; i < GridViewData.Rows.Count; i++)
{
strXLSBody = "";
for (int j = 0; j < GridViewData.Columns.Count; j++)
{
if (GridViewData.Columns[j].HeaderText.Trim() == "") continue;
if (!GridViewData.Columns[j].Visible) continue;
strXLSBody += strXLSBody == "" ? "" : ",";
if ((GridViewData.Rows[i].Cells[j].Value == null) || (GridViewData.Rows[i].Cells[j].Value.ToString().Length == 0))
{
strXLSBody += "Null";
}
else
{
if (GridViewData.Columns[j].ValueType == typeof(DateTime))
{
strXLSBody += "#" + DateTime.Parse(GridViewData.Rows[i].Cells[j].Value.ToString()).ToString("yyyy/MM/dd HH:mm:ss") + "#";
}
else if ((GridViewData.Columns[j].ValueType == typeof(int)) || (GridViewData.Columns[j].ValueType == typeof(Int16))
|| (GridViewData.Columns[j].ValueType == typeof(Int32)) || (GridViewData.Columns[j].ValueType == typeof(Int64))
|| (GridViewData.Columns[j].ValueType == typeof(long)) || (GridViewData.Columns[j].ValueType == typeof(decimal))
|| (GridViewData.Columns[j].ValueType == typeof(Decimal)) || (GridViewData.Columns[j].ValueType == typeof(double))
|| (GridViewData.Columns[j].ValueType == typeof(Single)) || (GridViewData.Columns[j].ValueType == typeof(Double)))
{
strXLSBody += GridViewData.Rows[i].Cells[j].Value.ToString();
}
else
{
if (GridViewData.Rows[i].Cells[j].Value.ToString().Trim() == "")
{
strXLSBody += "' '";
}
else
{
strXLSBody += "'" + GridViewData.Rows[i].Cells[j].Value.ToString() + "'";
}
}
}
}
cmdXLS.CommandText = strXLS + strXLSBody + ")";
cmdXLS.ExecuteNonQuery();
}
cmdXLS.Dispose();
conXLS.Dispose();
return true;
}
catch
{
cmdXLS.Dispose();
conXLS.Dispose();
return false;
}
}
/// <summary>
/// 插入活頁簿資料,使用指定 Sheet 名稱 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="SheetName">活頁簿名稱</param>
/// <param name="ExportDataTable">匯出的資料表</param>
/// <remarks>將資料表(DataTable)的資料匯出,並使用指定的活頁簿名稱。<br />
/// 如果有相同名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns>是否成功匯出資料</returns>
public static bool InsertSheetData(string ExcelFileName, ExcelMode ExcelFileMode, string SheetName, DataTable ExportDataTable)
{
if ((ExcelFileName.Trim() == "") || (SheetName.Trim() == "")) return false;
if ((ExportDataTable == null) || (ExportDataTable.Rows.Count == 0) || (ExportDataTable.Columns.Count == 0)) return false;
SheetName = SheetName.Trim() == "" ? "Sheet1" : SheetName.Trim();
SheetName = NormalizeFieldName(SheetName);
SheetName = CheckSheetName(ExcelFileName, ExcelFileMode, SheetName);
if (SheetName.Length > 31) return false;
OleDbConnection conXLS = new OleDbConnection();
OleDbCommand cmdXLS = new OleDbCommand();
string strXLS = "", strXLSBody = "";
try
{
conXLS.ConnectionString = string.Format(OleDBConnectionString(ExcelFileMode), ExcelFileName);
if (conXLS.ConnectionString == "")
{
conXLS.Dispose();
return false;
}
conXLS.Open();
strXLS = "Create Table [" + SheetName + "] ";
strXLSBody = "";
for (int i = 0; i < ExportDataTable.Columns.Count; i++)
{
if (ExportDataTable.Columns[i].Caption.Trim() == "") continue;
strXLSBody = strXLSBody == "" ? "" : strXLSBody + ", ";
strXLSBody += "[" + NormalizeFieldName(ExportDataTable.Columns[i].Caption) + "] ";
if (ExportDataTable.Columns[i].DataType == typeof(DateTime))
{
strXLSBody += "Date";
}
else if ((ExportDataTable.Columns[i].DataType == typeof(int)) || (ExportDataTable.Columns[i].DataType == typeof(Int16))
|| (ExportDataTable.Columns[i].DataType == typeof(Int32)) || (ExportDataTable.Columns[i].DataType == typeof(Int64))
|| (ExportDataTable.Columns[i].DataType == typeof(long)) || (ExportDataTable.Columns[i].DataType == typeof(decimal))
|| (ExportDataTable.Columns[i].DataType == typeof(Decimal)))
{
strXLSBody += "Integer";
}
else if ((ExportDataTable.Columns[i].DataType == typeof(Single)) || (ExportDataTable.Columns[i].DataType == typeof(Double)) || (ExportDataTable.Columns[i].DataType == typeof(double)))
{
strXLSBody += "Decimal";
}
else
{
strXLSBody += "NVarChar";
}
}
cmdXLS.Connection = conXLS;
cmdXLS.CommandType = CommandType.Text;
cmdXLS.CommandText = strXLS + "(" + strXLSBody + ")";
cmdXLS.ExecuteNonQuery();
if (ExcelFileMode == ExcelMode.Excel97_2003)
{
strXLS = "INSERT INTO [" + SheetName + "$] VALUES (";
}
else
{
strXLS = "INSERT INTO [" + SheetName + "] VALUES (";
}
for (int i = 0; i < ExportDataTable.Rows.Count; i++)
{
strXLSBody = "";
for (int j = 0; j < ExportDataTable.Columns.Count; j++)
{
if (ExportDataTable.Columns[j].Caption.Trim() == "") continue;
strXLSBody += strXLSBody == "" ? "" : ",";
if ((ExportDataTable.Rows[i][j] == null) || (ExportDataTable.Rows[i][j].ToString().Length == 0))
{
strXLSBody += "Null";
}
else
{
if (ExportDataTable.Columns[j].DataType == typeof(DateTime))
{
strXLSBody += "#" + DateTime.Parse(ExportDataTable.Rows[i][j].ToString()).ToString("yyyy/MM/dd HH:mm:ss") + "#";
}
else if ((ExportDataTable.Columns[j].DataType == typeof(int)) || (ExportDataTable.Columns[j].DataType == typeof(Int16))
|| (ExportDataTable.Columns[j].DataType == typeof(Int32)) || (ExportDataTable.Columns[j].DataType == typeof(Int64))
|| (ExportDataTable.Columns[j].DataType == typeof(long)) || (ExportDataTable.Columns[j].DataType == typeof(decimal))
|| (ExportDataTable.Columns[j].DataType == typeof(Decimal)) || (ExportDataTable.Columns[j].DataType == typeof(double))
|| (ExportDataTable.Columns[j].DataType == typeof(Single)) || (ExportDataTable.Columns[j].DataType == typeof(Double)))
{
strXLSBody += ExportDataTable.Rows[i][j].ToString();
}
else
{
if (ExportDataTable.Rows[i][j].ToString().Trim() == "")
{
strXLSBody += "' '";
}
else
{
strXLSBody += "'" + ExportDataTable.Rows[i][j].ToString() + "'";
}
}
}
}
cmdXLS.CommandText = strXLS + strXLSBody + ")";
cmdXLS.ExecuteNonQuery();
}
cmdXLS.Dispose();
conXLS.Dispose();
return true;
}
catch
{
cmdXLS.Dispose();
conXLS.Dispose();
return false;
}
}
/// <summary>
/// 插入活頁簿資料 (DataGridView)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="GridViewData">匯出的資料檢視表</param>
/// <remarks>將資料檢視表的資料匯出。<br />
/// 如果有相同的活頁簿名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(HeaderText)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// 資料欄設定為不顯示時,也不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns></returns>
public static bool InsertSheetData(string ExcelFileName, ExcelMode ExcelFileMode, DataGridView GridViewData)
{
return InsertSheetData(ExcelFileName, ExcelFileMode, "Sheet1", GridViewData);
}
/// <summary>
/// 插入活頁簿資料 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="ExportDataTable">匯出的資料表</param>
/// <remarks>將資料表(DataTable)的資料匯出。<br />
/// 如果有相同的活頁簿名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns></returns>
public static bool InsertSheetData(string ExcelFileName, ExcelMode ExcelFileMode, DataTable ExportDataTable)
{
return InsertSheetData(ExcelFileName, ExcelFileMode, "Sheet1", ExportDataTable);
}
/// <summary>
/// 插入活頁簿資料 (DataSet)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="ExportDataSet">匯出的資料集</param>
/// <param name="UserTableNameForSheetName">使用資料表名稱為活頁簿名稱</param>
/// <remarks>將資料集(DataSet)的資料匯出,並且使用資料名稱做為活頁簿的名稱。<br />
/// 如果有相同的活頁簿名稱時,則會自動在名稱後面附加 "_x"。<br />
/// 欄位名稱使用資料欄(Column)的標題(Caption)名稱,無標題名稱時,將不會匯出該欄位。<br />
/// <br />
/// <br />
/// 註:活頁簿名稱最大長度為 31 個字元。</remarks>
/// <returns></returns>
public static bool InsertSheetData(string ExcelFileName, ExcelMode ExcelFileMode, DataSet ExportDataSet, bool UserTableNameForSheetName)
{
string strSheetName;
int intCount = 1;
for (int i = 0; i < ExportDataSet.Tables.Count; i++)
{
if (UserTableNameForSheetName)
{
if ((ExportDataSet.Tables[i].TableName == null) || (ExportDataSet.Tables[i].TableName.Trim() == ""))
{
strSheetName = "Sheet" + intCount.ToString();
intCount++;
}
else
{
strSheetName = ExportDataSet.Tables[i].TableName;
}
}
else
{
strSheetName = "Sheet" + intCount.ToString();
intCount++;
}
if (!InsertSheetData(ExcelFileName, ExcelFileMode, strSheetName, ExportDataSet.Tables[i])) return false;
}
return true;
}
#endregion
#region 讀取 EXCEL 檔案
/// <summary>
/// 讀取 EXCEL 指定活頁簿的資料 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="SheetName">Sheet 名稱</param>
/// <remarks>將 Excel 檔案中指定的活頁簿資料取出,並儲存到資料表(DataTable)中。</remarks>
/// <returns>讀取的資料表</returns>
public static DataTable ReadXlsFile(string ExcelFileName, ExcelMode ExcelFileMode, string SheetName)
{
if ((ExcelFileName.Trim() == "") || (SheetName.Trim() == "")) return null;
if (!My.Computer.FileSystem.FileExists(ExcelFileName)) return null;
OleDbConnection conXLS = new OleDbConnection();
OleDbCommand cmdXLS = new OleDbCommand();
OleDbDataAdapter odaXLS = new OleDbDataAdapter();
DataTable dtReturn = new DataTable();
conXLS.ConnectionString = string.Format(OleDBConnectionString(ExcelFileMode), ExcelFileName);
if (conXLS.ConnectionString == "")
{
conXLS.Dispose();
return null;
}
try
{
conXLS.Open();
cmdXLS.Connection = conXLS;
cmdXLS.CommandType = CommandType.Text;
cmdXLS.CommandText = "Select * from [" + SheetName + "$]";
odaXLS.SelectCommand = cmdXLS;
odaXLS.Fill(dtReturn);
odaXLS.Dispose();
cmdXLS.Dispose();
conXLS.Dispose();
}
catch
{
odaXLS.Dispose();
cmdXLS.Dispose();
conXLS.Dispose();
return null;
}
return dtReturn;
}
/// <summary>
/// 讀取 EXCEL 所有活頁簿的資料 (DataSet)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <remarks>將 Excel 檔案中所有的活頁簿資料取出,並儲存到資料集(DataSet)中。</remarks>
/// <returns>讀取的資料集</returns>
public static DataSet ReadXlsFile(string ExcelFileName, ExcelMode ExcelFileMode)
{
if (ExcelFileName.Trim() == "") return null;
if (!My.Computer.FileSystem.FileExists(ExcelFileName)) return null;
string[] arySheetName = GetAllSheetName(ExcelFileName, ExcelFileMode);
if ((arySheetName == null) || (arySheetName[0].Trim() == "")) return null;
DataSet dsReturn = new DataSet();
DataTable tmpTable = new DataTable();
for (int i = 0; i < arySheetName.Length; i++)
{
tmpTable = ReadXlsFile(ExcelFileName, ExcelFileMode, arySheetName[i]);
if (tmpTable == null) return null;
dsReturn.Tables.Add(tmpTable);
}
return dsReturn;
}
/// <summary>
/// 讀取 EXCEL 的第一個 Sheet 資料 (DataTable)
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <remarks>將 Excel 檔案中第一個活頁簿的資料取出,並儲存到資料表(DataTable)中。</remarks>
/// <returns>讀取的資料表</returns>
public static DataTable ReadXlsFirstSheet(string ExcelFileName, ExcelMode ExcelFileMode)
{
if (ExcelFileName.Trim() == "") return null;
if (!My.Computer.FileSystem.FileExists(ExcelFileName)) return null;
string[] arySheetName = GetAllSheetName(ExcelFileName, ExcelFileMode);
if ((arySheetName == null) || (arySheetName[0].Trim() == "")) return null;
return ReadXlsFile(ExcelFileName, ExcelFileMode, arySheetName[0]);
}
#endregion
/// <summary>
/// 檢查 Sheet 名稱,產生唯一的 Sheet 名稱
/// </summary>
/// <param name="ExcelFileName">Excel 完整檔案名稱與路徑</param>
/// <param name="ExcelFileMode">Excel 檔案格式</param>
/// <param name="SheetName">要設定的 Sheet 名稱</param>
private static string CheckSheetName(string ExcelFileName, ExcelMode ExcelFileMode, string SheetName)
{
string[] arySheetName = GetAllSheetName(ExcelFileName, ExcelFileMode);
if (arySheetName == null) return SheetName;
if ((arySheetName.Length == 0) || (SheetName.Trim() == "")) return SheetName;
string strReturn = SheetName;
string[] aryTemp;
foreach (string tmpString in arySheetName)
{
if (tmpString.ToUpper().Trim() == SheetName.ToUpper())
{
aryTemp = strReturn.Split('_');
Array.Reverse(aryTemp);
if (aryTemp.Length > 1)
{
if (Tools.IsNumeric(aryTemp[0]))
{
strReturn = strReturn.Replace("_" + aryTemp[0], "_" + (Convert.ToInt32(aryTemp[0], 10) + 1).ToString());
}
else
{
strReturn += "_1";
}
}
else
{
strReturn += "_1";
}
}
}
return strReturn;
}
/// <summary>
/// 正規化欄位名稱,去除特殊字元
/// </summary>
/// <param name="FieldName">欄位名稱</param>
private static string NormalizeFieldName(string FieldName)
{
string strReturn = FieldName.Trim();
strReturn = strReturn.Replace("'", "").Replace(".", "").Replace("[", "").Replace("]", "");
strReturn = strReturn.Replace("*", "").Replace(":", "").Replace("?", "").Replace("/", "").Replace("\\", "");
return strReturn;
}
}
}
程式是運氣與直覺堆砌而成的奇蹟。
若不具備這兩者,不可能以這樣的工時實現這樣的規格。
修改規格是對奇蹟吐槽的褻瀆行為。
而追加修改則是相信奇蹟還會重現的魯莽行動。