C#操作Excel方法有很多,以前用的需要电脑安装office才能用,但因为版权问题公司不允许安装office。所以改用NPOI进行Excel操作,基本上一些简单的Excel操作都没有问题,读写合并单元格等都能实现。

NPOI 库下载地址

命名空间:

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

简单的保存数据:

        public void ExcelTest(string path)
{
IWorkbook workbook = new HSSFWorkbook();//创建Workbook
workbook.CreateSheet("sheet1");//创建sheet
using (FileStream fs = File.Create(path))//path=mmm.xls;
{
ISheet sheet = workbook.GetSheetAt();//获取sheet
sheet.CreateRow().CreateCell().SetCellValue("nami");//创建第一行/创建第一单元格/设置第一单元格的内容[可以分开创建,但必须先创建行才能创建单元格不然报错]
sheet.GetRow().CreateCell().SetCellValue("robin");//获取第一行/创建第二单元格/设置第二单元格的内容
sheet.CreateRow().CreateCell().SetCellValue("saber");//创建第二行/创建第一单元格/设置第一单元格的内容
sheet.GetRow().CreateCell().SetCellValue("luffy");//获取第二行/创建第二单元格/设置第二单元格的内容
sheet.GetRow().CreateCell().SetCellValue();
sheet.GetRow().CreateCell().SetCellValue();
//添加批注
IDrawing draw = sheet.CreateDrawingPatriarch();
IComment comment = draw.CreateCellComment(new HSSFClientAnchor(, , , , , , , ));//里面参数应该是指示批注的位置大小吧
comment.String = new HSSFRichTextString("one-piece");//添加批注内容
comment.Author = "梦琪小生";//添加批注作者
sheet.GetRow().GetCell().CellComment = comment;//将之前设置的批注给定某个单元格
//单元格格式设置
ICellStyle cellStyle = workbook.CreateCellStyle();
IDataFormat format = workbook.CreateDataFormat();
cellStyle.DataFormat = format.GetFormat("0.00");
sheet.GetRow().GetCell().CellStyle = cellStyle;
//合并单元格
sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(, , , ));
sheet.CreateRow().CreateCell().SetCellValue("梦琪小生");
ICellStyle titleStyle = workbook.CreateCellStyle();
IFont titleFont = workbook.CreateFont();
titleFont.FontHeightInPoints = ;//设置字体大小
titleFont.Color = HSSFColor.BLUE.index;//设置字体颜色
titleStyle.SetFont(titleFont);
titleStyle.Alignment = HorizontalAlignment.CENTER;//居中
sheet.GetRow().GetCell().CellStyle = titleStyle;
ICellStyle style = workbook.CreateCellStyle();
style.BorderBottom = BorderStyle.THIN;
style.BorderLeft = BorderStyle.THIN;
style.BorderRight = BorderStyle.THIN;
style.BorderTop = BorderStyle.THIN;
sheet.GetRow().GetCell().CellStyle = style;
//插入图片
HSSFClientAnchor anchor2 = new HSSFClientAnchor(, , , , , , , );
byte[] bytes = System.IO.File.ReadAllBytes(@"C:\Users\Administrator\Desktop\image\mqxs.png");
int picID = workbook.AddPicture(bytes, PictureType.PNG);
IPicture pic = patriarch.CreatePicture(anchor2, picID);
pic.Resize();
workbook.Write(fs);//保存文件
}
}

读取Excel返回DataTable:

        /// <summary>
