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. SQL SERVER 使用ESCAPE转义

    使用SQL语句查询是开发中常做的事,在实际的情况中,可能会遇到,查询包含某个关键词的所有行,而这个关键词正好也是SQL SERVER的关键词. 下面有一张表Member,有如下的数据: 假如需要查询名 ...

  2. 从 s = "我爱北京天安门" 中悟道了-----------迭代器操作print(c.__next__())的最!大!好!处!-----------------------------------------------------可以一个一个输出

    s = "我爱北京天安⻔"c = s.__iter__() # 获取迭代器# print(c) # 打印迭代器的地址# print(c.__next__()) # 打印迭代器中的下 ...

  3. 关于layui(layer)子页面获取不到父页面jQuery对象的问题。

    如果在使用layui-layer模块过程中,在子页面执行代码: window.parent.$("#id").val() 报错:window.parent.$ is not a f ...

  4. 死磕salt系列-salt文章目录汇总

    死磕salt系列-salt入门 死磕salt系列-salt配置文件 死磕salt系列-salt grains pillar 配置 死磕salt系列-salt 常用modules 死磕salt系列-sa ...

  5. HBase学习之路 (二)HBase集群安装

    前提 1.HBase 依赖于 HDFS 做底层的数据存储 2.HBase 依赖于 MapReduce 做数据计算 3.HBase 依赖于 ZooKeeper 做服务协调 4.HBase源码是java编 ...

  6. Java基础加强之并发(三)Thread中start()和run()的区别

    Thread中start()和run()的区别 start() : 它的作用是启动一个新线程,新线程会执行相应的run()方法.start()不能被重复调用.run()   : run()就和普通的成 ...

  7. istio 配置解读

    Istio在服务网络中统一提供了许多关键功能: 流量管理:控制服务之间的流量和API调用的流向,使得调用更可靠,并使网络在恶劣情况下更加健壮. 可观察性:了解服务之间的依赖关系,以及它们之间流量的本质 ...

  8. 20155314 2016-2017-2 《Java程序设计》第9周学习总结

    20155314 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 了解JDBC架构 掌握JDBC架构 掌握反射与ClassLoader 了解自定义泛型和自定义 ...

  9. ES6新特性5:类(Class)和继承(Extends)

    本文摘自ECMAScript6入门,转载请注明出处. 一.类(Class) 1.基本语法 JavaScript语言的传统方法是通过构造函数,定义并生成新对象.下面是一个例子 function Poin ...

  10. mongodb的学习-4-使用 MongoDB shell 来连接 Mongodb 服务

    执行启动操作后,mongodb 在输出一些必要信息后不会输出任何信息,之后就等待连接的建立,当连接被建立后,就会开始打印日志信息. 使用 MongoDB shell 来连接 Mongodb 服务 标准 ...