前言

最近在写 OneBlock 平台 的最新版本,新版本里将支持案例的批量执行和数据导入导出,为了导出后能方便用户编辑我决定用 Excel 作为载体。
如果是以.NET Framework 来写的话有很多现成的库可以用,比如 NPOI、TMS Flexcel 等等。
但是 OneBlock 平台 是以跨平台为目标的 .NET Core 编写的,而 .NET Core 正式发布到现在也不过半年, 还没有完善的 Excel 操作库 (可能是我没找到),所以我只能先造一个简单的轮子先凑合着。在造轮子的过程中慢慢对 Excel 文件结构有了一些了解,所以就有了这一篇文章。

正文

2007 版 Excel 使用 xlsx 作为新的 Excel 的文件格式,xlsx 是用新的基于 XML 的压缩文件格式取代了其之前专有的默认文件格式,使其占用空间更小。
上面这段是官方给出的定义,其实简单来说就是 xlsx 格式文件就是一个 ZIP 的压缩包,而压缩包里包含了用以记录表格数据和样式的 xml 文件。

将一个新建的 xlsx 文件使用解压工具打开,后可以看到里面的内容:

下面我就来简单介绍下里面的几个文件:

我们来着重看一下 xl 这个文件夹内的文件

在 xl 下也有一写 _rels 目录 (xl/_rels),这个目录里还是存放了 sheet 的一些信息.

printerSettings 是关于打印的,其实删掉这个目录 Excel 也不会报错,而且里面的东西我也看不懂.

theme 文件夹 是存放主题的一些配置信息,一般都不会动.

worksheets 这个就厉害了,这里面保存了所有 sheet 的数据/数据索引 和单元格格式信息 (其实数据文件还有一个 sharedStrings.xml 等会儿会说到).

如果你在 excel 里添加一些文本数据 (中英文非数字) 的话,那么解压出来后还会有 一个叫 sharedStrings.xml 的文件,这个文件主要是保存文本数据用的,具体我就不细说了,你自己修改一下后解压看看就能明白了.

styles.xml 就是一个格式文件,主要对字体格式进行定义,改颜色就靠他了.

其实整个文件结构并不负责,但文件里的内容确很复杂,我这里就不细说了,想了解的话你可以插入些数据,l 然后解压出来自己看一下
解压后想重新打包成 excel 的话请注意一定要使用 ZIP 格式.

我的类库

因为是个人使用,所以只实现了 sheet 创建、数据写入、列宽设置、单元格超链接这些功能。

最后如果你也使用 c# 或.NET Core 的话你可以通过 Nuget 引用我的类库,也可以直接在 GitHub 上查看相关的源代码。

NETCore.Extensions.Excel 源码

code demo

using NETCore.Extensions.Excel;
using NETCore.Extensions.Excel.Infrastructure;

public static void Main(string[] args) {
            MemoryStream ms = new MemoryStream(1024 * 1024);

            using (ExcelStream _ExcelStream = new ExcelStream()) {
                _ExcelStream.Create(ms);

                var sheet = _ExcelStream.LoadSheet(1);

                var row = sheet.CreateRow(1);

                var cell = row.CreateCell(row.LastCellNum + 1);
                cell.value = "测试案例1";
                //超链接
                HSSFHyperlink hy = new HSSFHyperlink();
                hy.Address = "'s1'!A1";
                hy.Label = "测试案例1";
                cell.Hyperlink = hy;
                //列宽设置
                sheet.SetColumnWidth(4, 60);
                sheet.SetColumnWidth(2, 30);
                sheet.SaveChanges();

                var sheet2 = _ExcelStream.CreateSheet("s1");
                var r2 = sheet2.CreateRow(1);
                var c2 = r2.CreateCell(1);
                c2.value = "hhhhhhhhhhhhhhhhhhh";

                sheet2.SetColumnWidth(4, 60);
                sheet2.SetColumnWidth(2, 30);
                sheet2.SaveChanges();
            }

            ms.Position = 0;
            using (FileStream fs = new FileStream(@"D:\excel\result.xlsx", FileMode.Create)) {
                ms.CopyTo(fs);
            }
}


↙↙↙阅读原文可查看相关链接,并与作者交流