1. 程式人生 > >asp.net mvc 資料匯出excel表及自excel表匯入資料到相應表

asp.net mvc 資料匯出excel表及自excel表匯入資料到相應表

一、自資料表匯出excel

/// <summary>
        /// 匯出excel
        /// </summary>
        /// <param name="sortgid"></param>
        /// <returns></returns>
        public FileResult WithQuestionToExcel(string sortgid)
        {

            QuestionsLibraryAndSortService service = new QuestionsLibraryAndSortService();
            List<OrderBy> orderbys = new List<OrderBy>
            {
                new OrderBy{Field="Sorting",IsASC=true},
                new OrderBy{Field="CreateTime",IsASC=true}
            };
            var info = service.Get(m => m.SortGID == sortgid).OrderBy(orderbys);
            string fileName = "sort" + DateTime.Now.ToString("yyyy-MM-dd");
            StringBuilder strRows = new StringBuilder();
            strRows.Append("<table><tr>");
            strRows.Append("<td style=\"mso-number-format:\\@;\">Id</td>");
            strRows.Append("<td style=\"mso-number-format:\\@;\">title</td>");
            strRows.Append("</tr>");


            foreach (var row in info)
            {
                QuestionsLibraryService qService = new QuestionsLibraryService();
                QuestionsLibrary model = qService.Get(row.QuestionsLibraryGID);
                strRows.Append("<tr>");
                strRows.Append("<td style=\"mso-number-format:\\@;\">" + model.IID + "</td>");
                strRows.Append("<td style=\"mso-number-format:\\@;\">" + (model.Title ?? "") + "</td>");
                strRows.Append("</tr>");


            }
            strRows.Append("</table>");
            string result = strRows.ToString();
            //第一種:使用FileContentResult
            byte[] fileContents = Encoding.Default.GetBytes(result);
            //return File(fileContents, "application/ms-excel", fileName + ".xls");
            return File(fileContents, "application/vnd.ms-excel", fileName + ".xls");
        }
方法中自資料庫中讀取資料的方法這裡不做解釋。如果有人用,可以自行換上自己的方法。主要注意以下幾點:
其一、匯出excel使用的是網頁的table

其二、為了防止數字過長導致的科學計數法現象,使用了tyle=\"mso-number-format:\\@;\"

其三、此匯出的excel並不是標準的excel格式。當然,在excel中檢視正常,但是如果使用匯出的excel表當做匯入的excel,不可以直接使用,需要另存一下,改為標準的excel格式。如果想知道什麼是標準的excel格式,可以這樣。把excel檔案在記事本中開啟,使用此方法匯出的excel檔案,不是亂碼,而是html的table表單形式。而你另存後的excel則在記事本中是亂碼。沒錯,標準的excel格式在記事本中就是亂碼

二、自excel檔案匯入資料到資料庫表

/// <summary>
        /// 匯入excel
        /// </summary>
        /// <param name="sortgid"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult WithQuestionToImportExcel(string sortgid,string file)
        {
            try
            {
                //EventLog.WriteLog(sortgid);
                string url = Server.MapPath("/gallery/" + file);
                //string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + url + "; " + "Extended Properties=Excel 8.0;";  //此連線只能操作Excel2007之前(.xls)檔案
                string strConn = "Provider=Microsoft.Ace.OleDb.12.0;" + "data source=" + url + ";Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'"; //此連線可以操作.xls與.xlsx檔案 (支援Excel2003 和 Excel2007 的連線字串)
                using (OleDbConnection conn = new OleDbConnection(strConn))
                {
                    conn.Open();

                    //返回Excel的架構,包括各個sheet表的名稱,型別,建立時間和修改時間等
                    DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
                    //包含excel中表名的字串陣列
                    string[] strTableNames = new string[dtSheetName.Rows.Count];
                    for (int k = 0; k < dtSheetName.Rows.Count; k++)
                    {
                        strTableNames[k] = dtSheetName.Rows[k]["TABLE_NAME"].ToString();
                    }

                    using (OleDbDataAdapter myCommand = new OleDbDataAdapter("select * from [" + strTableNames[0] + "]", strConn))
                    {
                        DataSet myDataSet = new DataSet();
                        myCommand.Fill(myDataSet, "ExcelInfo");
                        DataTable dt = myDataSet.Tables["ExcelInfo"].DefaultView.ToTable();
                        QuestionsLibraryService qservice = new QuestionsLibraryService();
                        QuestionsLibraryAndSortService service = new QuestionsLibraryAndSortService();
                        //EventLog.WriteLog("" + dt.Rows.Count);
                        for (int i = 0; i < dt.Rows.Count; i++)
                        {
                            DataRow dr = dt.Rows[i];
                            int iid = dr[0].ToInteger();
                            //EventLog.WriteLog(""+ iid);
                            var model = new QuestionsLibraryAndSort();
                            model.GID = Guid.NewGuid().ToString();
                            model.SortGID = sortgid;
                            var qModel = qservice.Get(m => m.IID == iid).FirstOrDefault();
                            if (qModel == null)
                            {
                                //EventLog.WriteLog("aa");
                                continue;
                            }
                            //EventLog.WriteLog("continue1");
                            if (service.Exist(m => m.SortGID == sortgid && m.QuestionsLibraryGID == qModel.GID))
                            {
                                continue;
                            }
                            //EventLog.WriteLog(qModel.GID);
                            model.QuestionsLibraryGID = qModel.GID;
                            model.Sorting= i;
                            service.Add(model);
                        }
                    }

                }


                return Json("匯入成功");
            }
            catch(Exception ex)
            {
                return Json(ExceptionHelper.GetErrorMessageByJavascript(ex));
            }



        }

這裡對方法的兩個引數稍加解釋,第一個sortgid是匯入資料所屬的gid。第二個是已經上傳的excel檔案的相對路徑。沒錯,這裡excel表需要上傳後才能使用,至於如果上傳,這裡不加解釋,無論是自寫,還是用外掛,可自行解決。

這裡有幾個坑需要注意。

錯誤資訊:未在本地計算機上註冊“microsoft.ACE.oledb.12.0”提供程式

這個表示在伺服器上未安裝相應的支援excel處理的資料處理引擎。處理辦法:
http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463960fdcdb/AccessDatabaseEngine.exe下載。然後安裝

安裝後可能仍然有問題,這個時候要對網站使用的程式池開通32位支援

該應用程式的 應用程式池 ------>選擇高階設定 --------->啟用32位應用程式 ------->true 

弄好後如果讀取excel資料語句這樣寫:

select * from [sheet1$],有可能會提示對應表名不正確。這是因為你的excel檔案的sheet名字已經修改造成。這裡我已經做了處理,使用

 string[] strTableNames = new string[dtSheetName.Rows.Count];
for (int k = 0; k < dtSheetName.Rows.Count; k++)
{
strTableNames[k] = dtSheetName.Rows[k]["TABLE_NAME"].ToString();
}

迴圈讀取,然後取第一個。

還有一個坑就是有可能會提示excel表資料不是標準形式,這裡的處理方法我已經在匯出excel做了說明,這裡不再贅述