• 处理Doc、Doc,Excel文件的学习总结- ExcelDataReader,DocX,Microsoft.Office.Interop.Word


    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         }
    View Code

    在使用Microsoft.Office.Interop.Word进行新增列Row的时候就抛Com组件错误,所以就使用了Docx。成功解决了问题

    提供一个具体的例子-Utilitys.zip

    欢迎留言:相互讨论,相互学习。

  • 相关阅读:
    Python:Fatal error in launcher: Unable to create process using 问题排查
    接口测试及接口Jmeter工具介绍
    bug的分类和等级
    如何编写测试用例
    网络流入门--最大流算法Dicnic 算法
    Codevs 1004 四子连棋
    洛谷 P1072 Hankson 的趣味题
    Codevs 搜索刷题 集合篇
    洛谷 P1195 口袋的天空
    洛谷 P1362 兔子数
  • 原文地址:https://www.cnblogs.com/tianwen9579/p/12133186.html
Copyright © 2020-2023  润新知