2020年8月10日星期一

基于 DocumentFormat.OpenXml 操作 Excel (1)

  最近抽空研究了一下 基于DocumentFormat.Open

  各种系统中,导出Excel是一种很常见的功能,在C#/.Net 环境下, 市面上存在很多相关的类库,开源免费的有基于JAVAPOI移植过来的 NPOIEPPlusOpen 等等;也有收费的 如 Aspose.CellsSpire.XLS 等。

  收费的商业组件在性能,功能上会一般来说都会比较好,例如Aspose.Cells,在性能上是比较卓越的,价格最便宜也要1000美金左右。 但是大部分公司,特别是初创公司,考虑到成本问题,用得比较多的,可能还是会使用开源免费的 NPOIEPPlus,而Open(DocumentFormat.Open

  这个组件为啥叫 Open,因为从07版本之后,office系列的文档,包括Excel, Word, PPT这些文档,都是使用方式存储的。 而 Office 的 Open Open只能适用与07版本后的office, 像2003版本的Excel 文件(.xls)是不支持的。

  在一个文档的内部,都是由多份

  如下图所示:

   

 

  

  从以上的图中解压出来后的文件,可以看出,一个 Excel (.xlsx)文件里面包含很多个

  从名字上,我们大概初步可以猜测出几点: 

  (1)workbook.

  (2)styles.

  (3)worksheets文件夹,包含多份

  (4)theme 文件夹,Excel主题相关

  (5)printerSettings文件夹, 打印设置相关

 

那么再来看看,初步通过代码应该怎么实现。

微软官方提供的文档说明,可以查阅:https://docs.microsoft.com/zh-cn/office/open-

Open 对应的Nuget包叫DocumentFormat.Open,目前最新版本是 2.11.3,地址是: https://www.nuget.org/packages/DocumentFormat.Open

Open 的相关类型说明,可以查阅微软官方提供的API文档:https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.open

在C#.Net 项目中,通过VS开发工具的Nuget管理工具安装,也可以直接在终端通过nuget包管理命令安装:  Install-Package DocumentFormat.Open2.11.3 

 

 

根据微软官方的文档,先来通过C#代码,简单生成一个excel文件,并且保存到磁盘。 通过Nuget安装好SDK。

根据微软官方的介绍,一份最小(空白)工作簿必须包含以下内容,要:

    1、有一个工作表(WorkSheet)

    2、工作表的Id

    3、指向工作表定义位置的关系 Id 

 

可能听起来有点难理解,通过这个来看下面的代码示例(可以运行的)  

 1 using System; 2 using System.IO; 3 using DocumentFormat.Open 4 using DocumentFormat.Open 5 using DocumentFormat.Open 6  7 namespace PracticePart1 8 { 9  public class Program10  {11   public static void Main(string[] args)12   {13    //当前运行时路径14    var directoryInfo = new DirectoryInfo(Directory.GetCurrentDirectory());15    var fileName = $@"PracticePart1-{DateTime.Now:yyyyMMddHHmmss}.xlsx";16 17    //文件路径,保存在运行时路径下18    var filepath = Path.Combine(directoryInfo.ToString(), fileName);19    Console.WriteLine($"FilePath: {filepath}");20 21    //创建SpreadsheetDocument对象,xlsx类型,通过路径22    var spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);23 24    //通过Stream对象25    //MemoryStream ms = new MemoryStream();26    //SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook);27 28    //调用AddWorkbookPart, 创建WorkbookPart对象, 创建Workbook对象(相当于29    var workbookPart = spreadsheetDocument.AddWorkbookPart();30    workbookPart.Workbook = new Workbook();31 32    //通过上面的WorkbookPart,创建WorksheetPart对象,创建Worksheet对象(相当于33    var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();34    worksheetPart.Worksheet = new Worksheet(new SheetData());35 36    // 创建Sheets 到 Workbook37    var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());38 39    // 创建添加Sheet对象, Id关联 Worksheet, 从而命名工作表的名称40    var sheet = new Sheet()41    {42     Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),43     SheetId = 1,44     Name = "myFirstSheet"45    };46 47    //追加到 Sheets48    sheets.Append(sheet);49 50    //保存到磁盘51    workbookPart.Workbook.Save();52 53    // Close the document.54    spreadsheetDocument.Close();55   }56  }57 }

 

  以上是可以直接运行,然后生成Excel文件。上述涉及到的几个类型,依据我个人的理解,下面简单说明下。

  SpreadsheetDocument 表格文档类, 从字面意思,它就表示一个Excel相关的文档包。 通过它的Create方法, 通过枚举来指定文档类型(*.xlsx, 可以指定其它如*.xltx, *.xlsm等),同时指定文件路径(重载方法中,是可以支持传入一个Stream),创建一个document对象。然后创建表示 工作簿 的WorkbookPart, 创建表示 工作表的 WorksheetPart, 这个时候符合上诉的 第一个要求【有一个工作表(WorkSheet)】。

  接着通过工作簿对象Workbook创建一个Sheets,表示工作簿中的所有表。 这里要先明白Sheet Worksheet 的这2个的不同:

  (1)Worksheet : 表示的是工作簿的一份工作表的内容定义,就是我们打开Excel文件,下方显示sheet1, sheet2,sheet3....的每一份工作表。

  (2)Sheet : 代表的是工作簿的一个表,它可以是工作表(Worksheet), 也可以图表(ChartSheet),也可以是其它类型的表。它本身不涉及具体表怎么定义,但是会通过Id关联具体表的定义; 所以 Sheets 是表示工作簿中关联的所有表的集合(图表,工作表,宏表等)。 比如一个Sheets,它其中包含2个工作表,1个图表,而具体的定义放在其它的地方,一般一个表的定义有一个

  Sheet 对象, 有一个 IdSheetId, 这2个字段。 按照上诉的 第二个要求 【工作表的Id】,就是指 SheetId, 自己赋值。 第三个要求【指向工作表定义位置的关系 Id 】, 就是指这个Id字段, 这个Id 指向工作表定义位置(就是指Sheet 关联到具体哪个 WorksheetPart ), 通过 WorkbookPart.GetIdOfPart 的方法来获取这个Id

 

  以上就是DocumentFormat.Open最小化空白文档的方式。

 

 

基于 DocumentFormat.OpenXml 操作 Excel (1)2020年跨境电商亚马逊数据化爆款选品法亚马逊全球开店从0到1新手入门实操课抢注商标移动端将占领未来电商市场的"大半蛋糕",电商卖家如何抢占先机?疫情蔓延,日韩口罩等防疫物资价格涨幅约5-10倍!4月1日起,美国开始向亚马逊卖家征税 / 亚马逊物流轻小商品计划政策更新端午节去阳西沙扒湾好不好?沙扒湾环境怎么样?漂流是不是越贵越好玩,越便宜越不好玩?2017年端午节可以去泡温泉吗?

没有评论:

发表评论