https://github.com/VahidN/EPPlus.Core
https://www.cnblogs.com/wuzhixiong/p/11991327.html
https://www.cnblogs.com/ouqi/p/13362079.html
这篇文章说明了如何使用EPPlus在ASP.NET Core中导入和导出.xls/.xlsx文件(Excel)。在考虑使用.NET处理excel时,我们总是寻找第三方库或组件。使用Open Office Xml格式(xlsx)读取和写入Excel 2007/2010文件的最流行的.net库之一是EPPlus。这个库现在已经支持.NET Core许久了。这适用于Windows,Linux和Mac。
因此,让我们创建一个新的ASP.NET Core WEB API应用程序并安装EPPlus.Core。要安装EPPlus.Core,请在程序包管理器控制台中运行以下命令:
1 |
PM->Install-Package EPPlus.Core |
或者您可以通过UI界面来安装它.
一切就绪,现在创建一个控制器,命名为: ImportExportController ,添加后,让我们编写导出方法。
为了方便演示,我在wwwroot文件夹中创建了一个excel文件,所以我们就需要去获取我们的项目的绝对路径。
1 2 3 4 5 6 7 8 9 |
public class ImportExportController : ControllerBase { private readonly IHostingEnvironment _hostingEnvironment; public ImportExportController(IHostingEnvironment hostingEnvironment) { _hostingEnvironment = hostingEnvironment; } } |
ExcelPackage 在 OfficeOpenXml 命名空间中可用的类将用于读写xlsx。定义名为“Export”的新Web api操作方法,该方法返回生成的xlsx文件的URL。所以这是将数据导出到xlsx的完整代码。其中您需要 using OfficeOpenXml;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
[HttpGet] public string Export() { string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = @"demo.xlsx"; string URL = string.Format("{0}://{1}/{2}", Request.Scheme, Request.Host, sFileName); FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); if (file.Exists) { file.Delete(); file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); } using (ExcelPackage package = new ExcelPackage(file)) { // add a new worksheet to the empty workbook ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Employee"); //First add the headers worksheet.Cells[1, 1].Value = "ID"; worksheet.Cells[1, 2].Value = "Name"; worksheet.Cells[1, 3].Value = "Gender"; worksheet.Cells[1, 4].Value = "Salary (in $)"; //Add values worksheet.Cells["A2"].Value = 1000; worksheet.Cells["B2"].Value = "Jon"; worksheet.Cells["C2"].Value = "M"; worksheet.Cells["D2"].Value = 5000; worksheet.Cells["A3"].Value = 1001; worksheet.Cells["B3"].Value = "Graham"; worksheet.Cells["C3"].Value = "M"; worksheet.Cells["D3"].Value = 10000; worksheet.Cells["A4"].Value = 1002; worksheet.Cells["B4"].Value = "Jenny"; worksheet.Cells["C4"].Value = "F"; worksheet.Cells["D4"].Value = 5000; package.Save(); //Save the workbook. } return URL; } |
就这样。现在,当您运行此应用程序并调用export
方法时。完成后,访问wwwroot
您的应用程序的文件夹。您应该在系统上看到“demo.xlsx”。当你打开它时,你应该看到以下内容。
导出为文件方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//导出数据 public IActionResult ExportExcel(int? page, int? officeId) { string XlsxContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; string XlsxContentType1 = "application/vnd.ms-excel"; //业务处理 var q = _dbcontext.MailBoxMessage.AsQueryable(); if (q == null) { return View(null); } using (var package = new ExcelPackage()) { var worksheet = package.Workbook.Worksheets.Add("留言"); string colNames = "编号,标题,"; //业务代码省略... return File(package.GetAsByteArray(), XlsxContentType, "report" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx"); } } |
MS Excel具有以下观察到的MIME类型:
application/vnd.ms-excel
(官方)application/msexcel
application/x-msexcel
application/x-ms-excel
application/x-excel
application/x-dos_ms_excel
application/xls
application/x-xls
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
(xlsx)是否有一种适用于所有版本的类型?如果没有,我们是否需要分别设置
response.setContentType()
这些哑剧类型中的每一种?另外,我们在应用程序中使用文件流来显示文档(不仅仅是excel-任何类型的文档)。这样,如果用户选择保存文件,我们如何保留文件名-当前,呈现文件的servlet的名称显示为默认名称。
对于.xls,请使用以下内容类型
1 application/vnd.ms-excel对于Excel 2007版本及以上.xlsx文件格式
1 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
123 $("#btnExcel").click(function () {window.location.href = window.location.href.replace("/Search", "/ExportExcel");});
您还可以对标题进行加粗,这些并不是EPPlus.Core给我们提供的,你需要引用 using OfficeOpenXml; using OfficeOpenXml.Style;
1 2 3 4 5 6 |
using (var cells = worksheet.Cells[1, 1, 1, 4]) { cells.Style.Font.Bold = true; cells.Style.Fill.PatternType = ExcelFillStyle.Solid; cells.Style.Fill.BackgroundColor.SetColor(Color.LightGray); } |
关于导入,其实真实的情况还是比较复杂的,我们这里就不进行验证了,对于演示,我们只是读取刚刚保存的文件。 ImportAPI 将读取文件并以格式化的字符串返回文件内容。以下是导入API的完整代码,用于读取xlsx,创建文件内容的格式化字符串并返回相同的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
[HttpGet] [Route("Import")] public string Import() { string sWebRootFolder = _hostingEnvironment.WebRootPath; string sFileName = @"demo.xlsx"; FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName)); try { using (ExcelPackage package = new ExcelPackage(file)) { StringBuilder sb = new StringBuilder(); ExcelWorksheet worksheet = package.Workbook.Worksheets[1]; int rowCount = worksheet.Dimension.Rows; int ColCount = worksheet.Dimension.Columns; bool bHeaderRow = true; for (int row = 1; row <= rowCount; row++) { for (int col = 1; col <= ColCount; col++) { if (bHeaderRow) { sb.Append(worksheet.Cells[row, col].Value.ToString() + "\t"); } else { sb.Append(worksheet.Cells[row, col].Value.ToString() + "\t"); } } sb.Append(Environment.NewLine); } return sb.ToString(); } } catch (Exception ex) { return "Some error occured while importing." + ex.Message; } } |
注意:低版本不支持xls文件,只支持xlsx文档的导入。新版本5以上需要商业授权
如果想支持xls需要使用NPOI插件了。参考代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
/// <summary> /// Excel导入帮助类 /// </summary> public class ImportExcelUtil<T> where T : new() { //合法文件扩展名 private static List<string> extName = new List<string>() { ".xls", ".xlsx" }; /// <summary> /// 导入Excel内容读取到List<T>中 /// </summary> /// <param name="file">导入Execl文件</param> /// <param name="sheetName">指定读取excel工作薄sheet的名称</param> /// <returns>List<T></returns> public static List<T> InputExcel(IFormFile file, string sheetName = null) { //获取文件后缀名 string type = Path.GetExtension(file.FileName); //判断是否导入合法文件 if(!extName.Contains(type)) { return null; } //转成为文件流 MemoryStream ms = new MemoryStream(); file.CopyTo(ms); ms.Seek(0, SeekOrigin.Begin); //实例化T数组 List<T> list = new List<T>(); //获取数据 list = InputExcel(ms, sheetName); return list; } /// <summary> /// 将Excel文件内容读取到List<T>中 /// </summary> /// <param name="fileName">文件完整路径名</param> /// <param name="sheetName">指定读取excel工作薄sheet的名称</param> /// <param name="isFirstRowColumn">第一行是否是DataTable的列名:true=是,false=否</param> /// <returns>List<T></returns> public static List<T> InputExcel(string fileName, string sheetName = null) { if (!File.Exists(fileName)) { return null; } //根据指定路径读取文件 FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); //实例化T数组 List<T> list = new List<T>(); //获取数据 list = InputExcel(fs, sheetName); return list; } /// <summary> /// 将Excel文件内容读取到List<T>中 /// </summary> /// <param name="fileStream">文件流</param> /// <param name="sheetName">指定读取excel工作薄sheet的名称</param> /// <returns>List<T></returns> private static List<T> InputExcel(Stream fileStream, string sheetName = null) { //创建Excel数据结构 IWorkbook workbook = WorkbookFactory.Create(fileStream); //如果有指定工作表名称 ISheet sheet = null; if (!string.IsNullOrEmpty(sheetName)) { sheet = workbook.GetSheet(sheetName); //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet if (sheet == null) { sheet = workbook.GetSheetAt(0); } } else { //如果没有指定的sheetName,则尝试获取第一个sheet sheet = workbook.GetSheetAt(0); } //实例化T数组 List<T> list = new List<T>(); if (sheet != null) { //一行最后一个cell的编号 即总的列数 IRow cellNum = sheet.GetRow(0); int num = cellNum.LastCellNum; //获取泛型对象T的所有属性 var propertys = typeof(T).GetProperties(); //每行转换为单个T对象 for (int i = 1; i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); var obj = new T(); for (int j = 0; j < num; j++) { //没有数据的单元格都默认是null ICell cell = row.GetCell(j); if (cell != null) { var value = row.GetCell(j).ToString(); string str = (propertys[j].PropertyType).FullName; if (str == "System.String") { propertys[j].SetValue(obj, value, null); } else if (str == "System.DateTime") { DateTime pdt = Convert.ToDateTime(value, CultureInfo.InvariantCulture); propertys[j].SetValue(obj, pdt, null); } else if (str == "System.Boolean") { bool pb = Convert.ToBoolean(value); propertys[j].SetValue(obj, pb, null); } else if (str == "System.Int16") { short pi16 = Convert.ToInt16(value); propertys[j].SetValue(obj, pi16, null); } else if (str == "System.Int32") { int pi32 = Convert.ToInt32(value); propertys[j].SetValue(obj, pi32, null); } else if (str == "System.Int64") { long pi64 = Convert.ToInt64(value); propertys[j].SetValue(obj, pi64, null); } else if (str == "System.Byte") { byte pb = Convert.ToByte(value); propertys[j].SetValue(obj, pb, null); } else { propertys[j].SetValue(obj, null, null); } } } list.Add(obj); } } return list; } } |
设置日期格式:
设置第5列为日期格式
worksheet.Column(5).Style.Numberformat.Format = "yyyy-MM-dd HH:mm:ss";
C#读取EXCEL单元格的日期时间
C# 导入EXCEL表时,会遇上读出日期时间格式的值一个double类型,而不是常见的日期时间格式字符的形状。
如果从EXCEL单元格读取日期时间的值是一个数字或带小数的数字,那么需要使用日期时间函数进行转换后得到日期时间值:
DateTime.FromOADate(Convert.ToDouble(worksheet.Cells[i, 11].Value));
读取Excel日期数据,一种方式是在EXCEL中把你的日期列的格式设置一下,设成"文本"型。
如果单元格格式设置为date,则在后台读出的数值是一个数值,如2008-08-08读出来是39688,怎样才能读出来是日期格式?方法如下:
要做一个判断,如果该单元格是一个double值,那么就要用 DateTime.FromOADate(double.Parse(range.Value2.ToString()));方法获得时间;如果就是一个时间,那么就直接DateTime.Parse(range.Value2.ToString());就可以了。
string schedule = CommonFunc.ConvertObjectToString(row.GetCell(6)).Trim();
if (IsDouble(schedule))//判断是否是double类型
{
schedule = DateTime.FromOADate(double.Parse(schedule)).ToString("yyyy/MM/dd", System.Globalization.DateTimeFormatInfo.InvariantInfo);
}
发表评论