由OutOfMemoryException异常到Excel的Xlsx文件读写
来源:互联网 发布:丁丁知乎 编辑:程序博客网 时间:2024/06/06 03:16
最近在一个项目中要用到对Excel的XLSX文件进行读写,本来直接使用第三方库NPOI来实现,在对小文件进行读写时也没遇到什么问题。但在每次读完一个小文件再读一个大文件时,就会在NPOI的XSSFWorkbook类型对象初始化中抛出System.OutOfMemoryException异常。在网上也查了相关资料,有说加内存的解决的,有说是托管代码的问题。也尝试使用EPPlus,也会出现同样的问题。采用Open-XML-SDK来解决,也有类似问题。最后,还是决定不使用第三方库,自己动手写一个XLSX文件读写库。
关于XLSX文件,通过搜索相关资料可以知道这是一种压缩格式。可以直接将XLSX文件解压缩,解压后的目录结构如下图1
继续打开xl文件夹,目录如下图2
这里就是我们主要关注的地方了。
workbook.xml文件主要关注里面的<sheets />节点,里面的子节点对应excel的每个sheet表格。通过<sheet />节点的name属性记录表格的名称。
sharedStrings.xml文件含有XLSX文件中单元格里用到的字符串。每个单元格字符串对应一个<si />节点,每个<si />节点里有至少一个<t />节点,每个<t />节点的内容就是单元格字符串的一部分。一般情况一个<si />节点下只有一个<t />节点,那么这个<t />节点的内容就是一个完整的单元格字符串;也可能出现多个<t />节点,那么就要把每个<t />节点的内容拼接起来,才形成一个单元格的字符串。
styles.xml文件记录了单元格的样式,一般不会对它进行处理。
worksheets文件夹内是Excel文件每张sheet表格对应的文件,文件名为sheet1.xml、sheet2.xml、sheet3.xml...如此类推。sheet1.xml代表第一张sheet表格的内容。重点关注<dimension />节点,她记录了网格的范围大小,如“A1”代表这张表只有一个单元格;如“A1:AA10”代表26×10大小的表格。<row />节点代表一行单元格,属性r代表从1开始的行编号。<c />节点代表某个单元格,属性r代表单元格位置,如r="A1"代表位于第1行A列,属性t表示单元格值的类型,如t="s"代表<v />节点的内容是共享字符串的索引。如果属性t没有,就表示<v />节点的内容就是单元格的值。
在读写过程中最容易出错的地方就是共享字符串的读取,如果读取不完整,就会导致解析不出正确的数据。下面是读取sharedStrings.xml文件流来获取共享字符串列表的方法
/// <summary> /// 读取共享字符串表单 /// </summary> /// <param name="input">sharedStrings.xml文件流</param> /// <returns></returns> private static IList<string> ReadStringTable(Stream input) { var stringTable = new List<string>(); using (var reader = XmlReader.Create(input)) { string meta = ""; bool added = true; for (reader.MoveToContent(); reader.Read(); ) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "si") { if (!added) { stringTable.Add(meta); added = true; } meta = ""; added = false; } if (reader.Name == "t") { meta += reader.ReadElementString(); } } else if (reader.NodeType == XmlNodeType.EndElement) { if (reader.Name == "si") { if (!added) { stringTable.Add(meta); added = true; } } else if (reader.Name == "sst") { if (!added) { stringTable.Add(meta); added = true; } } } } } return stringTable; }
完整的项目文件可以从这里获取https://github.com/Nick-PAN/PdkXlsxFileIO
- 由OutOfMemoryException异常到Excel的Xlsx文件读写
- Python读写Excel 2007文件(xlsx)
- Python读写Excel 2007文件(xlsx)
- Qt Xlsx ( QtXlsxWriter ) qt读写excel文件库的windows安装使用
- Qt Xlsx ( QtXlsxWriter ) qt读写excel文件库的windows安装使用
- System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常
- qt vs 读写xlsx文件
- OutOfMemoryException异常
- .xls和.xlsx的区别?.xlsx Excel文件怎么转换成.xls文件
- 使用ExcelDataReader读写excel(.xls,.xlsx)
- poi读写Excel,兼容2007xlsx
- nodejs--node-xlsx模块读写excel
- 安装xlsx包来读取Excel的xlsx文件(包括rJava的安装)
- c#读取excel的xls和xlsx文件的方法
- C++ 读写Excel表格文件 Libxl破解版 支持2007版本 xlsx 中文
- 使用XSSFWork创建的xlsx后缀Excel文件无法打开
- POI读取并解析xlsx格式的excel文件
- PHPExcel 读取Excel以xlsx格式的文件
- linux后台运行和关闭、查看后台任务
- jsp-config
- 一个可做模版的i2c设备驱动
- 【JAVA】java解析HTML代码
- html在线浏览pdf并且控制打印下载等按钮
- 由OutOfMemoryException异常到Excel的Xlsx文件读写
- Java EE概述
- 单链表的头插法与尾插法
- 423B. Black Square
- 洛谷P1001 A+B Problem
- 解决window.location.href不跳转,无反应,不执行的问题
- error LNK2001: 无法解析的外部符号 __imp__Py_Initialize
- CTR、推荐系统学习路线
- 利用proguard5.3.3进行代码混淆