名词介绍:
整个Excel:工作薄
Sheet页:页签,一个工作簿中可以包含多个Sheet页
表格:对应一个Sheet
行、列、单元格
C#中的常规操作:
导出一个Excel:其实就是要生成一个Excel文件,Excel文件对应的文件流
导入一个Excel:读取一个文件,读取文件流,需要从文件流中读取我们需要的各种数据,解析Excel的数据
1.Nuget引入程序包
DotNetCore.NPOI
2.生成一个Excel文件出来
//Main方法
IWorkbook workBook = ExcelOperationHelper.CreateExcelWorkbook();
{
using (FileStream file = new FileStream("D:\\Test\\TestExcel\\StudentInfo.xlsx", FileMode.Create))
{
workBook.Write(file);
file.Close();
}
}
///
/// 测试一下如何生成Excel
///
///
public static IWorkbook CreateExcelWorkbook()
{
HSSFWorkbook _workbook = new HSSFWorkbook();
ISheet sheet1 = _workbook.CreateSheet("Sheet1");
//创建第一行
{
IRow head = sheet1.CreateRow(0);
ICell cell = head.CreateCell(0);
cell.SetCellValue("学生姓名");
ICell cell1 = head.CreateCell(1);
cell1.SetCellValue("数学成绩");
ICell cell2 = head.CreateCell(2);
cell2.SetCellValue("语文成绩");
}
//创建第二行
{
IRow head = sheet1.CreateRow(1);
ICell cell = head.CreateCell(0);
cell.SetCellValue("Richard");
ICell cell1 = head.CreateCell(1);
cell1.SetCellValue("100");
ICell cell2 = head.CreateCell(2);
cell2.SetCellValue("95");
}
return _workbook;
}
1.导出Excel —必然要生成Excel
2.对于系统来说–可以提供的是数据
需要考虑的问题:
最终的目标:
做到业务系统不需要考虑其他,只需要按照规则来给定数据即可,就可以生成Excel出来;
设计生成Excel的数据格式:
using Advanced.Common;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.Data;
namespace NPOI操作Excel导入导出
{
internal class Program
{
static void Main(string[] args)
{
try
{
//IWorkbook workBook = ExcelOperationHelper.CreateExcelWorkbook();
//{
// using (FileStream file = new FileStream("D:\\Test\\TestExcel\\StudentInfo.xlsx", FileMode.Create))
// {
// workBook.Write(file);
// file.Close();
// }
//}
{
List dataResourceslist = GetExcelDataList();
ExcelOperationHelper.DataToHSSFWorkbook(dataResourceslist);
IWorkbook workBook = ExcelOperationHelper.DataToHSSFWorkbook(dataResourceslist);
{
using (FileStream file = new FileStream("D:\\Test\\TestExcel\\StudentInfo.xlsx", FileMode.Create))
{
workBook.Write(file);
//file.Close();
}
}
}
//{
// using (FileStream fileStream = new FileStream("D:\\Test\\TestExcel\\StudentInfo.xlsx", FileMode.Open))
// {
// List dataTables = ExcelOperationHelper.ExcelStreamToDateTable(fileStream);
// }
//}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
}
public static List GetExcelDataList()
{
List
///
/// 给定固定格式的数据,可以生成Excel
///
///
///
public static IWorkbook DataToHSSFWorkbook(List dataResources)
{
HSSFWorkbook _workbook = new HSSFWorkbook();
if (dataResources == null || dataResources.Count == 0)
{
return _workbook;
}
//每循环一次就生成一个Sheet页出来
foreach (var sheetResource in dataResources)
{
if (sheetResource.SheetDataResource != null && sheetResource.SheetDataResource.Count == 0)
{
break;
}
//创建一个页签
ISheet sheet = _workbook.CreateSheet(sheetResource.SheetName);
//确定当前这一页有多少列---取决保存当前Sheet页数据的实体属性中的标记的特性
object obj = sheetResource.SheetDataResource[0];
//获取需要导出的所有的列
Type type = obj.GetType();
List propList = type.GetProperties().Where(c => c.IsDefined(typeof(TitleAttribute),true)).ToList();
//确定表头在哪一行生成
int titleIndex = 0;
if (sheetResource.TitleIndex >= 0)
{
titleIndex = sheetResource.TitleIndex - 1;
}
//基于当前的这个Sheet创建表头
IRow titleRow = sheet.CreateRow(titleIndex);
ICellStyle style = _workbook.CreateCellStyle();
style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
style.FillPattern = FillPattern.SolidForeground;
style.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Automatic.Index;
style.Alignment = HorizontalAlignment.Center;
style.VerticalAlignment = VerticalAlignment.Center;
titleRow.Height = 100 * 4;
//给表头行,分别创建单元格,并赋值字段的名称
for (int i = 0; i < propList.Count(); i++)
{
TitleAttribute propertyAttribute = propList[i].GetCustomAttribute();
ICell cell = titleRow.CreateCell(i);
cell.SetCellValue(propertyAttribute.Titile);
cell.CellStyle = style;
}
//去生成数据
for (int i = 0; i < sheetResource.SheetDataResource.Count(); i++)
{
IRow row = sheet.CreateRow(i + titleIndex + 1);
object objInstance = sheetResource.SheetDataResource[i];
for (int j = 0; j < propList.Count(); j++)
{
ICell cell = row.CreateCell(j);
cell.SetCellValue((propList[j].GetValue(objInstance).ToString()));
}
}
}
return _workbook;
}
///
/// 传入固定格式的数据,生成Excel workbook再写入到基于内存的流里边去
///
///
///
public static MemoryStream ToExcelMemoryStream(List dataResources)
{
IWorkbook _workbook = DataToHSSFWorkbook(dataResources);
using (MemoryStream stream = new MemoryStream())
{
_workbook.Write(stream);
return stream;
}
}
///
/// 通过数据生成Excel 然后转换成byte[]
///
///
///
public static byte[] ToExcelByteArray(List dataResources)
{
IWorkbook _workbook = DataToHSSFWorkbook(dataResources);
using(MemoryStream stream = new MemoryStream())
{
_workbook.Write(stream);
byte[] bt = stream.ToArray();
stream.Write(bt,0,(int)stream.Length);
return bt;
}
}
本质:目的是把Excel文件提交到服务器,然后把Excel文件中的数据信息读取出来,然后要处理的就是数据信息;
Excel文件的解析
using (FileStream fileStream = new FileStream("D:\\Test\\TestExcel\\StudentInfo.xlsx", FileMode.Open))
{
List dataTables = ExcelOperationHelper.ExcelStreamToDateTable(fileStream);
}
///
/// Excel转换成DataTable
///
///
///
public static List ToExcelDataTable(IWorkbook hSSFWorkbook)
{
List datablelist = new List();
for (int sheetIndex = 0; sheetIndex < hSSFWorkbook.NumberOfSheets; sheetIndex++)
{
ISheet sheet = hSSFWorkbook.GetSheetAt(sheetIndex);
//获取表头FirstRowNum 第一行索引 0
IRow header = sheet.GetRow(sheet.FirstRowNum);//获取第一行
if (header == null)
{
break;
}
int startRow = 0; //数据的第一行索引
DataTable dtNpoi = new DataTable();
startRow = sheet.FirstRowNum + 1;
for (int i = header.FirstCellNum; i < header.LastCellNum; i++)
{
ICell cell = header.GetCell(i);
if (cell != null)
{
string cellValue = $"Column{i + 1}_{cell.ToString()}";
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
dtNpoi.Columns.Add(column);
}
else
{
DataColumn column = new DataColumn();
dtNpoi.Columns.Add(column);
}
}
}
//数据 LastRowNum最后一行的索引 如第九行----索引8
for (int i = startRow; i < sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);//获取第i行
if (row == null)
{
continue;
}
DataRow dr = dtNpoi.NewRow();
//遍历每行的单元格
for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
{
if (row.GetCell(j) != null)
{
dr[j] = row.GetCell(j).ToString();
}
}
dtNpoi.Rows.Add(dr);
}
datablelist.Add(dtNpoi);
}
return datablelist;
}
using Advanced.Common;
using System.Data;
namespace Advanced.WinFormProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string fileName = Path.GetExtension(openFileDialog.FileName);
if (fileName != ".xls" && fileName != ".xlsx")
{
MessageBox.Show("请选择Excel文件!");
}
else
{
List dataTables = null;
using (FileStream fileStream = new FileStream(openFileDialog.FileName, FileMode.Open))
{
dataTables = ExcelOperationHelper.ExcelStreamToDateTable(fileStream);
}
this.dataGridView1.DataSource = dataTables[0];
}
}
}
}
}
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.Data;
using System.Reflection;
namespace Advanced.Common
{
///
/// Excel帮助类库
///
public class ExcelOperationHelper
{
///
/// 测试一下如何生成Excel
///
///
public static IWorkbook CreateExcelWorkbook()
{
HSSFWorkbook _workbook = new HSSFWorkbook();
ISheet sheet1 = _workbook.CreateSheet("Sheet1");
//创建第一行
{
IRow head = sheet1.CreateRow(0);
ICell cell = head.CreateCell(0);
cell.SetCellValue("学生姓名");
ICell cell1 = head.CreateCell(1);
cell1.SetCellValue("数学成绩");
ICell cell2 = head.CreateCell(2);
cell2.SetCellValue("语文成绩");
}
//创建第二行
{
IRow head = sheet1.CreateRow(1);
ICell cell = head.CreateCell(0);
cell.SetCellValue("Richard");
ICell cell1 = head.CreateCell(1);
cell1.SetCellValue("100");
ICell cell2 = head.CreateCell(2);
cell2.SetCellValue("95");
}
return _workbook;
}
///
/// 给定固定格式的数据,可以生成Excel
///
///
///
public static IWorkbook DataToHSSFWorkbook(List dataResources)
{
HSSFWorkbook _workbook = new HSSFWorkbook();
if (dataResources == null || dataResources.Count == 0)
{
return _workbook;
}
//每循环一次就生成一个Sheet页出来
foreach (var sheetResource in dataResources)
{
if (sheetResource.SheetDataResource != null && sheetResource.SheetDataResource.Count == 0)
{
break;
}
//创建一个页签
ISheet sheet = _workbook.CreateSheet(sheetResource.SheetName);
//确定当前这一页有多少列---取决保存当前Sheet页数据的实体属性中的标记的特性
object obj = sheetResource.SheetDataResource[0];
//获取需要导出的所有的列
Type type = obj.GetType();
List propList = type.GetProperties().Where(c => c.IsDefined(typeof(TitleAttribute),true)).ToList();
//确定表头在哪一行生成
int titleIndex = 0;
if (sheetResource.TitleIndex >= 0)
{
titleIndex = sheetResource.TitleIndex - 1;
}
//基于当前的这个Sheet创建表头
IRow titleRow = sheet.CreateRow(titleIndex);
ICellStyle style = _workbook.CreateCellStyle();
style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
style.FillPattern = FillPattern.SolidForeground;
style.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Automatic.Index;
style.Alignment = HorizontalAlignment.Center;
style.VerticalAlignment = VerticalAlignment.Center;
titleRow.Height = 100 * 4;
//给表头行,分别创建单元格,并赋值字段的名称
for (int i = 0; i < propList.Count(); i++)
{
TitleAttribute propertyAttribute = propList[i].GetCustomAttribute();
ICell cell = titleRow.CreateCell(i);
cell.SetCellValue(propertyAttribute.Titile);
cell.CellStyle = style;
}
//去生成数据
for (int i = 0; i < sheetResource.SheetDataResource.Count(); i++)
{
IRow row = sheet.CreateRow(i + titleIndex + 1);
object objInstance = sheetResource.SheetDataResource[i];
for (int j = 0; j < propList.Count(); j++)
{
ICell cell = row.CreateCell(j);
cell.SetCellValue((propList[j].GetValue(objInstance).ToString()));
}
}
}
return _workbook;
}
///
/// 传入固定格式的数据,生成Excel workbook再写入到基于内存的流里边去
///
///
///
public static MemoryStream ToExcelMemoryStream(List dataResources)
{
IWorkbook _workbook = DataToHSSFWorkbook(dataResources);
using (MemoryStream stream = new MemoryStream())
{
_workbook.Write(stream);
return stream;
}
}
///
/// 通过数据生成Excel 然后转换成byte[]
///
///
///
public static byte[] ToExcelByteArray(List dataResources)
{
IWorkbook _workbook = DataToHSSFWorkbook(dataResources);
using(MemoryStream stream = new MemoryStream())
{
_workbook.Write(stream);
byte[] bt = stream.ToArray();
stream.Write(bt,0,(int)stream.Length);
return bt;
}
}
///
/// Excel转换成DataTable
///
///
///
public static List ToExcelDataTable(IWorkbook hSSFWorkbook)
{
List datablelist = new List();
for (int sheetIndex = 0; sheetIndex < hSSFWorkbook.NumberOfSheets; sheetIndex++)
{
ISheet sheet = hSSFWorkbook.GetSheetAt(sheetIndex);
//获取表头FirstRowNum 第一行索引 0
IRow header = sheet.GetRow(sheet.FirstRowNum);//获取第一行
if (header == null)
{
break;
}
int startRow = 0; //数据的第一行索引
DataTable dtNpoi = new DataTable();
startRow = sheet.FirstRowNum + 1;
for (int i = header.FirstCellNum; i < header.LastCellNum; i++)
{
ICell cell = header.GetCell(i);
if (cell != null)
{
string cellValue = $"Column{i + 1}_{cell.ToString()}";
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
dtNpoi.Columns.Add(column);
}
else
{
DataColumn column = new DataColumn();
dtNpoi.Columns.Add(column);
}
}
}
//数据 LastRowNum最后一行的索引 如第九行----索引8
for (int i = startRow; i < sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);//获取第i行
if (row == null)
{
continue;
}
DataRow dr = dtNpoi.NewRow();
//遍历每行的单元格
for (int j = row.FirstCellNum; j < row.LastCellNum; j++)
{
if (row.GetCell(j) != null)
{
dr[j] = row.GetCell(j).ToString();
}
}
dtNpoi.Rows.Add(dr);
}
datablelist.Add(dtNpoi);
}
return datablelist;
}
public static List ExcelStreamToDateTable(Stream stream)
{
IWorkbook hSSFWorkbook = WorkbookFactory.Create(stream);
return ToExcelDataTable(hSSFWorkbook);
}
}
}