C#利用NPOI操作Excel文件

  NPOI作为开源免费的组件,功能强大,可用来读写Excel(兼容xls和xlsx两种版本)、Word、PPT文件。可是要让我们记住所有的操作,这便有点困难了,至此,总结一些在开发中常用的针对Excel的简单。NPOI官网地址

  本文地址:https://www.cnblogs.com/CKExp/p/9626022.html

一、NPOI的安装

  下载NPOI或是通过Nuget包加入进来,然后在代码中引用如下命名空间,然后开始读写Excel文件。

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

二、NPOI写入Excel文件

  在NPOI中,使用HSSFWorkbook类类来处理xls结尾的Excel文件(版本在2003及以前),XSSFWorkbook类来处理xlsx结尾的Excel文件(版本在2007及以后),都继承自接口IWorkbook,我们可以使用IWorkbook来统一处理两种不同格式的Excel文件。

  直接参考相关代码即可,对于合并单元格的跨行跨列操作,无需将被跨掉的行生成新行,合并单元格的信息是单独保存的。设置单元格样式时,请创建一个新的样式对象,不创建将使用默认的样式对象。

 /// <summary>
/// Datable导出到Excel
/// </summary>
/// <returns></returns>
public static void DataTableToExcel()
{
//一些已有数据信息
bool fileSaved = false;
SaveFileDialog saveDialog = new SaveFileDialog
{
DefaultExt = "xls",
Filter = "Excel文件|*.xls",
FileName = DateTime.Now.ToString("yyyyMMdd") + "-" + enterpriseTable.Rows[]["名称"].ToString() + "委托书"
};
saveDialog.ShowDialog();
string saveFileName = saveDialog.FileName;
if (saveFileName.IndexOf(":") < ) return; //被点了取消
if (saveFileName != "")
{
try
{
IWorkbook workbook;
string fileExt = System.IO.Path.GetExtension(saveFileName).ToLower();
if (fileExt == ".xlsx")
{
workbook = new XSSFWorkbook();
}
else if (fileExt == ".xls")
{
workbook = new HSSFWorkbook();
}
else
{
return;
} ISheet sheet = workbook.CreateSheet("Sheet1"); sheet.AddMergedRegion(new CellRangeAddress(, , , ));//合并单元格
IRow row = sheet.CreateRow();//创建首行
ICell cell = row.CreateCell();//行中创建第一列
cell.SetCellValue("标题");
ICellStyle style = workbook.CreateCellStyle();//设置样式,创建新的style实例,脱离统一样式
style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;//设置单元格的样式:水平对齐居中
style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; IFont font = workbook.CreateFont();//新建一个字体样式对象
font.Boldweight = short.MaxValue; //设置字体加粗样式
style.SetFont(font); //使用SetFont方法将字体样式添加到单元格样式中
cell.CellStyle = style; //将新的样式赋给单元格 sheet.AddMergedRegion(new CellRangeAddress(, , , ));
sheet.AddMergedRegion(new CellRangeAddress(, , , ));
row = sheet.CreateRow();
cell = row.CreateCell();
cell.SetCellValue("编号:");
cell = row.CreateCell();
cell.SetCellValue(planCode);
cell = row.CreateCell();
cell.SetCellValue("日期:");
cell = row.CreateCell();
cell.SetCellValue(taskPlantable.Rows[]["编制日期"].ToString()); sheet.AddMergedRegion(new CellRangeAddress(, , , ));
sheet.AddMergedRegion(new CellRangeAddress(, , , ));
row = sheet.CreateRow();
cell = row.CreateCell();
cell.SetCellValue("单位:");
cell = row.CreateCell();
cell.SetCellValue(enterpriseTable.Rows[]["名称"].ToString());
cell = row.CreateCell();
cell.SetCellValue("联系人:");
cell = row.CreateCell();
cell.SetCellValue(enterpriseTable.Rows[]["联系人"].ToString()); sheet.AddMergedRegion(new CellRangeAddress(, , , ));
sheet.AddMergedRegion(new CellRangeAddress(, , , ));
row = sheet.CreateRow();
cell = row.CreateCell();
cell.SetCellValue("传真:");
cell = row.CreateCell();
cell.SetCellValue(enterpriseTable.Rows[]["传真"].ToString());
cell = row.CreateCell();
cell.SetCellValue("联系电话:");
cell = row.CreateCell();
cell.SetCellValue(enterpriseTable.Rows[]["电话"].ToString()); sheet.AddMergedRegion(new CellRangeAddress(, , , ));
row = sheet.CreateRow();
cell = row.CreateCell();
cell.SetCellValue("详细地址:");
cell = row.CreateCell();
cell.SetCellValue(enterpriseTable.Rows[]["详细地址"].ToString()); int index = ;
//数据
for (int i = ; i < taskProjectTable.Rows.Count; i++)
{
index++;
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
row = sheet.CreateRow(index);
cell = row.CreateCell();
cell.SetCellValue("名称:");
cell = row.CreateCell();
cell.SetCellValue(taskProjectTable.Rows[i]["名称"].ToString());
cell = row.CreateCell();
cell.SetCellValue("类型:");
cell = row.CreateCell();
cell.SetCellValue(taskProjectTable.Rows[i]["项目类型"].ToString()); index++;
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
row = sheet.CreateRow(index);
cell = row.CreateCell();
cell.SetCellValue("项目");
cell = row.CreateCell();
cell.SetCellValue("方法");
cell = row.CreateCell();
cell.SetCellValue("仪器"); //获取数据信息
DataTable taskDataTable = mysql.GetTableFromSQL(selstr.ToString());
selstr.Clear();
for (int j = ; j < taskDataTable.Rows.Count; j++)
{
index++;
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
sheet.AddMergedRegion(new CellRangeAddress(index, index, , ));
row = sheet.CreateRow(index);
cell = row.CreateCell();
cell.SetCellValue(taskDataTable.Rows[j]["名称"].ToString());
cell = row.CreateCell();
cell.SetCellValue(taskDataTable.Rows[j]["方法"].ToString());
cell = row.CreateCell();
cell.SetCellValue(taskDataTable.Rows[j]["仪器型号"].ToString());
}
} //转为字节数组
MemoryStream stream = new MemoryStream();
workbook.Write(stream);
var buf = stream.ToArray(); //保存为Excel文件
using (FileStream fs = new FileStream(saveDialog.FileName, FileMode.Create, FileAccess.Write))
{
fs.Write(buf, , buf.Length);
fs.Flush();
}
fileSaved = true;
}
catch (Exception ex)
{
fileSaved = false;
MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
}
}
GC.Collect();//强行销毁 if (fileSaved && File.Exists(saveFileName))
{
MessageBox.Show("导出成功!", "通知");
Process.Start(saveFileName);
}
else
{
MessageBox.Show("导出失败!", "通知");
}
}

三、NPOI读取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(); //表头
IRow header = sheet.GetRow(sheet.FirstRowNum);
List<int> columns = new List<int>();
for (int i = ; 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 + ; 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;
}

四、对单元格数据类型的操作

  获取目标单元格的数据类型及数据值。

 /// <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;
}
}

  将数据设置到目标单元格中,并设置为指定数据格式。

 /// <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());
}
}

  本文地址:https://www.cnblogs.com/CKExp/p/9626022.html

2018-09-11,望技术有成后能回来看见自己的脚步
上一篇:通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(四)


下一篇:python grib气象数据可视化