簡稱爲 ooxml ,是Microsoft 在 Office 2007 以後推行的標準格式,用在 Excel, Word, PPT 等文件。已肯定爲國際標準。git
Open-Xml SDK是Microsoft提供操做ooxml格式的接口類庫,是c#實現的,2014年開源的,github
open-xml sdk開源項目地址:https://github.com/OfficeDev/Open-XML-SDKc#
open-xml sdk官方介紹文檔:https://docs.microsoft.com/en-us/office/open-xml/open-xml-sdk單元測試
和其餘操做ooxml類庫相比,如NPOI,EPPlus等比較,網上說NPOI速度更快些,可是我測試後open-xml sdk更快,只能說其餘類庫接口封裝比較容易使用測試
如下是用open-xml sdk 讀寫的示例ui
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using System; using System.Data; using System.Linq; namespace ExcelExport { public class ExcelOpenXml { /* * excel 對象結構 * SpreadsheetDocument * 》WorkbookPart * 》WorksheetPart * 》Worksheet * 》SheetData * 》WorksheetPart * 》Worksheet * 》SheetData1 * 》Workbook * 》Sheets * 》Sheet */ public static void Create(string filename, DataSet ds) { SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook); WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart(); Workbook workbook = new Workbook(); Sheets sheets = new Sheets(); #region 建立多個 sheet 頁 //建立多個sheet for (int s = 0; s < ds.Tables.Count; s++) { DataTable dt = ds.Tables[s]; var tname = dt.TableName; WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>(); Worksheet worksheet = new Worksheet(); SheetData sheetData = new SheetData(); //建立 sheet 頁 Sheet sheet = new Sheet() { //頁面關聯的 WorksheetPart Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = UInt32Value.FromUInt32((uint)s + 1), Name = tname }; sheets.Append(sheet); #region 建立sheet 行 Row row; uint rowIndex = 1; //添加表頭 row = new Row() { RowIndex = UInt32Value.FromUInt32(rowIndex++) }; sheetData.Append(row); for (int i = 0; i < dt.Columns.Count; i++) { Cell newCell = new Cell(); newCell.CellValue = new CellValue(dt.Columns[i].ColumnName); newCell.DataType = new EnumValue<CellValues>(CellValues.String); row.Append(newCell); } //添加內容 object val = null; for (int i = 0; i < dt.Rows.Count; i++) { row = new Row() { RowIndex = UInt32Value.FromUInt32(rowIndex++) }; sheetData.Append(row); for (int j = 0; j < dt.Columns.Count; j++) { Cell newCell = new Cell(); val = dt.Rows[i][j]; newCell.CellValue = new CellValue(val.ToString()); newCell.DataType = new EnumValue<CellValues>(CellValues.String); row.Append(newCell); } } #endregion worksheet.Append(sheetData); worksheetPart.Worksheet = worksheet; worksheetPart.Worksheet.Save(); } #endregion workbook.Append(sheets); workbookpart.Workbook = workbook; workbookpart.Workbook.Save(); spreadsheetDocument.Close(); } public static DataTable GetSheet(string filename, string sheetName) { DataTable dt = new DataTable(); using (SpreadsheetDocument document = SpreadsheetDocument.Open(filename, false)) { WorkbookPart wbPart = document.WorkbookPart; //經過sheet名查找 sheet頁 Sheet sheet = wbPart .Workbook .Descendants<Sheet>() .Where(s => s.Name == sheetName) .FirstOrDefault(); if (sheet == null) { throw new ArgumentException("未能找到" + sheetName + " sheet 頁"); } //獲取Excel中共享表 SharedStringTablePart sharedStringTablePart = wbPart .GetPartsOfType<SharedStringTablePart>() .FirstOrDefault(); SharedStringTable sharedStringTable = null; if (sharedStringTablePart != null) sharedStringTable = sharedStringTablePart.SharedStringTable; #region 構建datatable //添加talbe列,返回列數 Func<Row, int> addTabColumn = (r) => { //遍歷單元格 foreach (Cell c in r.Elements<Cell>()) { dt.Columns.Add(GetCellVal(c, sharedStringTable)); } return dt.Columns.Count; }; //添加行 Action<Row> addTabRow = (r) => { DataRow dr = dt.NewRow(); int colIndex = 0; int colCount = dt.Columns.Count; //遍歷單元格 foreach (Cell c in r.Elements<Cell>()) { if (colIndex >= colCount) break; dr[colIndex++] = GetCellVal(c, sharedStringTable); } dt.Rows.Add(dr); }; #endregion //經過 sheet.id 查找 WorksheetPart WorksheetPart worksheetPart = wbPart.GetPartById(sheet.Id) as WorksheetPart; //查找 sheetdata SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First(); //遍歷行 foreach (Row r in sheetData.Elements<Row>()) { //構建table列 if (r.RowIndex == 1) { addTabColumn(r); continue; } //構建table行 addTabRow(r); } } return dt; } /// <summary> /// 獲取單元格值 /// </summary> /// <param name="cell"></param> /// <param name="sharedStringTable"></param> /// <returns></returns> static string GetCellVal(Cell cell, SharedStringTable sharedStringTable) { var val = cell.InnerText; if (cell.DataType != null) { switch (cell.DataType.Value) { //從共享表中獲取值 case CellValues.SharedString: if (sharedStringTable != null) val = sharedStringTable .ElementAt(int.Parse(val)) .InnerText; break; default: val = string.Empty; break; } } return val; } } }
數據接口spa
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; namespace TextExcelExport { public class TestData { private static string _exportDir = @"D:\temp"; public static string GetNewExcelFileName(string name) { //return Path.Combine(_exportDir, DateTime.Now.ToString("yyMMdd-HHmmss") + suffix); return Path.Combine(_exportDir, name); } public static string GetFileName(string fileName) { return Path.Combine(_exportDir , fileName); } public static DataTable GetDataTable(int cols = 100, int rows = 1000, string tabName = "mytable") { DataTable dt = new DataTable(tabName); for (int i = 0; i < cols; i++) { dt.Columns.Add("col" + i.ToString("D3")); } DataRow dr = null; for (int i = 0; i < rows; i++) { dr = dt.NewRow(); for (int j = 0; j < dt.Columns.Count; j++) { dr[j] = "val-" + i + "-" + j; } dt.Rows.Add(dr); } return dt; } } }
單元測試接口代碼excel
using System; using System.Data; using System.IO; using ExcelExport; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace TextExcelExport { [TestClass] public class TestCreateExcel { #region openxml [TestMethod] public void TestOpenXmlCrate() { var fname = TestData.GetNewExcelFileName("TestOpenXmlCrate.xlsx"); var dt1 = TestData.GetDataTable(tabName: "tab1"); var dt2 = TestData.GetDataTable(tabName: "tab2"); DataSet ds = new DataSet(); ds.Tables.Add(dt1); ds.Tables.Add(dt2); ExcelOpenXml.Create(fname, ds); Assert.IsTrue(File.Exists(fname)); } [TestMethod] public void TestOpenXmlRead() { var fname = TestData.GetFileName("TestOpenXmlCrate.xlsx"); var dt = ExcelOpenXml.GetSheet(fname, "tab1"); Assert.IsTrue(File.Exists(fname)); } #endregion } }
測試發現,寫兩張sheet表,1000行,100列的數據建立須要2秒多,讀取只需433mscode
詳細能夠查看git倉庫代碼:https://github.com/marblemm/UtilsHelperorm