C#使用NPOI读写excel - Geronimo - 博客园

本帖内容来自网络+自己稍作整理,已找不到原贴,侵删

个人比较习惯用NPOI操作excel,方便易理解。在宇宙第一IDE(笑)——VS2017中插入NPOI就很方便:

首先安装NPOI:

然后在.cs文件中加入如下引用:

using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using NPOI.HSSF.UserModel;

XSSF是用于.xlsx(2007以后版本)

HSSF是用于.xls(2007以前版本)

同时我的代码中要用到Datatable,用于存储表格数据

读写文件需要IO

using System.Data; using System.IO

接下来是读写excel的代码:

首先从excel中读入数据存入datatable并返回:

复制代码; "复制代码")

    /// <summary>
    /// Excel导入成DataTble /// </summary>
    /// <param name="file">导入路径(包含文件名与扩展名)</param>
    /// <returns></returns>
    public static DataTable ExcelToTable(string file)
    {
        DataTable dt = new DataTable();
        IWorkbook workbook; string fileExt = Path.GetExtension(file).ToLower(); using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
        { if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(fs); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(fs); } else { workbook = null; } if (workbook == null) { return null; }
            ISheet sheet = workbook.GetSheetAt(0); //表头 
            IRow header = sheet.GetRow(sheet.FirstRowNum);
            List<int\> columns = new List<int>(); for (int i = 0; i < header.LastCellNum; i++)
            { object obj = GetValueType(header.GetCell(i)); if (obj == null || obj.ToString() == string.Empty)
                {
                    dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
                } else dt.Columns.Add(new DataColumn(obj.ToString()));
                columns.Add(i);
            } //数据 
            for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
            {
                DataRow dr = dt.NewRow(); bool hasValue = false; foreach (int j in columns)
                {
                    dr\[j\] = GetValueType(sheet.GetRow(i).GetCell(j)); if (dr\[j\] != null && dr\[j\].ToString() != string.Empty)
                    {
                        hasValue = true;
                    }
                } if (hasValue)
                {
                    dt.Rows.Add(dr);
                }
            }
        } return dt;
    }

复制代码; "复制代码")

同时支持.xlsx和.xls

上面代码用到了GetValueType函数:

复制代码; "复制代码")

    /// <summary>
    /// 获取单元格类型 /// </summary>
    /// <param name="cell">目标单元格</param>
    /// <returns></returns>
    private static object GetValueType(ICell cell)
    { if (cell == null) return null; switch (cell.CellType)
        { case CellType.Blank: return null; case CellType.Boolean: return cell.BooleanCellValue; case CellType.Numeric: return cell.NumericCellValue; case CellType.String: return cell.StringCellValue; case CellType.Error: return cell.ErrorCellValue; case CellType.Formula: default: return "=" + cell.CellFormula;
        }
    }

复制代码; "复制代码")

最后是datatable写入excel(仅适用于.xlsx)文件:

复制代码; "复制代码")

    /// <summary>
    /// Datable导出成Excel(xlsx) /// </summary>
    /// <param name="dt"></param>
    /// <param name="file">导出路径(包括文件名与扩展名)</param>
    public static void TableToExcel(DataTable dt, string file)
    {
        IWorkbook workbook; string fileExt = Path.GetExtension(file).ToLower();if (workbook == null) { return; } 
        ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("sheet0") : workbook.CreateSheet(dt.TableName); //表头 
        IRow row = sheet.CreateRow(0); for (int i = 0; i < dt.Columns.Count; i++)
        {
            ICell cell = row.CreateCell(i);
            cell.SetCellValue(dt.Columns\[i\].ColumnName);
        } //数据 
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            IRow row1 = sheet.CreateRow(i + 1); for (int j = 0; j < dt.Columns.Count; j++)
            {
                ICell cell = row1.CreateCell(j);

cell.SetCellValue(dt.Rows[i][j].ToString());

}

        } //转为字节数组 
        MemoryStream stream = new MemoryStream();
        workbook.Write(stream); var buf = stream.ToArray(); //保存为Excel文件 

        using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Write))
        {
            fs.Write(buf, 0, buf.Length);
            fs.Flush();
        } 
    }

