ExcelDataReader
是一个非常轻量级和快速的库,用c#编写,用于读取Microsoft Excel文件(2.0-2007)。
支持的文件格式和版本
文件类型 Container Format File Format Excel Version(s)
.xlsx ZIP, CFB+ZIP OpenXml 2007 and newer
.xls CFB BIFF8 97, 2000, XP, 2003
98, 2001, v.X, 2004 (Mac)
.xls CFB BIFF5 5.0, 95
.xls - BIFF4 4.0
.xls - BIFF3 3.0
.xls - BIFF2 2.0, 2.2
.csv - CSV (All)
安装ExcelDataReader基本包以使用“低级” reader接口。兼容net20、net45、netstandard1.3和netstandard2.0。
安装ExcelDataReader.DataSet扩展包使用AsDataSet()方法来填充System.Data.DataSet的数据集。这也将拉入基本包。兼容net20、net45和netstandard2.0。
基本使用
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read)) { // 自动检测格式,支持: // - Binary Excel files (2.0-2003 format; *.xls) // - OpenXml Excel files (2007 format; *.xlsx) using (var reader = ExcelReaderFactory.CreateReader(stream)) { // 从1或2中选择一个: // 1. Use the reader methods do { while (reader.Read()) { // reader.GetDouble(0); } } while (reader.NextResult()); // 2. 使用AsDataSet扩展方法 var result = reader.AsDataSet(); //每个电子表格的结果在result. tables中 } }
读csv文件
使用ExcelReaderFactory.CreateCsvReader 而不是CreateReader 解析用逗号分隔值的纯文本流。
也可以看下配置选项:FallbackEncoding and AutodetectSeparators.
输入CSV总是完全解析一次,以设置FieldCount、RowCount、编码、分隔符(如果CSV缺少BOM且不是UTF8,则解析两次),然后在迭代行记录时再次解析。如果输入不能使用指定的编码进行解析,则会抛出System.Text.DecoderFallbackException异常
reader将所有CSV字段值作为字符串返回,并且不尝试将数据转换为数字或日期。这个调用者负责解释CSV数据。
使用读取器方法
AsDataSet()扩展方法是快速获取数据的方便助手,但并不总是可用或需要使用。IExcelDataReader扩展了System.Data.IDataReader and IDataRecord接口,用于在较低级别导航和检索数据。
最重要的读取器方法和属性。
Read() 从当前工作表中读取一行
NextResult() 将光标移到下一个工作表
ResultsCount 返回当前工作簿中的工作表数
Name 返回当前工作表的名称
CodeName 返回当前工作表的VBA代码名称标识符
FieldCount 返回当前工作表中的列数。
RowCount 返回当前工作表中的行数。这包括终端空行,否则将被AsDataSet()排除。当与AnalyzeInitialCsvRows一起使用时,在CSV文件中抛出InvalidOperationException。
HeaderFooter 返回带有有关页眉和页脚信息的对象,如果没有,则返回null。
MergeCells 返回当前工作表中合并的单元格范围数组。
RowHeight 返回当前行的可视高度(以点为单位)。如果该行被隐藏,则可能为0。
GetColumnWidth() 以字符单位返回列的宽度。如果该列被隐藏,则可能为0。
GetFieldType() 返回当前行的值的类型。总是Excel支持的类型之一:double、int、bool、DateTime、TimeSpan、string,如果没有值,则为null。
IsDBNull() 检查当前行的值是否为空。
GetValue() 从当前行返回一个值作为对象,如果没有值则返回null
GetDouble(), GetInt32(), GetBoolean(), GetDateTime(), GetString() 将当前行的一个值转换为它们各自的类型。
GetNumberFormatString() 返回包含当前行的值的格式化代码的字符串,如果没有值则返回null。请参阅下面的格式化部分。
GetNumberFormatIndex() 返回当前行的值的数字格式索引。164以下的索引值表示内置的数字格式,否则表示自定义数字格式
除非类型完全匹配,否则类型化Get*()方法将抛出InvalidCastException。
CreateReader()配置选项
ExcelReaderFactory.CreateReader()、CreateBinaryReader()、CreateOpenXmlReader()、CreateCsvReader()方法接受一个可选的配置对象来修改reader的行为:
var reader = ExcelReaderFactory.CreateReader(stream, new ExcelReaderConfiguration() { // 获取或者设置encoding 当输入的XLS缺失CodePage 记录或者当CSV缺失Bom并且不解析为UTF8。 //默认是: cp1252 (XLS BIFF2-5 and CSV only) FallbackEncoding = Encoding.GetEncoding(1252), // 获取或设置用于打开受密码保护的工作簿的密码。 Password = "password", // 获取或设置CSV分隔符候选数组。reader自动检测哪个最适合输入数据。 TAB | # // (CSV only) AutodetectSeparators = new char[] { ',', ';', ' ', '|', '#' }, //获取或设置一个值,该值指示在IExcelDataReader对象被释放后是否保持流打开。默认值:假 LeaveOpen = false, //获取或设置一个值,该值指示在CSV中要分析编码、分隔符和字段计数的行数。设置时,此选项使 IExcelDataReader.RowCount属性来抛出异常。默认值:0 -分析整个文件只有CSV,对其他没有影响格式) AnalyzeInitialCsvRows = 0, });
AsDataSet()配置选项
AsDataSet()方法接受一个可选的配置对象来修改DataSet转换的行为:
var result = reader.AsDataSet(new ExcelDataSetConfiguration() { // 获取或设置一个值,该值指示是否设置DataColumn.DataType属性. UseColumnDataType = true, // 获取或设置回调,以确定是否在DataSet中包含当前工作表。在ConfigureDataTable之前,每个Sheet调用一次。 FilterSheet = (tableReader, sheetIndex) => true, // 获取或设置回调以获取数据表的配置选项。 ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration() { // 获取或设置一个值,该值指示生成的列名的前缀。 EmptyColumnNamePrefix = "Column", //获取或设置一个值,该值指示是否将数据中的行用作列名。 UseHeaderRow = false, //获取或设置回调以确定哪一行是标题行。只在UseHeaderRow = true时调用。 ReadHeaderRow = (rowReader) => { //跳过第一行使用第二行作为列的header rowReader.Read(); }, //获取或设置回调,以确定是否包括数据表中的当前行 FilterRow = (rowReader) => { return true; }, // 获取或设置回调,以确定是否在数据表中包含特定列。读取标题后,每列调用一次。 FilterColumn = (rowReader, columnIndex) => { return true; } } });
Formatting
ExcelDataReader 不直接支持格式化. 用户可以通过IExcelDataReader.GetNumberFormatString(i)获取单元格的数字格式字符串,并使用第三方的ExcelNumberFormat库进行格式化。
string GetFormattedValue(IExcelDataReader reader, int columnIndex, CultureInfo culture) { var value = reader.GetValue(columnIndex); var formatString = reader.GetNumberFormatString(columnIndex); if (formatString != null) { var format = new NumberFormat(formatString); return format.Format(value, culture); } return Convert.ToString(value, culture); }
处理Doc或者Docx
可以是用Microsoft.Office.Interop.Word组件库,需要依赖Office,并且使用还存在莫名的bug,不建议使用
推荐使用DocX-它不需要安装Microsoft Word或Office。就能直接使用。
What is DocX?
DocX是一个.NET 库,允许开发人员操作Word 2007/2010/2013文件,操作简单直观。DocX是快速、轻量级的,最好的是它不需要安装Microsoft Word或Office。
注:自2017年10月3日起新增一个主分支。如果您在更改之前使用这个项目,请阅读关于Classic分支的内容。
DocX是 .NET的Xceed word的免费开源版本。最初由Cathal Coffey撰写,由Przemyslaw Klys维护,现在由Xceed维护。从v1.5.0开始,这个免费的开源产品是在Xceed社区许可协议下提供的(用于非商业用途)。
当前,DocX和Xceed Words for Net的区别在于- Xceed Words for .NET
可以将Word文档转换为PDF吗
添加属性来将文本包装在图片/表格/形状周围
添加图片裁剪添加形状(现在是矩形)
添加文本框或包含文本的形状
从段落中获取形状
从段落中获取图表,并可以修改其类别/值
是否至少有两个版本先于DocX版本
订阅中包含专业技术支持吗
我还需要什么?
使用DocX所需要安装的是。net framework 4.0和Visual Studio 2010或更高版本,它们都是免费的。
DocX的主要特性是什么?
创建新的Word文档
修改Word文档
支持从Word2007及以上的.DOCX
并行修改多个文档以获得更好的性能
将模板应用于Word文档
连接文档,从一个文档到另一个文档重新创建部分
支持文档保护与密码或不带密码
设置文档的页边距和页面大小
设置行间距,缩进,文本方向,文本对齐
管理字体和字体大小
设置文本颜色,粗体,下划线,斜体,删除线,高亮显示
设置页码
创建sections
添加页眉或页脚,这些页眉或页脚可以在所有页面上都是相同的,或者在第一个页面上是唯一的,或者在奇数/偶数页面上是唯一的。可以包含图像,超链接和更多。
插入/修改段落。
插入/修改编号或项目符号列表。
插入/修改图片。翻转,旋转,复制,修改,调整大小。
插入/修改表。插入/删除行、列、更改方向、列宽、行高、边框、合并/删除单元格。
插入/修改格式化的方程或公式。
插入/修改书签。
插入/修改超链接。
插入/修改水平线。
插入/修改图表(条、线、饼图、3D图表)。设置颜色、标题、图例等。
查找、删除或替换文本。支持大小写敏感和正则表达式。
插入/修改核心属性或自定义属性,如作者、地址、主题、标题等。
插入目录。设置标题,更改格式。
插入/修改形状(目前为矩形)
更新文档字段
为什么要使用DocX?
DocX使创建和操作文档成为一项简单的任务。它不使用COM库,也不需要安装Microsoft Office。
下面这篇来自Cathal Coffey的博客比较了用来创建HelloWorld文档的代码:
Office Interop libraries,
OOXML SDK,
DocX
Advanced Examples
一步一步的指导创建一个公司的发票http://cathalscorner.blogspot.com/2009/08/docx-v1007-released.html
在多个文档之间并行替换文本 http://cathalscorner.blogspot.com/2010/12/replace-text-across-many-documents-in.html
以编程方式操作嵌入在文档中的图像http://cathalscorner.blogspot.com/2010/12/programmatically-manipulate-image.html
转换 DocX 为(.doc, .pdf, .html) http://cathalscorner.blogspot.com/2009/10/converting-docx-into-doc-pdf-html.html
更多信息可以在许可页面中找到。
商业许可证可以在Xceed购买。
这里重点讲操作Word中的Table-比如新增一行,新增多行等,在指定的行插入新行等
1 public static void InsertRow(string fileName,int tableNum,int rowNum) 2 { 3 using (var document = DocX.Load(fileName)) 4 { 5 var table = document.Tables[tableNum]; 6 //var row = table.Rows[rowNum]; 7 table.InsertRow(rowNum); 8 document.Save(); 9 } 10 } 11 public static void InsertRowMults(string fileName, int tableNum, int rowNum,int rowCount) 12 { 13 using (var document = DocX.Load(fileName)) 14 { 15 var table = document.Tables[tableNum]; 16 for (int i = 0; i < rowCount; i++) 17 { 18 table.InsertRow(rowNum); 19 rowNum++; 20 } 21 document.Save(); 22 } 23 } 24 public static void InsertRowMultsWithFormat(string fileName, int tableNum, int rowNum, int rowCount) 25 { 26 using (var document = DocX.Load(fileName)) 27 { 28 var table = document.Tables[tableNum]; 29 for (int i = 0; i < rowCount; i++) 30 { 31 var row = table.Rows[rowNum]; 32 table.InsertRow(row, rowNum, true); 33 rowNum++; 34 } 35 document.Save(); 36 } 37 } 38 public static void InsertRowMultsWithFormatEnd(string fileName, int tableNum, int rowNum, int rowCount) 39 { 40 using (var document = DocX.Load(fileName)) 41 { 42 var table = document.Tables[tableNum]; 43 for (int i = 0; i < rowCount; i++) 44 { 45 var row = table.Rows.AsEnumerable().Last(); 46 table.InsertRow(row, rowNum, true); 47 rowNum++; 48 } 49 document.Save(); 50 } 51 }
在使用Microsoft.Office.Interop.Word进行新增列Row的时候就抛Com组件错误,所以就使用了Docx。成功解决了问题
提供一个具体的例子-Utilitys.zip
欢迎留言:相互讨论,相互学习。