Office Open XML

简称为 ooxml ,是Microsoft 在 Office 2007 之后推行的标准格式,用在 Excel, Word, PPT 等文件。已确定为国际标准。

Open-Xml SDK是Microsoft提供操作ooxml格式的接口类库,是c#实现的,2014年开源的,

open-xml sdk开源项目地址:https://github.com/OfficeDev/Open-XML-SDK

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 读写的示例

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 = ; 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 + ),
Name = tname
};
sheets.Append(sheet); #region 创建sheet 行
Row row;
uint rowIndex = ;
//添加表头
row = new Row()
{
RowIndex = UInt32Value.FromUInt32(rowIndex++)
};
sheetData.Append(row);
for (int i = ; 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 = ; i < dt.Rows.Count; i++)
{
row = new Row()
{
RowIndex = UInt32Value.FromUInt32(rowIndex++)
};
sheetData.Append(row); for (int j = ; 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 = ;
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 == )
{
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;
}
}
}

数据接口

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 = , int rows = , string tabName = "mytable")
{
DataTable dt = new DataTable(tabName);
for (int i = ; i < cols; i++)
{
dt.Columns.Add("col" + i.ToString("D3"));
} DataRow dr = null;
for (int i = ; i < rows; i++)
{
dr = dt.NewRow();
for (int j = ; j < dt.Columns.Count; j++)
{
dr[j] = "val-" + i + "-" + j;
}
dt.Rows.Add(dr);
} return dt;
}
}
}

单元测试接口代码

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秒多,读取只需433ms

详细可以查看git仓库代码:https://github.com/marblemm/UtilsHelper

Open-Xml SDK使用介绍的更多相关文章

  1. Open Xml SDK Word模板开发最佳实践(Best Practice)

    1.概述 由于前面的引文已经对Open Xml SDK做了一个简要的介绍. 这次来点实际的——Word模板操作. 从本质上来讲,本文的操作都是基于模板替换思想的,即,我们通过替换Word模板中指定元素 ...

  2. Open Xml SDK 引文

    什么是Open Xml SDK? 什么是Open Xml? 首先,我们得知道,Open Xml为何物? 我们还是给她起个名字——就叫 “开放Xml”,以方便我们中文的阅读习惯.之所以起开放这个名字,因 ...

  3. Android sdk目录介绍

    android sdk目录介绍 build-tools 各版本SDK编译工具 docs 离线开发者文档Android SDK API参考文档 extras 扩展开发包,如兼容架包. platforms ...

  4. User Word Automation Services and Open XML SDK to generate word files in SharePoint2010

    SharePoint 2010 has established a new service called "Word Automation Services" to operate ...

  5. Csharp: create word file using Open XML SDK 2.5

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. Csharp: read excel file using Open XML SDK 2.5

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  7. 下载和编译 Open XML SDK

    我们需要一些工具来开始 Open XML 的开发. 开发工具 推荐的开发工具是 Visual Studio 社区版. 开发工具:Visual Studio Community 2013 下载地址:ht ...

  8. Open XML SDK 在线编程黑客松

    2015年2月10日-3月20日,开源社 成员 微软开放技术,GitCafe,极客学院联合举办" Open XML SDK 在线编程黑客松 ",为专注于开发提高生产力的应用及服务的 ...

  9. Embedding Documents in Word 2007 by Using the Open XML SDK 2.0 for Microsoft Office

    Download the sample code This visual how-to article presents a solution that creates a Word 2007 doc ...

随机推荐

  1. BackgroundWorker原理剖析

    BackgroundWorker类位于System.ComponentModel命名空间下,主要用来异步执行一个长时间的操作,然后,在完成事件中安全更新UI的控件属性.UI中的控件是不允许非创建该控件 ...

  2. 百度开源的分布式 id 生成器

    UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器.UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于d ...

  3. 转载:eclipse 搭建SSH项目(第一篇)

    第一篇:原文地址:http://blog.csdn.net/aaaaaaaa0705/article/details/6288431(虽然没有具体的例子,不过逻辑性强点,比较容易看懂) SSH框架是最 ...

  4. 通过ffplay实现摄像头preview

    通过ffplay实现摄像头preview 硬件平台:Jetson TK1 开发板(NVIDIA Tegra K1 Mobile Processor 32bit),宁波舜宇光电SP103A(OV1682 ...

  5. [翻译] DDExpandableButton

    DDExpandableButton https://github.com/ddebin/DDExpandableButton Purpose - 目的 DDExpandableButton is a ...

  6. print(dir(...)) 打印对象或者类中的方法和函数

  7. 取消centOS7虚拟机锁屏

    https://blog.csdn.net/ViJayThresh/article/details/81076622

  8. mysql中FIND_IN_SET函数的使用

    有种需求,A和B是父子关系,B和C是父子关系,C与D亦是父子关系,以此类推,无限级 现在需要查询到某一级(包括本级)下面所有的,就需要用到FIND_IN_SET函数 select * from tab ...

  9. BZOJ1135:[POI2009]Lyz(线段树,Hall定理)

    Description 初始时滑冰俱乐部有1到n号的溜冰鞋各k双.已知x号脚的人可以穿x到x+d的溜冰鞋. 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人.xi为负,则代表走了这么多人 ...

  10. sql排序方法

    SQL Server中使用order by charindex按指定顺序排序 在使用SQL Server数据库编程中,有时需要对取出来的数据按照指定的顺序排序,例如,取出来的数据某个字段值有张三.李四 ...