复制代码; "复制代码")

其中:

using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Write))

这一行,FileMode.open会在已有的文件中加入你所create的sheet,适用FileMode.create会创新新文件,几遍已有文件,也会删掉该文件。

这是写入.xls文件的代码

复制代码; "复制代码")

    /// <summary>
    /// 将datatable写入到excel(xls) /// </summary>
    /// <param name="dt">datatable</param>
    /// <param name="filepath">写入的文件路径</param>
    /// <returns></returns>
    public static bool DataTableToExcel(DataTable dt, string filepath)
    { bool result = false;
        IWorkbook workbook = null;
        FileStream fs = null;
        IRow row = null;
        ISheet sheet = null;
        ICell cell = null; try { if (dt != null && dt.Rows.Count > 0)
            {
                workbook = new HSSFWorkbook();
                sheet = workbook.CreateSheet("Sheet0");//创建一个名称为Sheet0的表 
                int rowCount = dt.Rows.Count;//行数 
                int columnCount = dt.Columns.Count;//列数 

                int cellnum; //设置列头 
                row = sheet.CreateRow(0);//excel第一行设为列头 
                for (int c = 0; c < columnCount; c++)
                {
                    cell = row.CreateCell(c);
                    cell.SetCellValue(dt.Columns\[c\].ColumnName);
                } //设置每行每列的单元格, 
                for (int i = 0; i < rowCount; i++)
                {
                    row = sheet.CreateRow(i + 1); for (int j = 0; j < columnCount; j++)
                    {
                        cell = row.CreateCell(j);//excel第二行开始写入数据 //cell.SetCellValue(dt.Rows\[i\]\[j\].ToString()); //保存单元格格式为数字
                        if (j < 2)
                        {
                            cell.SetCellValue(dt.Rows\[i\]\[j\].ToString());
                        } else { //cell.SetCellValue(int.Parse(dt.Rows\[i\]\[j\].ToString()));
                            if (dt.Rows\[i\]\[j\] is DBNull)
                            {
                                cell.SetCellValue(dt.Rows\[i\]\[j\].ToString());
                            } else {
                                cellnum = Convert.ToInt32(dt.Rows\[i\]\[j\].ToString());
                                cell.SetCellValue(cellnum);
                            }
                        }
                    }
                } if (System.IO.File.Exists(filepath))
                { if (MessageBox.Show("该文件已存在!确定覆盖吗?", "WARNING", MessageBoxButtons.OKCancel) == DialogResult.OK)
                    {
                        File.Delete(filepath);
                    } else { return false;
                    }

                } using (fs = File.OpenWrite(filepath))
                {
                    workbook.Write(fs);//向打开的这个xls文件中写入数据
                    result = true;
                }
            } return result;
        } catch (Exception ex)
        {
            MessageBox.Show(ex.Message); if (fs != null)
            {
                fs.Close();
            } return false;
        }
    }

复制代码; "复制代码")

最后,虽然不常用,但是关键时刻很有用的,写入文件时设置每个单元格数据类型的代码:

复制代码; "复制代码")

    /// <summary>
    /// 设置单元格数据类型 /// </summary>
    /// <param name="cell">目标单元格</param>
    /// <param name="obj">数据值</param>
    /// <returns></returns>
    public static void SetCellValue(ICell cell, object obj)
    { if (obj.GetType() == typeof(int))
        {
            cell.SetCellValue((int)obj);
        } else if (obj.GetType() == typeof(double))
        {
            cell.SetCellValue((double)obj);
        } else if (obj.GetType() == typeof(IRichTextString))
        {
            cell.SetCellValue((IRichTextString)obj);
        } else if (obj.GetType() == typeof(string))
        {
            cell.SetCellValue(obj.ToString());
        } else if (obj.GetType() == typeof(DateTime))
        {
            cell.SetCellValue((DateTime)obj);
        } else if (obj.GetType() == typeof(bool))
        {
            cell.SetCellValue((bool)obj);
        } else {
            cell.SetCellValue(obj.ToString());
        }
    }

复制代码; "复制代码")


原网址: 访问
创建于: 2024-06-19 16:49:07
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论