npoi获取合并单元格_梦琪小生 C# 如何使用NPOI操作Excel以及读取合并单元格等
C#操作Excel方法有很多,以前用的需要電腦安裝office才能用,但因為版權(quán)問題公司不允許安裝office。所以改用NPOI進行Excel操作,基本上一些簡單的Excel操作都沒有問題,讀寫合并單元格等都能實現(xiàn)。
命名空間:
using NPOI;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
簡單的保存數(shù)據(jù):
public void ExcelTest(string path)
{
IWorkbook workbook = new HSSFWorkbook();//創(chuàng)建Workbook
workbook.CreateSheet("sheet1");//創(chuàng)建sheet
using (FileStream fs = File.Create(path))//path=mmm.xls;
{
ISheet sheet = workbook.GetSheetAt(0);//獲取sheet
sheet.CreateRow(1).CreateCell(0).SetCellValue("nami");//創(chuàng)建第一行/創(chuàng)建第一單元格/設置第一單元格的內(nèi)容[可以分開創(chuàng)建,但必須先創(chuàng)建行才能創(chuàng)建單元格不然報錯]
sheet.GetRow(1).CreateCell(1).SetCellValue("robin");//獲取第一行/創(chuàng)建第二單元格/設置第二單元格的內(nèi)容
sheet.CreateRow(2).CreateCell(0).SetCellValue("saber");//創(chuàng)建第二行/創(chuàng)建第一單元格/設置第一單元格的內(nèi)容
sheet.GetRow(2).CreateCell(1).SetCellValue("luffy");//獲取第二行/創(chuàng)建第二單元格/設置第二單元格的內(nèi)容
sheet.GetRow(1).CreateCell(2).SetCellValue(5);
sheet.GetRow(2).CreateCell(2).SetCellValue(2);
//添加批注
IDrawing draw = sheet.CreateDrawingPatriarch();
IComment comment = draw.CreateCellComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 2, 4, 4));//里面參數(shù)應該是指示批注的位置大小吧
comment.String = new HSSFRichTextString("one-piece");//添加批注內(nèi)容
comment.Author = "夢琪小生";//添加批注作者
sheet.GetRow(1).GetCell(1).CellComment = comment;//將之前設置的批注給定某個單元格
//單元格格式設置
ICellStyle cellStyle = workbook.CreateCellStyle();
IDataFormat format = workbook.CreateDataFormat();
cellStyle.DataFormat = format.GetFormat("0.00");
sheet.GetRow(2).GetCell(2).CellStyle = cellStyle;
//合并單元格
sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 2));
sheet.CreateRow(0).CreateCell(0).SetCellValue("夢琪小生");
ICellStyle titleStyle = workbook.CreateCellStyle();
IFont titleFont = workbook.CreateFont();
titleFont.FontHeightInPoints = 15;//設置字體大小
titleFont.Color = HSSFColor.BLUE.index;//設置字體顏色
titleStyle.SetFont(titleFont);
titleStyle.Alignment = HorizontalAlignment.CENTER;//居中
sheet.GetRow(0).GetCell(0).CellStyle = titleStyle;
ICellStyle style = workbook.CreateCellStyle();
style.BorderBottom = BorderStyle.THIN;
style.BorderLeft = BorderStyle.THIN;
style.BorderRight = BorderStyle.THIN;
style.BorderTop = BorderStyle.THIN;
sheet.GetRow(1).GetCell(1).CellStyle = style;
//插入圖片
HSSFClientAnchor anchor2 = new HSSFClientAnchor(0, 0, 0, 0, 0, 5, 6, 10);
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:
///
/// 讀取Excel[.xls](返回DataTable)
///
/// Excel路徑
///
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(0);
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 + 1; 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也用了一段時間了....
講一點經(jīng)驗之談...關(guān)于NPOI的單元格樣式CellStyles個數(shù)是有限制的4000個,所以大家設置單元格樣式的時候盡量不要再for循環(huán)里面定義,可以在for循環(huán)外圍定義好使用...減少CellStyles個數(shù),Ok,主要要講的是下面的那一條....
((HSSFSheet)sheet).SetEnclosedBorderOfRegion(new NPOI.SS.Util.CellRangeAddress(0, 50, 0, 100), BorderStyle.MEDIUM, HSSFColor.BLACK.index);
這句的功能是給合并后的單元格加外邊框。
比如這條語句的意思是將單元格0行0列到50行100列繪制一個整體的外邊框。用到是很好用...但是很占資源,不知道為什么就這么一句話會占好幾個CellStyles...而且速度較慢....
所以這個功能在數(shù)據(jù)量小的可以用,問題不大,速度基本影響也不大,但數(shù)據(jù)量一大...這個相對就會拖累速度了又太占資源.
小生我就在這邊吃過虧,就是這條語句導致CellStyles個數(shù)不夠用[當然不是一句就會有問題咯....因為很多地方合并單元格然后加外邊框...最終就悲劇了....]....小生覺得這是NPOI的缺陷...
NPOI操作Excel使用說明:
2017/05/05補充:
C# Color轉(zhuǎn)NPOI顏色:
///
/// 獲取顏色值
///
/// 顏色RGB
/// Excel畫布
///
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補充:
獲取合并單元格
///
/// 獲取當前單元格所在的合并單元格的位置
///
/// sheet表單
/// 行索引 0開始
/// 列索引 0開始
/// 合并單元格左上角坐標
/// 合并單元格右下角坐標
/// 返回false表示非合并單元格
private static bool IsMergeCell(ISheet sheet, int rowIndex, int colIndex, out Point start, out Point end)
{
bool result = false;
start = new Point(0, 0);
end = new Point(0, 0);
if ((rowIndex < 0) || (colIndex < 0)) return result;
int regionsCount = sheet.NumMergedRegions;
for (int i = 0; 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;
}
2020-09-29補充:(為啥這么多年了,還補充...因為換公司又用到了,就補充一下)
將DataTable導出Excel:
///
/// 創(chuàng)建Excel
///
/// 保存路徑
/// 表格標題
/// 表格數(shù)據(jù)
///
public static bool CreateExcel(string savefile, string title, DataTable dt)
{
try
{
if (dt.Columns.Count > 255)
{
throw new Exception("表格數(shù)據(jù)列超出最大值255");
}
IWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet("sheet1");
using (FileStream fs = File.Create(savefile))
{
int dtRowCount = dt.Rows.Count;
int dtcolumnCount = dt.Columns.Count;
#region[表格樣式]
ICellStyle TitleStyle = MCellStyle.GetCellStyle(workbook, -1, "", 15, true, HSSFColor.Black.Index, HorizontalAlignment.Center, VerticalAlignment.Center, HSSFColor.Grey25Percent.Index);
ICellStyle columnStyle = MCellStyle.GetCellStyle(workbook, -1, "", 11, true, HSSFColor.Black.Index, HorizontalAlignment.Center, VerticalAlignment.Center, HSSFColor.Grey25Percent.Index);
ICellStyle limeStyle = MCellStyle.GetCellStyle(workbook, -1, "", 11, false, HSSFColor.Black.Index, HorizontalAlignment.Center, VerticalAlignment.Center, HSSFColor.White.Index);
ICellStyle roseStyle = MCellStyle.GetCellStyle(workbook, -1, "", 11, false, HSSFColor.Black.Index, HorizontalAlignment.Center, VerticalAlignment.Center, HSSFColor.White.Index);
#endregion
#region[設置標題]
sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 1, 0, dtcolumnCount - 1));
sheet.CreateRow(0); sheet.CreateRow(1);
sheet.GetRow(0).CreateCell(0).SetCellValue(title);
sheet.GetRow(0).GetCell(0).CellStyle = TitleStyle;
#endregion
#region[設置表頭]
IRow row = sheet.CreateRow(2);
for (int j = 0; j < dtcolumnCount; j++)
{
row.CreateCell(j).SetCellValue(dt.Columns[j].ToString());
row.GetCell(j).CellStyle = columnStyle;
sheet.SetColumnWidth(j, 20 * 256);
}
row = null;
#endregion
#region[設置數(shù)據(jù)]
for (int i = 0; i < dtRowCount; i++)
{
IRow rows = sheet.CreateRow(i + 3);
for (int j = 0; j < dtcolumnCount; j++)
{
rows.CreateCell(j).SetCellValue(dt.Rows[i][j].ToString());
if (i % 2 == 0)
rows.GetCell(j).CellStyle = limeStyle;
else
rows.GetCell(j).CellStyle = roseStyle;
}
rows = null;
}
#endregion
#region[設置主邊框]
sheet.GetRow(0).CreateCell(dtcolumnCount - 1).CellStyle = TitleStyle;
sheet.GetRow(1).CreateCell(dtcolumnCount - 1).CellStyle = TitleStyle;
//((HSSFSheet)sheet).SetEnclosedBorderOfRegion(new NPOI.SS.Util.CellRangeAddress(0, dtRowCount, 0, dtcolumnCount - 1), BorderStyle.MEDIUM, HSSFColor.Black.Index);
#endregion
#region[表格樣式反設置]
TitleStyle = null;
columnStyle = null;
limeStyle = null;
roseStyle = null;
#endregion
workbook.Write(fs);
}
sheet = null;
workbook = null;
return true;
}
catch
{
return false;
}
}
創(chuàng)建樣式:(2020-10-20增加樣式的填充顏色)
public static class MCellStyle
{
///
/// 獲取NPOI的單元格樣式
///
/// 表格
/// 單元格編號 默認-1即忽略編號
/// 字體名字
/// 字體大小
/// 是否加粗
/// 填充顏色
/// 水平對齊方式
/// 垂直對齊方式
/// 背景顏色
/// 數(shù)字的格式"0.00"
/// 返回表格單元格樣式CellStyle
public static ICellStyle GetCellStyle(IWorkbook workbook, short cellstyleindex = -1, string fontname = "", short fontsize = 11, bool IsBold = false, short fillforecolor = HSSFColor.COLOR_NORMAL, HorizontalAlignment halignment = HorizontalAlignment.Left, VerticalAlignment valignment = VerticalAlignment.Center, short fillbackcolor = HSSFColor.COLOR_NORMAL, string format = "")
{
if (cellstyleindex != -1)
{
try { return workbook.GetCellStyleAt(cellstyleindex); }
catch {; }
}
if (cellStyle != null) { cellStyle = null; }
cellStyle = workbook.CreateCellStyle();
IFont font = workbook.CreateFont();
if (fillforecolor != HSSFColor.COLOR_NORMAL)
font.Color = fillforecolor;
else
font.Color = HSSFColor.Black.Index;
if (fontsize > 0)
font.FontHeightInPoints = fontsize;
if (fontname != "")
font.FontName = fontname;
if (IsBold)
font.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;
cellStyle.SetFont(font);
if (fillbackcolor != HSSFColor.COLOR_NORMAL)
{
cellStyle.FillForegroundColor = fillbackcolor;
cellStyle.FillPattern = FillPattern.SolidForeground;
}
if (format != "")
{
IDataFormat dataformat = workbook.CreateDataFormat();
cellStyle.DataFormat = dataformat.GetFormat(format);
}
cellStyle.Alignment = halignment;
cellStyle.VerticalAlignment = valignment;
cellStyle.BorderLeft = BorderStyle.Thin;
cellStyle.BorderRight = BorderStyle.Thin;
cellStyle.BorderTop = BorderStyle.Thin;
cellStyle.BorderBottom = BorderStyle.Thin;
cellStyle.WrapText = true;
return cellStyle;
}
///
/// 獲取NPOI的單元格樣式(填充顏色精準)
///
/// 表格
/// 填充顏色
/// 背景顏色
/// 單元格編號 默認-1即忽略編號
/// 字體名字
/// 字體大小
/// 是否加粗
/// 水平對齊方式
/// 垂直對齊方式
/// 數(shù)字的格式"0.00"
/// 返回表格單元格樣式CellStyle
public static ICellStyle GetCellStyle(XSSFWorkbook workbook, Color fillforecolor, Color fillbackcolor, short cellstyleindex = -1, string fontname = "", short fontsize = 11, bool IsBold = false, HorizontalAlignment halignment = HorizontalAlignment.Left, VerticalAlignment valignment = VerticalAlignment.Center, string format = "")
{
if (cellstyleindex != -1)
{
try { return workbook.GetCellStyleAt(cellstyleindex); }
catch {; }
}
if (xssfcellStyle != null) { xssfcellStyle = null; }
xssfcellStyle = workbook.CreateCellStyle() as XSSFCellStyle;
XSSFFont font = workbook.CreateFont() as XSSFFont;
font.SetColor(new XSSFColor(new byte[] { fillforecolor.R, fillforecolor.G, fillforecolor.B }));
if (fontsize > 0)
font.FontHeightInPoints = fontsize;
if (fontname != "")
font.FontName = fontname;
if (IsBold)
font.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;
xssfcellStyle.SetFont(font);
xssfcellStyle.FillPattern = FillPattern.SolidForeground;
if (xssfcellStyle.FillForegroundColorColor == null)
xssfcellStyle.FillForegroundColorColor = new XSSFColor(new byte[] { fillbackcolor.R, fillbackcolor.G, fillbackcolor.B });
else
((XSSFColor)xssfcellStyle.FillForegroundColorColor).SetRgb(new byte[] { fillbackcolor.R, fillbackcolor.G, fillbackcolor.B });
if (format != "")
{
IDataFormat dataformat = workbook.CreateDataFormat();
xssfcellStyle.DataFormat = dataformat.GetFormat(format);
}
xssfcellStyle.Alignment = halignment;
xssfcellStyle.VerticalAlignment = valignment;
xssfcellStyle.BorderLeft = BorderStyle.Thin;
xssfcellStyle.BorderRight = BorderStyle.Thin;
xssfcellStyle.BorderTop = BorderStyle.Thin;
xssfcellStyle.BorderBottom = BorderStyle.Thin;
xssfcellStyle.WrapText = true;
return xssfcellStyle;
}
///
/// 獲取顏色值(不精準)
///
/// 顏色RGB
/// Excel畫布
///
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.Indexed;
}
private static ICellStyle cellStyle;
private static XSSFCellStyle xssfcellStyle;
總結(jié)
以上是生活随笔為你收集整理的npoi获取合并单元格_梦琪小生 C# 如何使用NPOI操作Excel以及读取合并单元格等的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql 开发html,uap开发sql
- 下一篇: C#实现指派问题的匈牙利算法(运筹学)