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. 监控SQLServer 数据库表每天的空间变化情况

    阅读完桦仔的<分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)>后,我想使用文中提供的代码做一个统计表每天的新增行数及新增存储空间的功能 实现步骤如下: 1 ...

  2. AIX常用命令学习(一)

    1.prtconf命令 查看AIX主机的结构特征状态 语法: prtconf [ -c ] [ -k ] [ -L ] [ -m ] [ -s ] [ -v ] Flags: -c  Displays ...

  3. SpringMVC源码分析和一些常用最佳实践

    前言 本文分两部分,第一部分剖析SpringMVC的源代码,看看一个请求响应是如何处理,第二部分主要介绍一些使用中的最佳实践,这些best practices有些比较common,有些比较tricky ...

  4. SpringBoot+MyBatis连接数据库

    SpringBoot通过MyBatis连接数据库有2种方法: 1.注解 2.XML文件 1.注解 1.构建项目 2.添加依赖: <dependencies> <dependency& ...

  5. win10WLAN没有有效的ip配置

    方案一:将路由器和猫重启一下,一般都可以解决了!方案二:1.在开始菜单上单击鼠标右键,选择“命令提示符(管理员)”,如果没有找到这个选项,通过cortana搜索cmd,右键以管理员身份运行,还可以进入 ...

  6. Git学习文档——文件状态git status

    1.已经跟踪的文件有三种状态 已跟踪的文件,即被纳入版本控制的文件,又分为未修改(unmodified).已修改(modified).已暂存(staged)三种状态. 如图: 当在工作目录中新加入一个 ...

  7. Echarts 曲线数少于图例数解决方法

    在上一篇文章 Echarts 多曲线“断点”问题解决方法 中说到了Angular 项目中要使用 Echarts 的方法. 说明了自己解决当“每一条曲线的横坐标不相同”时,在各条曲线上,它们的值采用数组 ...

  8. libextobjc 实现的 defer

    算法沉思录:分而治之(复用): 分而治之是指把大而复杂的问题分解成若干个简单的小问题,然后逐个解决.这种朴素的思想来源于人们生活与工作的经验,也完全适合于技术领域. 要崩溃的节奏: 要崩溃的节奏: V ...

  9. hdu2102

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u014303647/article/details/27705195 题目链接: pid=2102& ...

  10. beautifulsoup4-4.3.2的安装

    下载地址:https://www.crummy.com/software/BeautifulSoup/bs4/download/4.5/ 安装成功,亲测可用! 参考文章http://blog.csdn ...