/// 读取Excel[.xls](返回DataTable)
/// </summary>
/// <param name="path">Excel路径</param>
/// <returns></returns>
public static DataTable ReadExcel(string path)
{
try
{
DataTable dt = new DataTable();
using (FileStream fs = new FileStream(path, FileMode.Open))
{
IWorkbook workbook = new HSSFWorkbook(fs);
ISheet sheet = workbook.GetSheetAt();
int rfirst = sheet.FirstRowNum;
int rlast = sheet.LastRowNum;
IRow row = sheet.GetRow(rfirst);
int cfirst = row.FirstCellNum;
int clast = row.LastCellNum;
for (int i = cfirst; i < clast; i++)
{
if (row.GetCell(i) != null)
dt.Columns.Add(row.GetCell(i).StringCellValue, System.Type.GetType("System.String"));
}
row = null;
for (int i = rfirst + ; i <= rlast; i++)
{
DataRow r = dt.NewRow();
IRow ir = sheet.GetRow(i);
for (int j = cfirst; j < clast; j++)
{
if (ir.GetCell(j) != null)
{
r[j] = ir.GetCell(j).ToString();
}
}
dt.Rows.Add(r);
ir = null;
r = null;
}
sheet = null;
workbook = null;
}
return dt;
}
catch
{
System.Windows.Forms.MessageBox.Show("Excel格式错误或者Excel正由另一进程在访问");
return null;
}
}

Ok,NPOI也用了一段时间了....

讲一点经验之谈...关于NPOI的单元格样式CellStyles个数是有限制的4000个,所以大家设置单元格样式的时候尽量不要再for循环里面定义,可以在for循环外围定义好使用...减少CellStyles个数,Ok,主要要讲的是下面的那一条....

((HSSFSheet)sheet).SetEnclosedBorderOfRegion(new NPOI.SS.Util.CellRangeAddress(, , , ), BorderStyle.MEDIUM, HSSFColor.BLACK.index);

这句的功能是给合并后的单元格加外边框。

比如这条语句的意思是将单元格0行0列到50行100列绘制一个整体的外边框。用到是很好用...但是很占资源,不知道为什么就这么一句话会占好几个CellStyles...而且速度较慢....

所以这个功能在数据量小的可以用,问题不大,速度基本影响也不大,但数据量一大...这个相对就会拖累速度了又太占资源.

小生我就在这边吃过亏,就是这条语句导致CellStyles个数不够用[当然不是一句就会有问题咯....因为很多地方合并单元格然后加外边框...最终就悲剧了....]....小生觉得这是NPOI的缺陷...

NPOI操作Excel使用说明:

官网教程相当详细,需进一步学习的请移步至官网学习  http://tonyqus.sinaapp.com/npoi2tutorial

2017/05/05补充:

C# Color转NPOI颜色:

/// <summary>
/// 获取颜色值
/// </summary>
/// <param name="color">颜色RGB</param>
/// <param name="workbook">Excel画布</param>
/// <returns></returns>
public static short GetColorIndex(this HSSFWorkbook workbook,Color color)
{
HSSFPalette palette = workbook.GetCustomPalette();
var v = palette.FindSimilarColor(color.R, color.G, color.B);
if (v == null)
{
throw new Exception("Color is not in Palette");
}
else return v.GetIndex();
}

2018/4/8补充:

获取合并单元格

        /// <summary>
/// 获取当前单元格所在的合并单元格的位置
/// </summary>
/// <param name="sheet">sheet表单</param>
/// <param name="rowIndex">行索引 0开始</param>
/// <param name="colIndex">列索引 0开始</param>
/// <param name="start">合并单元格左上角坐标</param>
/// <param name="end">合并单元格右下角坐标</param>
/// <returns>返回false表示非合并单元格</returns>
private static bool IsMergeCell(ISheet sheet, int rowIndex, int colIndex, out Point start, out Point end)
{
bool result = false;
start = new Point(, );
end = new Point(, );
if ((rowIndex < ) || (colIndex < )) return result;
int regionsCount = sheet.NumMergedRegions;
for (int i = ; i < regionsCount; i++)
{
CellRangeAddress range = sheet.GetMergedRegion(i);
//sheet.IsMergedRegion(range);
if (rowIndex >= range.FirstRow && rowIndex <= range.LastRow && colIndex >= range.FirstColumn && colIndex <= range.LastColumn)
{
start = new Point(range.FirstRow, range.FirstColumn);
end = new Point(range.LastRow, range.LastColumn);
result = true;
break;
}
}
return result;
}

扫码关注微信公众号

