C# 关于Excel 读写操作

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

最近老系统开发,vs2008开发环境的,用到一个EXCEL的读取和存入操作。本来一开始是用网络上下载的类来实现,而且网站上一大堆,但是发现很多都不是很好,而且解释不清楚,所以自己小结了一下,写了一个.net4.0的类:

开发环境:VS2010  .net4.0

操作系统:win 7

条件:加载Microsoft.Office.Interop.Excel动态库


先上代码:

/// 
    /// 标题:Excel文件助手类
    /// 描述:1.读取指定条件的Excel信息到内存中
    ///       2.将内存中的信息导出到Excel文件中
    ///       3.消除Excel文件中的空白记录
    /// 作者:孙继鹏
    /// 日期:2013-7-26
    /// 
    public static class ExcelHelper
    {
        #region Field

        /// 
        /// 读取Excel的连接字符串
        /// 
        /// 
        /// Provider代表连接驱动4.0版本
        /// Data Source代表Excel的路径
        /// Extended Properties代表连接Excel的版本,对于Excel 97以上版本都用Excel 8.0
        /// HDR代表默认Excel第一行是否列名,Yse代表是可以直接读取,No反之
        /// IMEX代表
        /// 
        private const string strFormat = "Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = {0};Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";

        #endregion

        #region Method
        /// 
        /// 把指定的DataTable里的空白行去除,返回一个没有空白行的DataTable
        /// 
        /// 原始的DataTable
        /// 没有空白行的DataTable
        public static DataTable DataTableEmptyRowsFilter(DataTable dataTable)
        {
            DataTable newDataTable = null;
            if (dataTable.Rows.Count != 0)
            {
                newDataTable = dataTable.Clone();
                foreach (DataRow dr in dataTable.Rows)
                {
                    if (dr[0].ToString() != string.Empty)
                    {
                        newDataTable.ImportRow(dr);
                    }
                }
            }
            return newDataTable;
        }

        /// 
        /// 读取Excel文件内指定sheet页的数据到DataSet
        /// 
        /// Excel文件完整路径
        /// 读取的表格数据
        /// sheet名称
        /// dataTable名称
        /// 操作错误信息,若为空则执行成功
        public static string TryRead(string strFilePath, out DataTable dataTable, string strSheetName = "Sheet1", string strNewSheetName = "ExcelInfo")
        {
            string errormsg = string.Empty;

            if (!string.IsNullOrEmpty(strFilePath) && File.Exists(strFilePath))
            {
                string strConn = string.Format(strFormat, strFilePath);
                string strSQL = string.Format("SELECT * FROM [{0}$]", strSheetName);
                try
                {
                    using (OleDbDataAdapter ExcelDA = new OleDbDataAdapter(strSQL, strConn))
                    {
                        DataSet ExcelDS = new DataSet();
                        ExcelDA.Fill(ExcelDS, strNewSheetName);
                        dataTable = DataTableEmptyRowsFilter(ExcelDS.Tables[0]);
                    }
                }
                catch (Exception err)
                {
                    errormsg=err.Message;
                    dataTable = null;
                }
            }
            else
            {
               errormsg="The file path of the file does not exist";
               dataTable = null;
            }

            return errormsg;
        }

        /// 
        /// 将DataTable写入指定路径Excel文件
        /// 
        /// 
        /// 采用将导出的数据保存到数组,然后一次过导出,以提高速度
        /// excelSheet.Merge(Missing.Value); 合并 
        /// excelSheet.Font.Bold=true; 设置粗体
        /// excelSheet.Font.Size=12;设置字体大小
        /// excelSheet.HorizontalAlignment=Excel.XlHAlign.xlHAlignCenter;水平对齐设置
        /// excelSheet.VerticalAlignment=Excel.XlVAlign.xlVAlignCenter;垂直对齐设置 
        /// excelSheet.FormulaR1C1=公式; 公式设置
        /// excelSheet.ColumnWidth=20;  设置列宽
        /// excelSheet.RowHeight=20; 设置行高
        /// 
        /// 数据表
        ///  导出路径文件夹路径
        /// Excel内容开始列,默认为1,第一列为标题
        /// Excel内容开始行,默认为1,第一行为标题
        public static string DataTableToExcel(DataTable dTable, string strFiledirectPath,int startRow=1, int startCol=1)
        {
            string errorMsg = string.Empty;

            if (dTable == null ||startRow <= 0 || startCol <=0)
            {
                errorMsg = "DataTable is null";
            }

            var excel = new Excel.Application();
            var excelBook = excel.Workbooks.Add(Type.Missing);
            var excelSheet = (Excel.Worksheet)excelBook.ActiveSheet;
            var rowCount = dTable.Rows.Count;
            var colCount = dTable.Columns.Count;

            //二维数组定义是多一个标题行
            var dataArray = new object[rowCount + 1, colCount];

            for (var j = 0; j < colCount; j++)
            {
                //导出字段标题
                dataArray[0, j] = dTable.Columns[j].Caption;

                //根据各列的数据类型设置Excel的格式。
                switch (dTable.Columns[j].DataType.ToString())
                {
                    case "System.String":
                        excelSheet.get_Range(excelSheet.Cells[startRow, startCol + j] as Excel.Range,excelSheet.Cells[rowCount + startRow, startCol + j] as Excel.Range).
                        NumberFormatLocal = "@";
                        break;
                    case "System.DateTime":
                        excelSheet.get_Range(excelSheet.Cells[startRow, startCol + j] as Excel.Range,excelSheet.Cells[rowCount + startRow, startCol + j] as Excel.Range).
                            NumberFormatLocal = "yyyy-MM-dd HH:mm:ss";
                        break;
                    //可以根据自己的需要扩展。
                    default:
                        excelSheet.get_Range(excelSheet.Cells[startRow, startCol + j] as Excel.Range,excelSheet.Cells[rowCount + startRow, startCol + j] as Excel.Range).
                            NumberFormatLocal= "G/通用格式";
                        break;
                }
                for (int i = 0; i < rowCount; i++)
                {
                    dataArray[i + 1, j] = dTable.Rows[i][j];
                }
            }
            //写入Excel Sheet
            excelSheet.get_Range(excel.Cells[startRow, startCol] as Excel.Range,excel.Cells[rowCount + startRow, colCount + startCol - 1] as Excel.Range).Value2= dataArray;        
            //设置列头为粗体字
            excelSheet.get_Range(excel.Cells[1, 1] as Excel.Range,excel.Cells[1, colCount] as Excel.Range).Font.Bold = true;
            //设置列头底色为灰色
            excelSheet.get_Range(excel.Cells[1, 1] as Excel.Range,excel.Cells[1, colCount] as Excel.Range).Interior.ColorIndex = 15;
            //设置内容的字体大小为9
            excelSheet.get_Range(excel.Cells[2, 1] as Excel.Range,excel.Cells[rowCount + startRow, colCount + startCol - 1] as Excel.Range).Font.Size = 9;
            //设置Sheet的名称
            excelSheet.Name = dTable.TableName;

            //保存文档
            try
            {

                strFiledirectPath = Path.Combine(strFiledirectPath, dTable.TableName + ".xls");
                excelBook.Saved = true;
                excelBook.SaveCopyAs(strFiledirectPath);
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
            }
            finally
            {
                excel.Quit();
                GC.Collect();
            }

            return errorMsg;
        }        
        #endregion
    }
这里面要注意的几个特别的问题:
1.就是Excel的连接字符串,里面的参数必须注意,在注释中都有解释
2.就是在网上很多代码都是老的VS2008,.net2.0 ,当到VS2010中可能就会出现一些问题,比如:

VS2010的.NET4.0下调用Excel对象出现错误:“object”未包含“get_Range”;

eg:

 错误代码:excelSheet.get_Range(excelSheet.Cells[startRow, startCol + j] ,excelSheet.Cells[rowCount + startRow, startCol + j]).
                        NumberFormatLocal = "@";
修正代码:
 excelSheet.get_Range(excelSheet.Cells[startRow, startCol + j] as Excel.Range,excelSheet.Cells[rowCount + startRow, startCol + j] as Excel.Range).
                        NumberFormatLocal = "@";
原因:就是
get_Range()内的参数类型必须统一,貌似原来的就可以,但是VS2010至少就必须类型转换为
Excel.Range,否则编译不会出错,运行时会出错

转载于:https://my.oschina.net/violetmoon/blog/164199

你可能感兴趣的:(C# 关于Excel 读写操作)