C#利用Openxml讀取Excel數(shù)據(jù)實(shí)例
本文實(shí)例講述了C#利用Openxml讀取Excel數(shù)據(jù)的方法,分享給大家供大家參考。具體分析如下:
這里有些問題,如果當(dāng)Cell 里面是 日期和浮點(diǎn)型的話,對應(yīng)的Cell.DataType==Null,對應(yīng)的時(shí)間會(huì)轉(zhuǎn)換為一個(gè)浮點(diǎn)型,對于這塊可以通過DateTime.FromOADate(double d)轉(zhuǎn)換為時(shí)間。 可是缺點(diǎn)的地方就是,如果Cell.DataType ==NULL, 根本無法確認(rèn)這個(gè)數(shù)據(jù)到底是 浮點(diǎn)型還是[被轉(zhuǎn)換為了日期的浮點(diǎn)數(shù)]。查閱了很多國外資料,的確國外博客有一部分都反映了。有關(guān)Openxml讀取Excel時(shí)Cell.DataType==NULL的問題。本例子沒考慮那個(gè)問題,現(xiàn)在還沒解決。等后面查詢到更詳細(xì)的資料再解決。
其次解決這個(gè)問題的方法只有,在數(shù)據(jù)處理的時(shí)候,數(shù)據(jù)分析我們是可以知道這一列的數(shù)據(jù)到底是什么類型,然后根據(jù)自己的需求,自己對獲取的數(shù)據(jù)做相應(yīng)轉(zhuǎn)換處理。不過如果使用OleDb的Select語句來讀取Excel的時(shí)候,就不會(huì)出現(xiàn)這個(gè)問題,讀取到Datable時(shí)候是日期就不會(huì)轉(zhuǎn)換為浮點(diǎn)型數(shù)據(jù)。而且對象的Datable對于的那個(gè)單元格數(shù)據(jù)還可以直接強(qiáng)制轉(zhuǎn)換為DateTime。不過用OleDB讀取數(shù)據(jù)感覺上應(yīng)該沒有Openxml目前還沒測試大數(shù)據(jù),太晚了。該sleep了。如果有大神了解Openxml讀取表格,請指點(diǎn)[需要解決問題是:EXCEL的表格中CELL 的 DateTime類型和浮點(diǎn)類型數(shù)據(jù),在獲取后如何區(qū)分。因?yàn)槭褂肙penxml獲取后日期會(huì)被自動(dòng)轉(zhuǎn)換為浮點(diǎn)型]
參考代碼如下:
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; namespace ReadExcel { public class Program { static void Main(string[] args) { DataTable dt = new DataTable(); using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(@"Test.xlsx", false)) { WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart; IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>(); string relationshipId = sheets.First().Id.Value = sheets.First(x => x.Name == "TestSheet").Id.Value; WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId); Worksheet workSheet = worksheetPart.Worksheet; SheetData sheetData = workSheet.GetFirstChild<SheetData>(); Row[] rows = sheetData.Descendants<Row>().ToArray(); // 設(shè)置表頭DataTable foreach (Cell cell in rows.ElementAt(0)) { dt.Columns.Add((string)GetCellValue(spreadSheetDocument, cell)); } // 添加內(nèi)容 for (int rowIndex = 1; rowIndex < rows.Count(); rowIndex++) { DataRow tempRow = dt.NewRow(); for (int i = 0; i < rows[rowIndex].Descendants<Cell>().Count(); i++) { tempRow[i] = GetCellValue(spreadSheetDocument, rows[rowIndex].Descendants<Cell>().ElementAt(i)); } dt.Rows.Add(tempRow); } } Console.ReadKey(); } public static string GetCellValue(SpreadsheetDocument document, Cell cell) { SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart; string value = cell.CellValue.InnerXml; if (cell.DataType != null && (cell.DataType.Value == CellValues.SharedString || cell.DataType.Value == CellValues.String || cell.DataType.Value == CellValues.Number)) { return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText; } else //浮點(diǎn)數(shù)和日期對應(yīng)的cell.DataType都為NULL { // DateTime.FromOADate((double.Parse(value)); 如果確定是日期就可以直接用過該方法轉(zhuǎn)換為日期對象,可是無法確定DataType==NULL的時(shí)候這個(gè)CELL 數(shù)據(jù)到底是浮點(diǎn)型還是日期.(日期被自動(dòng)轉(zhuǎn)換為浮點(diǎn) return value; } } } }
希望本文所述對大家的C#程序設(shè)計(jì)有所幫助.
相關(guān)文章
Unity實(shí)現(xiàn)仿3D輪轉(zhuǎn)圖效果
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)仿3D輪轉(zhuǎn)圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01C#監(jiān)控文件夾并自動(dòng)給圖片文件打水印的方法
這篇文章主要介紹了C#監(jiān)控文件夾并自動(dòng)給圖片文件打水印的方法,涉及C#針對文件夾及圖片操作的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05C#中ManualResetEvent實(shí)現(xiàn)線程的暫停與恢復(fù)
本文主要介紹了C#中ManualResetEvent實(shí)現(xiàn)線程的暫停與恢復(fù),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01C#實(shí)現(xiàn)啟用與禁用本地網(wǎng)絡(luò)的方式小結(jié)【3種方式】
這篇文章主要介紹了C#實(shí)現(xiàn)啟用與禁用本地網(wǎng)絡(luò)的方式,結(jié)合實(shí)例形式總結(jié)分析了使用Hnetcfg.dll、Shell32.dll及setupapi.dll三種啟用與禁用本地網(wǎng)絡(luò)的操作方法,需要的朋友可以參考下2016-07-07C#實(shí)現(xiàn)DataGridView控件行列互換的方法
這篇文章主要介紹了C#實(shí)現(xiàn)DataGridView控件行列互換的方法,涉及C#中DataGridView控件元素遍歷與添加操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08