C# 如何使用NPOI操作Excel以及读取合并单元格等的更多相关文章

  1. 【转载】jxl操作excel 字体 背景色 合并单元格 列宽等 .

    package com.email.jav; import java.io.File;import java.io.IOException;import java.net.URL; import jx ...

  2. C# 获取Excel中的合并单元格

    C# 获取Excel中的合并单元格 我们在制作表格时,有时经常需要合并及取消合并一些单元格.在取消合并单元格时需要逐个查找及取消,比较麻烦.这里分享一个简单的方法来识别Excel中的合并单元格,识别这 ...

  3. python-Excel读取-合并单元格读取

    python-Excel读取-合并单元格读取(后续会补充python-Excel写入的部分) 1. python读取Excel单元格 代码包含读取Excel中数据,以及出现横向合并单元格,以及竖向合并 ...

  4. poi读取合并单元格

    poi读取合并单元格 学习了:http://blog.csdn.net/ycb1689/article/details/9764191 进行了列合并单元格的修正:原来是我自己找错了地方: import ...

  5. NPOI导出Excel文件,对单元格的一些设置

    HSSFWorkbook book = new HSSFWorkbook(); MemoryStream ms = new MemoryStream(); ISheet sheet = book.Cr ...

  6. C#中NPOI操作excel之读取和写入excel数据

    一.下载引用 下载需要引用的dll,即:NPOI.dll,NPOI.OOXML.dll,NPOI.OpenXml4Net.dll,ICSharpCode.SharpZipLib.dll(office2 ...

  7. JAVA操作Excel时文字自适应单元格的宽度设置方法

    使用JAVA操作Excel通常都使用JXL,方法很简单网上也有很多的教程,然后往往一些细节性的问题却导致我们这些Programmer苦恼不已.这两天帮一个朋友做一个Excel表格自动生成的小软件,就遇 ...

  8. EXCEL自动撤销合并单元格并填充相应内容(转帖)

    若EXCEL工作表有很多合并的单元格,要将所有合并的单元格撤销,并填充撤销合并前显示的内容,这是一项很繁琐且容易出错的工作.但可通过宏程序可轻松准确地搞定,方法如下: 一.实现该功能的Excel宏程序 ...

  9. NPOI操作excel之读取excel数据

    NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目.  一.下载引用 去NPOI官网http://npoi.codeplex. ...

随机推荐

  1. Linux中断 - tasklet

    一.前言 对于中断处理而言,linux将其分成了两个部分,一个叫做中断handler(top half),属于不那么紧急需要处理的事情被推迟执行,我们称之deferable task,或者叫做bott ...

  2. python-循环与判断练习题

    一.设计这样一个函数,在指定的文件夹上创建10个文本,以数字给它们命名. def text_creation(): path ='D:/study/python3/w/' for name in ra ...

  3. Github如何上传代码?

    Github如何上传代码? 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选),勾选Initialize this repository with a README选项, ...

  4. NUMA体系结构详解

    1. NUMA的几个概念(Node,socket,core,thread) 对于socket,core和thread会有不少文章介绍,这里简单说一下,具体参见下图: 一句话总结:socket就是主板上 ...

  5. 2015小米暑期实习笔试题_风口的猪-中国牛市(dp)

    风口之下.猪都能飞.当今中国股市牛市,真可谓"错过等七年". 给你一个回想历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i] ...

  6. 依据经纬度返回地址的url -- GoogleMap

    latlng=34,112">https://maps.googleapis.com/maps/api/geocode/xml? latlng=34,112

  7. RhinoMock中无参数方法和无返回值方法的使用

    无返回值方法,RhinoMock的例子是这么做的: demo.VoidThreeArgs(, "", 0f); LastCall.On(demo).Callback<int, ...

  8. 完美解决 IOS系统safari5.0 浏览器页面布局iframe滚动栏失效问题

    在iframe外层包一层div,加入例如以下样式: style="-webkit-overflow-scrolling:touch;overflow:auto;" 代码例如以下: ...

  9. Mingw opencv Windows下命令行运行

    1.下载opencv 2.3 http://sourceforge.net/projects/opencvlibrary/files/ 下个opencv-win版本吧 至于版本号就随意吧,我选的是2. ...

  10. angular学习笔记(二十二)-$http.post

    基本语法: $http.post('url',{},{}).success(function(data,status,headers,config){ }).error(function(data,s ...