经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
.NET Core 实现Excel的导入导出
来源:cnblogs  作者:TomLucas  时间:2023/9/18 9:04:37  对本文有异议

前言

我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作。在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程。但是直接使用Npoi大部分时候我们可能都会自己封装一下,毕竟根据二八原则,我们百分之八十的场景可能都是进行简单的导入导出操作,这里就引出我们的主角Npoi。

NPOI简介

NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作。NPOI是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目。

一、安装相对应的程序包

在 .Net Core 中使用NPOI首先必须先安装NPOI;如下图所示:
右键项目,选择“管理 NuGet 程序包”菜单

1.1、在 “管理NuGet程序包” 中的浏览搜索:“NPOI”

相关安装包的安装
点击安装以上两个即可,安装完成之后最好重新编译一下项目以防出错

二、新建Excel帮助类

在项目中新建“ExcelHelper”类;此类用于封装导入导出以及其他配置方法。代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.IO;
  5. using NPOI;
  6. using System.Text;
  7. using NPOI.HSSF.UserModel;
  8. using NPOI.XSSF.UserModel;
  9. using NPOI.SS.Formula.Eval;
  10. using NPOI.SS.UserModel;
  11. using NPOI.SS.Util;
  12. using System.Text.RegularExpressions;
  13. using System.Reflection;
  14. using System.Collections;
  15. using NPOI.HSSF.Util;
  16. namespace WebApplication1 //命名空间依据自己的项目进行修改
  17. {
  18. /// <summary>
  19. /// Excel帮助类
  20. /// 功能:
  21. /// 1、导出数据到Excel文件中
  22. /// 2、将Excel文件的数据导入到List<T>对象集合中
  23. /// </summary>
  24. public static class ExcelHelper
  25. {
  26. /// <summary>
  27. /// 导出列名
  28. /// </summary>
  29. public static SortedList ListColumnsName;
  30. #region 从DataTable导出到excel文件中,支持xls和xlsx格式
  31. #region 导出为xls文件内部方法
  32. /// <summary>
  33. /// 从DataTable 中导出到excel
  34. /// </summary>
  35. /// <param name="strFileName">excel文件名</param>
  36. /// <param name="dtSource">datatabe源数据</param>
  37. /// <param name="strHeaderText">表名</param>
  38. /// <param name="sheetnum">sheet的编号</param>
  39. /// <returns></returns>
  40. static MemoryStream ExportDT(string strFileName, DataTable dtSource, string strHeaderText, Dictionary<string, string> dir, int sheetnum)
  41. {
  42. //创建工作簿和sheet
  43. IWorkbook workbook = new HSSFWorkbook();
  44. using (Stream writefile = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Read))
  45. {
  46. if (writefile.Length > 0 && sheetnum > 0)
  47. {
  48. workbook = WorkbookFactory.Create(writefile);
  49. }
  50. }
  51. ISheet sheet = null;
  52. ICellStyle dateStyle = workbook.CreateCellStyle();
  53. IDataFormat format = workbook.CreateDataFormat();
  54. dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");
  55. int[] arrColWidth = new int[dtSource.Columns.Count];
  56. foreach (DataColumn item in dtSource.Columns)
  57. {
  58. arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(Convert.ToString(item.ColumnName)).Length;
  59. }
  60. for (int i = 0; i < dtSource.Rows.Count; i++)
  61. {
  62. for (int j = 0; j < dtSource.Columns.Count; j++)
  63. {
  64. int intTemp = Encoding.GetEncoding(936).GetBytes(Convert.ToString(dtSource.Rows[i][j])).Length;
  65. if (intTemp > arrColWidth[j])
  66. {
  67. arrColWidth[j] = intTemp;
  68. }
  69. }
  70. }
  71. int rowIndex = 0;
  72. foreach (DataRow row in dtSource.Rows)
  73. {
  74. #region 新建表,填充表头,填充列头,样式
  75. if (rowIndex == 0)
  76. {
  77. string sheetName = strHeaderText + (sheetnum == 0 ? "" : sheetnum.ToString());
  78. if (workbook.GetSheetIndex(sheetName) >= 0)
  79. {
  80. workbook.RemoveSheetAt(workbook.GetSheetIndex(sheetName));
  81. }
  82. sheet = workbook.CreateSheet(sheetName);
  83. #region 表头及样式
  84. {
  85. sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
  86. IRow headerRow = sheet.CreateRow(0);
  87. headerRow.HeightInPoints = 25;
  88. headerRow.CreateCell(0).SetCellValue(strHeaderText);
  89. ICellStyle headStyle = workbook.CreateCellStyle();
  90. headStyle.Alignment = HorizontalAlignment.Center;
  91. IFont font = workbook.CreateFont();
  92. font.FontHeightInPoints = 20;
  93. font.Boldweight = 700;
  94. headStyle.SetFont(font);
  95. headerRow.GetCell(0).CellStyle = headStyle;
  96. rowIndex = 1;
  97. }
  98. #endregion
  99. #region 列头及样式
  100. if (rowIndex == 1)
  101. {
  102. IRow headerRow = sheet.CreateRow(1);//第二行设置列名
  103. ICellStyle headStyle = workbook.CreateCellStyle();
  104. headStyle.Alignment = HorizontalAlignment.Center;
  105. IFont font = workbook.CreateFont();
  106. font.FontHeightInPoints = 10;
  107. font.Boldweight = 700;
  108. headStyle.SetFont(font);
  109. //写入列标题
  110. foreach (DataColumn column in dtSource.Columns)
  111. {
  112. headerRow.CreateCell(column.Ordinal).SetCellValue(dir[column.ColumnName]);
  113. headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
  114. //设置列宽
  115. sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256 * 2);
  116. }
  117. rowIndex = 2;
  118. }
  119. #endregion
  120. }
  121. #endregion
  122. #region 填充内容
  123. IRow dataRow = sheet.CreateRow(rowIndex);
  124. foreach (DataColumn column in dtSource.Columns)
  125. {
  126. NPOI.SS.UserModel.ICell newCell = dataRow.CreateCell(column.Ordinal);
  127. string drValue = row[column].ToString();
  128. switch (column.DataType.ToString())
  129. {
  130. case "System.String": //字符串类型
  131. double result;
  132. if (isNumeric(drValue, out result))
  133. {
  134. //数字字符串
  135. double.TryParse(drValue, out result);
  136. newCell.SetCellValue(result);
  137. break;
  138. }
  139. else
  140. {
  141. newCell.SetCellValue(drValue);
  142. break;
  143. }
  144. case "System.DateTime": //日期类型
  145. DateTime dateV;
  146. DateTime.TryParse(drValue, out dateV);
  147. newCell.SetCellValue(dateV);
  148. newCell.CellStyle = dateStyle; //格式化显示
  149. break;
  150. case "System.Boolean": //布尔型
  151. bool boolV = false;
  152. bool.TryParse(drValue, out boolV);
  153. newCell.SetCellValue(boolV);
  154. break;
  155. case "System.Int16": //整型
  156. case "System.Int32":
  157. case "System.Int64":
  158. case "System.Byte":
  159. int intV = 0;
  160. int.TryParse(drValue, out intV);
  161. newCell.SetCellValue(intV);
  162. break;
  163. case "System.Decimal": //浮点型
  164. case "System.Double":
  165. double doubV = 0;
  166. double.TryParse(drValue, out doubV);
  167. newCell.SetCellValue(doubV);
  168. break;
  169. case "System.DBNull": //空值处理
  170. newCell.SetCellValue("");
  171. break;
  172. default:
  173. newCell.SetCellValue(drValue.ToString());
  174. break;
  175. }
  176. }
  177. #endregion
  178. rowIndex++;
  179. }
  180. using (MemoryStream ms = new MemoryStream())
  181. {
  182. workbook.Write(ms, true);
  183. ms.Flush();
  184. ms.Position = 0;
  185. return ms;
  186. }
  187. }
  188. #endregion
  189. #region 导出为xlsx文件内部方法
  190. /// <summary>
  191. /// 从DataTable 中导出到excel
  192. /// </summary>
  193. /// <param name="dtSource">DataTable数据源</param>
  194. /// <param name="strHeaderText">表名</param>
  195. /// <param name="fs">文件流</param>
  196. /// <param name="readfs">内存流</param>
  197. /// <param name="sheetnum">sheet索引</param>
  198. static void ExportDTI(DataTable dtSource, string strHeaderText, FileStream fs, MemoryStream readfs, Dictionary<string, string> dir, int sheetnum)
  199. {
  200. IWorkbook workbook = new XSSFWorkbook();
  201. if (readfs.Length > 0 && sheetnum > 0)
  202. {
  203. workbook = WorkbookFactory.Create(readfs);
  204. }
  205. ISheet sheet = null;
  206. ICellStyle dateStyle = workbook.CreateCellStyle();
  207. IDataFormat format = workbook.CreateDataFormat();
  208. dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");
  209. //取得列宽
  210. int[] arrColWidth = new int[dtSource.Columns.Count];
  211. foreach (DataColumn item in dtSource.Columns)
  212. {
  213. arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(Convert.ToString(item.ColumnName)).Length;
  214. }
  215. for (int i = 0; i < dtSource.Rows.Count; i++)
  216. {
  217. for (int j = 0; j < dtSource.Columns.Count; j++)
  218. {
  219. int intTemp = Encoding.GetEncoding(936).GetBytes(Convert.ToString(dtSource.Rows[i][j])).Length;
  220. if (intTemp > arrColWidth[j])
  221. {
  222. arrColWidth[j] = intTemp;
  223. }
  224. }
  225. }
  226. int rowIndex = 0;
  227. foreach (DataRow row in dtSource.Rows)
  228. {
  229. #region 新建表,填充表头,填充列头,样式
  230. if (rowIndex == 0)
  231. {
  232. #region 表头及样式
  233. {
  234. string sheetName = strHeaderText + (sheetnum == 0 ? "" : sheetnum.ToString());
  235. if (workbook.GetSheetIndex(sheetName) >= 0)
  236. {
  237. workbook.RemoveSheetAt(workbook.GetSheetIndex(sheetName));
  238. }
  239. sheet = workbook.CreateSheet(sheetName);
  240. sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
  241. IRow headerRow = sheet.CreateRow(0);
  242. headerRow.HeightInPoints = 25;
  243. headerRow.CreateCell(0).SetCellValue(strHeaderText);
  244. ICellStyle headStyle = workbook.CreateCellStyle();
  245. headStyle.Alignment = HorizontalAlignment.Center;
  246. IFont font = workbook.CreateFont();
  247. font.FontHeightInPoints = 20;
  248. font.Boldweight = 700;
  249. headStyle.SetFont(font);
  250. headerRow.GetCell(0).CellStyle = headStyle;
  251. }
  252. #endregion
  253. #region 列头及样式
  254. {
  255. IRow headerRow = sheet.CreateRow(1);
  256. ICellStyle headStyle = workbook.CreateCellStyle();
  257. headStyle.Alignment = HorizontalAlignment.Center;
  258. IFont font = workbook.CreateFont();
  259. font.FontHeightInPoints = 10;
  260. font.Boldweight = 700;
  261. headStyle.SetFont(font);
  262. foreach (DataColumn column in dtSource.Columns)
  263. {
  264. headerRow.CreateCell(column.Ordinal).SetCellValue(dir[column.ColumnName]);
  265. headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
  266. //设置列宽
  267. sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256 * 2);
  268. }
  269. }
  270. #endregion
  271. rowIndex = 2;
  272. }
  273. #endregion
  274. #region 填充内容
  275. IRow dataRow = sheet.CreateRow(rowIndex);
  276. foreach (DataColumn column in dtSource.Columns)
  277. {
  278. NPOI.SS.UserModel.ICell newCell = dataRow.CreateCell(column.Ordinal);
  279. string drValue = row[column].ToString();
  280. switch (column.DataType.ToString())
  281. {
  282. case "System.String": //字符串类型
  283. double result;
  284. if (isNumeric(drValue, out result))
  285. {
  286. double.TryParse(drValue, out result);
  287. newCell.SetCellValue(result);
  288. break;
  289. }
  290. else
  291. {
  292. newCell.SetCellValue(drValue);
  293. break;
  294. }
  295. case "System.DateTime": //日期类型
  296. DateTime dateV;
  297. DateTime.TryParse(drValue, out dateV);
  298. newCell.SetCellValue(dateV);
  299. newCell.CellStyle = dateStyle; //格式化显示
  300. break;
  301. case "System.Boolean": //布尔型
  302. bool boolV = false;
  303. bool.TryParse(drValue, out boolV);
  304. newCell.SetCellValue(boolV);
  305. break;
  306. case "System.Int16": //整型
  307. case "System.Int32":
  308. case "System.Int64":
  309. case "System.Byte":
  310. int intV = 0;
  311. int.TryParse(drValue, out intV);
  312. newCell.SetCellValue(intV);
  313. break;
  314. case "System.Decimal": //浮点型
  315. case "System.Double":
  316. double doubV = 0;
  317. double.TryParse(drValue, out doubV);
  318. newCell.SetCellValue(doubV);
  319. break;
  320. case "System.DBNull": //空值处理
  321. newCell.SetCellValue("");
  322. break;
  323. default:
  324. newCell.SetCellValue(drValue.ToString());
  325. break;
  326. }
  327. }
  328. #endregion
  329. rowIndex++;
  330. }
  331. workbook.Write(fs,true);
  332. fs.Close();
  333. }
  334. #endregion
  335. #region 导出excel表格
  336. /// <summary>
  337. /// DataTable导出到Excel文件,xls文件
  338. /// </summary>
  339. /// <param name="dtSource">数据源</param>
  340. /// <param name="strHeaderText">表名</param>
  341. /// <param name="strFileName">excel文件名</param>
  342. /// <param name="dir">DataTable和excel列名对应字典</param>
  343. /// <param name="sheetRow">每个sheet存放的行数</param>
  344. public static void ExportDTtoExcel(DataTable dtSource, string strHeaderText, string strFileName, Dictionary<string, string> dir, bool isNew, int sheetRow = 50000)
  345. {
  346. int currentSheetCount = GetSheetNumber(strFileName);//现有的页数sheetnum
  347. if (sheetRow <= 0)
  348. {
  349. sheetRow = dtSource.Rows.Count;
  350. }
  351. string[] temp = strFileName.Split('.');
  352. string fileExtens = temp[temp.Length - 1];
  353. int sheetCount = (int)Math.Ceiling((double)dtSource.Rows.Count / sheetRow);//sheet数目
  354. if (temp[temp.Length - 1] == "xls" && dtSource.Columns.Count < 256 && sheetRow < 65536)
  355. {
  356. if (isNew)
  357. {
  358. currentSheetCount = 0;
  359. }
  360. for (int i = currentSheetCount; i < currentSheetCount + sheetCount; i++)
  361. {
  362. DataTable pageDataTable = dtSource.Clone();
  363. int hasRowCount = dtSource.Rows.Count - sheetRow * (i - currentSheetCount) < sheetRow ? dtSource.Rows.Count - sheetRow * (i - currentSheetCount) : sheetRow;
  364. for (int j = 0; j < hasRowCount; j++)
  365. {
  366. pageDataTable.ImportRow(dtSource.Rows[(i - currentSheetCount) * sheetRow + j]);
  367. }
  368. using (MemoryStream ms = ExportDT(strFileName, pageDataTable, strHeaderText, dir, i))
  369. {
  370. using (FileStream fs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
  371. {
  372. byte[] data = ms.ToArray();
  373. fs.Write(data, 0, data.Length);
  374. fs.Flush();
  375. }
  376. }
  377. }
  378. }
  379. else
  380. {
  381. if (temp[temp.Length - 1] == "xls")
  382. strFileName = strFileName + "x";
  383. if (isNew)
  384. {
  385. currentSheetCount = 0;
  386. }
  387. for (int i = currentSheetCount; i < currentSheetCount + sheetCount; i++)
  388. {
  389. DataTable pageDataTable = dtSource.Clone();
  390. int hasRowCount = dtSource.Rows.Count - sheetRow * (i - currentSheetCount) < sheetRow ? dtSource.Rows.Count - sheetRow * (i - currentSheetCount) : sheetRow;
  391. for (int j = 0; j < hasRowCount; j++)
  392. {
  393. pageDataTable.ImportRow(dtSource.Rows[(i - currentSheetCount) * sheetRow + j]);
  394. }
  395. FileStream readfs = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.Read);
  396. MemoryStream readfsm = new MemoryStream();
  397. readfs.CopyTo(readfsm);
  398. readfs.Close();
  399. using (FileStream writefs = new FileStream(strFileName, FileMode.Create, FileAccess.Write))
  400. {
  401. ExportDTI(pageDataTable, strHeaderText, writefs, readfsm, dir, i);
  402. }
  403. readfsm.Close();
  404. }
  405. }
  406. }
  407. /// <summary>
  408. /// 导出Excel(//超出10000条数据 创建新的工作簿)
  409. /// </summary>
  410. /// <param name="dtSource">数据源</param>
  411. /// <param name="dir">导出Excel表格的字段名和列名的字符串字典实例;例如:dir.Add("IllegalKeywords", "姓名");</param>
  412. public static XSSFWorkbook ExportExcel(DataTable dtSource, Dictionary<string, string> dir)
  413. {
  414. XSSFWorkbook excelWorkbook = new XSSFWorkbook();
  415. //int columnsCount = columnsNames.GetLength(0);
  416. int columnsCount = dir.Count;
  417. if (columnsCount > 0)
  418. {
  419. ListColumnsName = new SortedList(new NoSort());
  420. //for (int i = 0; i < columnsCount; i++)
  421. //{
  422. // ListColumnsName.Add(columnsNames[i, 0], columnsNames[i, 1]);
  423. //}
  424. foreach (KeyValuePair<string,string> item in dir)
  425. {
  426. ListColumnsName.Add(item.Key, item.Value);
  427. }
  428. if (ListColumnsName == null || ListColumnsName.Count == 0)
  429. {
  430. throw (new Exception("请对ListColumnsName设置要导出的列明!"));
  431. }
  432. else
  433. {
  434. excelWorkbook = InsertRow(dtSource);
  435. }
  436. }
  437. else
  438. {
  439. throw (new Exception("请对ListColumnsName设置要导出的列明!"));
  440. }
  441. return excelWorkbook;
  442. }
  443. #endregion
  444. /// <summary>
  445. /// 创建Excel文件
  446. /// </summary>
  447. /// <param name="filePath"></param>
  448. private static XSSFWorkbook CreateExcelFile()
  449. {
  450. XSSFWorkbook xssfworkbook = new XSSFWorkbook();
  451. //右击文件“属性”信息
  452. #region 文件属性信息
  453. {
  454. POIXMLProperties props = xssfworkbook.GetProperties();
  455. props.CoreProperties.Creator = "Joy";//Excel文件的创建作者
  456. props.CoreProperties.Title = "";//Excel文件标题
  457. props.CoreProperties.Description = "";//Excel文件备注
  458. props.CoreProperties.Category = "";//Excel文件类别信息
  459. props.CoreProperties.Subject = "";//Excel文件主题信息
  460. props.CoreProperties.Created = DateTime.Now;//Excel文件创建时间
  461. props.CoreProperties.Modified = DateTime.Now;//Excel文件修改时间
  462. props.CoreProperties.SetCreated(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
  463. props.CoreProperties.LastModifiedByUser = "Joy";//Excel文件最后一次保存者
  464. props.CoreProperties.SetModified(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));//Excel文件最后一次保存日期
  465. }
  466. #endregion
  467. return xssfworkbook;
  468. }
  469. /// <summary>
  470. /// 创建excel表头
  471. /// </summary>
  472. /// <param name="dgv"></param>
  473. /// <param name="excelSheet"></param>
  474. private static void CreateHeader(XSSFSheet excelSheet, XSSFWorkbook excelWorkbook, XSSFCellStyle cellStyle)
  475. {
  476. int cellIndex = 0;
  477. //循环导出列
  478. foreach (System.Collections.DictionaryEntry de in ListColumnsName)
  479. {
  480. XSSFRow newRow = (XSSFRow)excelSheet.CreateRow(0);
  481. XSSFCellStyle? headTopStyle = CreateStyle(excelWorkbook, cellStyle,HorizontalAlignment.Center, VerticalAlignment.Center, 18, true, true, "宋体", true, false, false, true, FillPattern.SolidForeground, HSSFColor.Grey25Percent.Index, HSSFColor.Black.Index,FontUnderlineType.None, FontSuperScript.None, false);
  482. XSSFCell newCell = (XSSFCell)newRow.CreateCell(cellIndex);
  483. newCell.SetCellValue(de.Value.ToString());
  484. newCell.CellStyle = headTopStyle;
  485. cellIndex++;
  486. }
  487. }
  488. /// <summary>
  489. /// 插入数据行
  490. /// </summary>
  491. private static XSSFWorkbook InsertRow(DataTable dtSource)
  492. {
  493. XSSFWorkbook excelWorkbook = CreateExcelFile();
  494. int rowCount = 0;
  495. int sheetCount = 1;
  496. XSSFSheet newsheet = null;
  497. //循环数据源导出数据集
  498. newsheet = (XSSFSheet)excelWorkbook.CreateSheet("Sheet" + sheetCount);
  499. XSSFCellStyle headCellStyle = (XSSFCellStyle)excelWorkbook.CreateCellStyle(); //创建列头单元格实例样式
  500. CreateHeader(newsheet, excelWorkbook, headCellStyle);
  501. //单元格内容信息
  502. foreach (DataRow dr in dtSource.Rows)
  503. {
  504. rowCount++;
  505. //超出10000条数据 创建新的工作簿
  506. if (rowCount == 10000)
  507. {
  508. rowCount = 1;
  509. sheetCount++;
  510. newsheet = (XSSFSheet)excelWorkbook.CreateSheet("Sheet" + sheetCount);
  511. CreateHeader(newsheet, excelWorkbook, headCellStyle);
  512. }
  513. XSSFRow newRow = (XSSFRow)newsheet.CreateRow(rowCount);
  514. XSSFCellStyle cellStyle = (XSSFCellStyle)excelWorkbook.CreateCellStyle(); //创建单元格实例样式
  515. XSSFCellStyle? style = CreateStyle(excelWorkbook, cellStyle, HorizontalAlignment.Center, VerticalAlignment.Center, 14, true, false);
  516. InsertCell(dtSource, dr, newRow, style, excelWorkbook);
  517. }
  518. //自动列宽
  519. //for (int i = 0; i <= dtSource.Columns.Count; i++)
  520. //{
  521. // newsheet.AutoSizeColumn(i, true);
  522. //}
  523. return excelWorkbook;
  524. }
  525. /// <summary>
  526. /// 导出数据行
  527. /// </summary>
  528. /// <param name="dtSource"></param>
  529. /// <param name="drSource"></param>
  530. /// <param name="currentExcelRow"></param>
  531. /// <param name="excelSheet"></param>
  532. /// <param name="excelWorkBook"></param>
  533. private static void InsertCell(DataTable dtSource, DataRow drSource, XSSFRow currentExcelRow, XSSFCellStyle cellStyle, XSSFWorkbook excelWorkBook)
  534. {
  535. for (int cellIndex = 0; cellIndex < ListColumnsName.Count; cellIndex++)
  536. {
  537. //列名称
  538. string columnsName = ListColumnsName.GetKey(cellIndex).ToString();
  539. XSSFCell newCell = null;
  540. System.Type rowType = drSource[columnsName].GetType();
  541. string drValue = drSource[columnsName].ToString().Trim();
  542. switch (rowType.ToString())
  543. {
  544. case "System.String"://字符串类型
  545. drValue = drValue.Replace("&", "&");
  546. drValue = drValue.Replace(">", ">");
  547. drValue = drValue.Replace("<", "<");
  548. newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  549. newCell.SetCellValue(drValue);
  550. newCell.CellStyle = cellStyle;
  551. break;
  552. case "System.DateTime"://日期类型
  553. DateTime dateV;
  554. DateTime.TryParse(drValue, out dateV);
  555. newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  556. newCell.SetCellValue(dateV);
  557. newCell.CellStyle = cellStyle;
  558. break;
  559. case "System.Boolean"://布尔型
  560. bool boolV = false;
  561. bool.TryParse(drValue, out boolV);
  562. newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  563. newCell.SetCellValue(boolV);
  564. newCell.CellStyle = cellStyle;
  565. break;
  566. case "System.Int16"://整型
  567. case "System.Int32":
  568. case "System.Int64":
  569. case "System.Byte":
  570. int intV = 0;
  571. int.TryParse(drValue, out intV);
  572. newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  573. newCell.SetCellValue(intV.ToString());
  574. newCell.CellStyle = cellStyle;
  575. break;
  576. case "System.Decimal"://浮点型
  577. case "System.Double":
  578. double doubV = 0;
  579. double.TryParse(drValue, out doubV);
  580. newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  581. newCell.SetCellValue(doubV);
  582. newCell.CellStyle = cellStyle;
  583. break;
  584. case "System.DBNull"://空值处理
  585. newCell = (XSSFCell)currentExcelRow.CreateCell(cellIndex);
  586. newCell.SetCellValue("");
  587. newCell.CellStyle = cellStyle;
  588. break;
  589. default:
  590. throw (new Exception(rowType.ToString() + ":类型数据无法处理!"));
  591. }
  592. }
  593. }
  594. /// <summary>
  595. /// 行内单元格常用样式设置
  596. /// </summary>
  597. /// <param name="workbook">Excel文件对象</param>
  598. /// <param name="cellStyle">Excel文件中XSSFCellStyle对象</param>
  599. /// <param name="hAlignment">水平布局方式</param>
  600. /// <param name="vAlignment">垂直布局方式</param>
  601. /// <param name="fontHeightInPoints">字体大小</param>
  602. /// <param name="isAddBorder">是否需要边框</param>
  603. /// <param name="boldWeight">字体加粗 (None = 0,Normal = 400,Bold = 700</param>
  604. /// <param name="fontName">字体(仿宋,楷体,宋体,微软雅黑...与Excel主题字体相对应)</param>
  605. /// <param name="isAddBorderColor">是否增加边框颜色</param>
  606. /// <param name="isItalic">是否将文字变为斜体</param>
  607. /// <param name="isLineFeed">是否自动换行</param>
  608. /// <param name="isAddCellBackground">是否增加单元格背景颜色</param>
  609. /// <param name="fillPattern">填充图案样式(FineDots 细点,SolidForeground立体前景,isAddFillPattern=true时存在)</param>
  610. /// <param name="cellBackgroundColor">单元格背景颜色(当isAddCellBackground=true时存在)</param>
  611. /// <param name="fontColor">字体颜色</param>
  612. /// <param name="underlineStyle">下划线样式(无下划线[None],单下划线[Single],双下划线[Double],会计用单下划线[SingleAccounting],会计用双下划线[DoubleAccounting])</param>
  613. /// <param name="typeOffset">字体上标下标(普通默认值[None],上标[Sub],下标[Super]),即字体在单元格内的上下偏移量</param>
  614. /// <param name="isStrikeout">是否显示删除线</param>
  615. /// <param name="dataFormat">格式化日期显示</param>
  616. /// <returns></returns>
  617. public static XSSFCellStyle CreateStyle(XSSFWorkbook workbook, XSSFCellStyle cellStyle, HorizontalAlignment hAlignment, VerticalAlignment vAlignment, short fontHeightInPoints, bool isAddBorder, bool boldWeight, string fontName = "宋体", bool isAddBorderColor = true, bool isItalic = false, bool isLineFeed = true, bool isAddCellBackground = false, FillPattern fillPattern = FillPattern.NoFill, short cellBackgroundColor = HSSFColor.Yellow.Index, short fontColor = HSSFColor.Black.Index, FontUnderlineType underlineStyle =
  618. FontUnderlineType.None, FontSuperScript typeOffset = FontSuperScript.None, bool isStrikeout = false,string dataFormat="yyyy-MM-dd HH:mm:ss")
  619. {
  620. cellStyle.Alignment = hAlignment; //水平居中
  621. cellStyle.VerticalAlignment = vAlignment; //垂直居中
  622. cellStyle.WrapText = isLineFeed;//自动换行
  623. //格式化显示
  624. XSSFDataFormat format = (XSSFDataFormat)workbook.CreateDataFormat();
  625. cellStyle.DataFormat = format.GetFormat(dataFormat);
  626. //背景颜色,边框颜色,字体颜色都是使用 HSSFColor属性中的对应调色板索引,关于 HSSFColor 颜色索引对照表,详情参考:https://www.cnblogs.com/Brainpan/p/5804167.html
  627. //TODO:引用了NPOI后可通过ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillPattern 为单元格背景色的填充样式
  628. //TODO:十分注意,要设置单元格背景色必须是FillForegroundColor和FillPattern两个属性同时设置,否则是不会显示背景颜色
  629. if (isAddCellBackground)
  630. {
  631. cellStyle.FillForegroundColor = cellBackgroundColor;//单元格背景颜色
  632. cellStyle.FillPattern = fillPattern;//填充图案样式(FineDots 细点,SolidForeground立体前景)
  633. }
  634. else
  635. {
  636. cellStyle.FillForegroundColor = HSSFColor.White.Index;//单元格背景颜色
  637. }
  638. //是否增加边框
  639. if (isAddBorder)
  640. {
  641. //常用的边框样式 None(没有),Thin(细边框,瘦的),Medium(中等),Dashed(虚线),Dotted(星罗棋布的),Thick(厚的),Double(双倍),Hair(头发)[上右下左顺序设置]
  642. cellStyle.BorderBottom = BorderStyle.Thin;
  643. cellStyle.BorderRight = BorderStyle.Thin;
  644. cellStyle.BorderTop = BorderStyle.Thin;
  645. cellStyle.BorderLeft = BorderStyle.Thin;
  646. }
  647. //是否设置边框颜色
  648. if (isAddBorderColor)
  649. {
  650. //边框颜色[上右下左顺序设置]
  651. cellStyle.TopBorderColor = XSSFFont.DEFAULT_FONT_COLOR;//DarkGreen(黑绿色)
  652. cellStyle.RightBorderColor = XSSFFont.DEFAULT_FONT_COLOR;
  653. cellStyle.BottomBorderColor = XSSFFont.DEFAULT_FONT_COLOR;
  654. cellStyle.LeftBorderColor = XSSFFont.DEFAULT_FONT_COLOR;
  655. }
  656. /**
  657. * 设置相关字体样式
  658. */
  659. var cellStyleFont = (XSSFFont)workbook.CreateFont(); //创建字体
  660. //假如字体大小只需要是粗体的话直接使用下面该属性即可
  661. //cellStyleFont.IsBold = true;
  662. cellStyleFont.IsBold = boldWeight; //字体加粗
  663. cellStyleFont.FontHeightInPoints = fontHeightInPoints; //字体大小
  664. cellStyleFont.FontName = fontName;//字体(仿宋,楷体,宋体 )
  665. cellStyleFont.Color = fontColor;//设置字体颜色
  666. cellStyleFont.IsItalic = isItalic;//是否将文字变为斜体
  667. cellStyleFont.Underline = underlineStyle;//字体下划线
  668. cellStyleFont.TypeOffset = typeOffset;//字体上标下标
  669. cellStyleFont.IsStrikeout = isStrikeout;//是否有删除线
  670. cellStyle.SetFont(cellStyleFont); //将字体绑定到样式
  671. return cellStyle;
  672. }
  673. #endregion
  674. #region 从excel文件中将数据导出到List<T>对象集合
  675. /// <summary>
  676. /// 将制定sheet中的数据导出到DataTable中
  677. /// </summary>
  678. /// <param name="sheet">需要导出的sheet</param>
  679. /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param>
  680. /// <param name="dir">excel列名和DataTable列名的对应字典</param>
  681. /// <returns></returns>
  682. static DataTable ImportDt(ISheet sheet, int HeaderRowIndex, Dictionary<string, string> dir)
  683. {
  684. DataTable table = new DataTable();
  685. IRow headerRow;
  686. int cellCount;
  687. try
  688. {
  689. //没有标头或者不需要表头用excel列的序号(1,2,3..)作为DataTable的列名
  690. if (HeaderRowIndex < 0)
  691. {
  692. headerRow = sheet.GetRow(0);
  693. cellCount = headerRow.LastCellNum;
  694. for (int i = headerRow.FirstCellNum; i <= cellCount; i++)
  695. {
  696. DataColumn column = new DataColumn(Convert.ToString(i));
  697. table.Columns.Add(column);
  698. }
  699. }
  700. //有表头,使用表头做为DataTable的列名
  701. else
  702. {
  703. headerRow = sheet.GetRow(HeaderRowIndex);
  704. cellCount = headerRow.LastCellNum;
  705. for (int i = headerRow.FirstCellNum; i <cellCount; i++)
  706. {
  707. //如果excel某一列列名不存在:以该列的序号作为DataTable的列名,如果DataTable中包含了这个序列为名的列,那么列名为重复列名+序号
  708. if (headerRow.GetCell(i) == null)
  709. {
  710. if (table.Columns.IndexOf(Convert.ToString(i)) > 0)
  711. {
  712. DataColumn column = new DataColumn(Convert.ToString("重复列名" + i));
  713. table.Columns.Add(column);
  714. }
  715. else
  716. {
  717. DataColumn column = new DataColumn(Convert.ToString(i));
  718. table.Columns.Add(column);
  719. }
  720. }
  721. //excel中的某一列列名不为空,但是重复了:对应的DataTable列名为“重复列名+序号”
  722. else if (table.Columns.IndexOf(headerRow.GetCell(i).ToString()) > 0)
  723. {
  724. DataColumn column = new DataColumn(Convert.ToString("重复列名" + i));
  725. table.Columns.Add(column);
  726. }
  727. else
  728. //正常情况,列名存在且不重复:用excel中的列名作为DataTable中对应的列名
  729. {
  730. string aaa = headerRow.GetCell(i).ToString();
  731. string colName = dir.Where(s => s.Value == headerRow.GetCell(i).ToString()).First().Key;
  732. DataColumn column = new DataColumn(colName);
  733. table.Columns.Add(column);
  734. }
  735. }
  736. }
  737. int rowCount = sheet.LastRowNum;
  738. for (int i = (HeaderRowIndex + 1); i <= sheet.LastRowNum; i++)//excel行遍历
  739. {
  740. try
  741. {
  742. IRow row;
  743. if (sheet.GetRow(i) == null)//如果excel有空行,则添加缺失的行
  744. {
  745. row = sheet.CreateRow(i);
  746. }
  747. else
  748. {
  749. row = sheet.GetRow(i);
  750. }
  751. DataRow dataRow = table.NewRow();
  752. for (int j = row.FirstCellNum; j <= cellCount; j++)//excel列遍历
  753. {
  754. try
  755. {
  756. if (row.GetCell(j) != null)
  757. {
  758. switch (row.GetCell(j).CellType)
  759. {
  760. case CellType.String://字符串
  761. string str = row.GetCell(j).StringCellValue;
  762. if (str != null && str.Length > 0)
  763. {
  764. dataRow[j] = str.ToString();
  765. }
  766. else
  767. {
  768. dataRow[j] = default(string);
  769. }
  770. break;
  771. case CellType.Numeric://数字
  772. if (DateUtil.IsCellDateFormatted(row.GetCell(j)))//时间戳数字
  773. {
  774. dataRow[j] = DateTime.FromOADate(row.GetCell(j).NumericCellValue);
  775. }
  776. else
  777. {
  778. dataRow[j] = Convert.ToDouble(row.GetCell(j).NumericCellValue);
  779. }
  780. break;
  781. case CellType.Boolean:
  782. dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
  783. break;
  784. case CellType.Error:
  785. dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
  786. break;
  787. case CellType.Formula://公式
  788. switch (row.GetCell(j).CachedFormulaResultType)
  789. {
  790. case CellType.String:
  791. string strFORMULA = row.GetCell(j).StringCellValue;
  792. if (strFORMULA != null && strFORMULA.Length > 0)
  793. {
  794. dataRow[j] = strFORMULA.ToString();
  795. }
  796. else
  797. {
  798. dataRow[j] = null;
  799. }
  800. break;
  801. case CellType.Numeric:
  802. dataRow[j] = Convert.ToString(row.GetCell(j).NumericCellValue);
  803. break;
  804. case CellType.Boolean:
  805. dataRow[j] = Convert.ToString(row.GetCell(j).BooleanCellValue);
  806. break;
  807. case CellType.Error:
  808. dataRow[j] = ErrorEval.GetText(row.GetCell(j).ErrorCellValue);
  809. break;
  810. default:
  811. dataRow[j] = "";
  812. break;
  813. }
  814. break;
  815. default:
  816. dataRow[j] = "";
  817. break;
  818. }
  819. }
  820. }
  821. catch (Exception exception)
  822. {
  823. //loger.Error(exception.ToString());
  824. }
  825. }
  826. table.Rows.Add(dataRow);
  827. }
  828. catch (Exception exception)
  829. {
  830. //loger.Error(exception.ToString());
  831. }
  832. }
  833. }
  834. catch (Exception exception)
  835. {
  836. //loger.Error(exception.ToString());
  837. }
  838. return table;
  839. }
  840. /// <summary>
  841. /// DataTable 转换为List<T>对象集合
  842. /// </summary>
  843. /// <typeparam name="TResult">类型</typeparam>
  844. /// <param name="dt">DataTable</param>
  845. /// <returns></returns>
  846. public static List<TResult> DataTableToList<TResult>(this DataTable dt) where TResult : class, new()
  847. {
  848. //创建一个属性的列表
  849. List<PropertyInfo> prlist = new List<PropertyInfo>();
  850. //获取TResult的类型实例 反射的入口
  851. Type t = typeof(TResult);
  852. //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表
  853. Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });
  854. //创建返回的集合
  855. List<TResult> oblist = new List<TResult>();
  856. foreach (DataRow row in dt.Rows)
  857. {
  858. //创建TResult的实例
  859. TResult ob = new TResult();
  860. //找到对应的数据 并赋值
  861. prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
  862. //放入到返回的集合中.
  863. oblist.Add(ob);
  864. }
  865. return oblist;
  866. }
  867. /// <summary>
  868. /// DataTable转化为List集合
  869. /// </summary>
  870. /// <typeparam name="T">实体对象</typeparam>
  871. /// <param name="dt">datatable表</param>
  872. /// <param name="isStoreDB">是否存入数据库datetime字段,date字段没事,取出不用判断</param>
  873. /// <returns>返回list集合</returns>
  874. private static List<T> DataTableToList<T>(DataTable dt, bool isStoreDB = true)
  875. {
  876. List<T> list = new List<T>();
  877. Type type = typeof(T);
  878. //List<string> listColums = new List<string>();
  879. PropertyInfo[] pArray = type.GetProperties(); //集合属性数组
  880. foreach (DataRow row in dt.Rows)
  881. {
  882. T entity = Activator.CreateInstance<T>(); //新建对象实例
  883. foreach (PropertyInfo p in pArray)
  884. {
  885. if (!dt.Columns.Contains(p.Name) || row[p.Name] == null || row[p.Name] == DBNull.Value)
  886. {
  887. continue; //DataTable列中不存在集合属性或者字段内容为空则,跳出循环,进行下个循环
  888. }
  889. if (isStoreDB && p.PropertyType == typeof(DateTime) && Convert.ToDateTime(row[p.Name]) < Convert.ToDateTime("1753-01-01"))
  890. {
  891. continue;
  892. }
  893. try
  894. {
  895. var obj = Convert.ChangeType(row[p.Name], p.PropertyType);//类型强转,将table字段类型转为集合字段类型
  896. p.SetValue(entity, obj, null);
  897. }
  898. catch (Exception)
  899. {
  900. // throw;
  901. }
  902. }
  903. list.Add(entity);
  904. }
  905. return list;
  906. }
  907. /// <summary>
  908. /// DataSet 转换成List
  909. /// </summary>
  910. /// <typeparam name="T"></typeparam>
  911. /// <param name="ds"></param>
  912. /// <param name="tableIndext"></param>
  913. /// <returns></returns>
  914. private static List<T> DataTable2List<T>(DataTable dt)
  915. {
  916. //确认参数有效
  917. if (dt == null || dt.Rows.Count <= 0)
  918. {
  919. return null;
  920. }
  921. IList<T> list = new List<T>(); //实例化一个list
  922. // 在这里写 获取T类型的所有公有属性。 注意这里仅仅是获取T类型的公有属性,不是公有方法,也不是公有字段,当然也不是私有属性
  923. PropertyInfo[] tMembersAll = typeof(T).GetProperties();
  924. for (int i = 0; i < dt.Rows.Count; i++)
  925. {
  926. //创建泛型对象。为什么这里要创建一个泛型对象呢?是因为目前我不确定泛型的类型。
  927. T t = Activator.CreateInstance<T>();
  928. //获取t对象类型的所有公有属性。但是我不建议吧这条语句写在for循环里,因为没循环一次就要获取一次,占用资源,所以建议写在外面
  929. //PropertyInfo[] tMembersAll = t.GetType().GetProperties();
  930. for (int j = 0; j < dt.Columns.Count; j++)
  931. {
  932. //遍历tMembersAll
  933. foreach (PropertyInfo tMember in tMembersAll)
  934. {
  935. //取dt表中j列的名字,并把名字转换成大写的字母。整条代码的意思是:如果列名和属性名称相同时赋值
  936. if (dt.Columns[j].ColumnName.ToUpper().Equals(tMember.Name.ToUpper()))
  937. {
  938. //dt.Rows[i][j]表示取dt表里的第i行的第j列;DBNull是指数据库中当一个字段没有被设置值的时候的值,相当于数据库中的“空值”。
  939. if (dt.Rows[i][j] != DBNull.Value)
  940. {
  941. //SetValue是指:将指定属性设置为指定值。 tMember是T泛型对象t的一个公有成员,整条代码的意思就是:将dt.Rows[i][j]赋值给t对象的tMember成员,参数详情请参照http://msdn.microsoft.com/zh-cn/library/3z2t396t(v=vs.100).aspx/html
  942. tMember.SetValue(t, Convert.ToString(dt.Rows[i][j]), null);
  943. }
  944. else
  945. {
  946. tMember.SetValue(t, null, null);
  947. }
  948. break;//注意这里的break是写在if语句里面的,意思就是说如果列名和属性名称相同并且已经赋值了,那么我就跳出foreach循环,进行j+1的下次循环
  949. }
  950. }
  951. }
  952. list.Add(t);
  953. }
  954. dt.Dispose();
  955. return list.ToList();
  956. }
  957. /// <summary>
  958. /// 读取Excel文件特定名字sheet的内容到List<T>对象集合
  959. /// </summary>
  960. /// <param name="strFileName">excel文件路径</param>
  961. /// <param name="dir">excel列名和DataTable列名的对应字典</param>
  962. /// <param name="SheetName">excel表名</param>
  963. /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param>
  964. /// <returns></returns>
  965. public static List<T> ImportExceltoDt<T>(string strFileName, Dictionary<string, string> dir, string SheetName, int HeaderRowIndex = 0)
  966. {
  967. DataTable table = new DataTable();
  968. using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
  969. {
  970. if (file.Length > 0)
  971. {
  972. IWorkbook wb = WorkbookFactory.Create(file);
  973. ISheet isheet = wb.GetSheet(SheetName);
  974. table = ImportDt(isheet, HeaderRowIndex, dir);
  975. isheet = null;
  976. }
  977. }
  978. List<T> results = DataTableToList<T>(table);
  979. table.Dispose();
  980. return results;
  981. }
  982. /// <summary>
  983. /// 读取Excel文件某一索引sheet的内容到DataTable
  984. /// </summary>
  985. /// <param name="strFileName">excel文件路径</param>
  986. /// <param name="sheet">需要导出的sheet序号</param>
  987. /// <param name="HeaderRowIndex">列头所在行号,-1表示没有列头</param>
  988. /// <param name="dir">excel列名和DataTable列名的对应字典</param>
  989. /// <returns></returns>
  990. public static List<T> ImportExceltoDt<T>(string strFileName, Dictionary<string, string> dir, int HeaderRowIndex = 0, int SheetIndex = 0)
  991. {
  992. DataTable table = new DataTable();
  993. using (FileStream file = new FileStream(strFileName, FileMode.Open, FileAccess.Read))
  994. {
  995. if (file.Length > 0)
  996. {
  997. IWorkbook wb = WorkbookFactory.Create(file);
  998. ISheet isheet = wb.GetSheetAt(SheetIndex);
  999. table = ImportDt(isheet, HeaderRowIndex, dir);
  1000. isheet = null;
  1001. }
  1002. }
  1003. List<T> results = DataTableToList<T>(table);
  1004. table.Dispose();
  1005. return results;
  1006. }
  1007. #endregion
  1008. /// <summary>
  1009. /// 获取excel文件的sheet数目
  1010. /// </summary>
  1011. /// <param name="outputFile"></param>
  1012. /// <returns></returns>
  1013. public static int GetSheetNumber(string outputFile)
  1014. {
  1015. int number = 0;
  1016. using (FileStream readfile = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Read))
  1017. {
  1018. if (readfile.Length > 0)
  1019. {
  1020. IWorkbook wb = WorkbookFactory.Create(readfile);
  1021. number = wb.NumberOfSheets;
  1022. }
  1023. }
  1024. return number;
  1025. }
  1026. /// <summary>
  1027. /// 判断内容是否是数字
  1028. /// </summary>
  1029. /// <param name="message"></param>
  1030. /// <param name="result"></param>
  1031. /// <returns></returns>
  1032. public static bool isNumeric(String message, out double result)
  1033. {
  1034. Regex rex = new Regex(@"^[-]?\d+[.]?\d*$");
  1035. result = -1;
  1036. if (rex.IsMatch(message))
  1037. {
  1038. result = double.Parse(message);
  1039. return true;
  1040. }
  1041. else
  1042. return false;
  1043. }
  1044. /// <summary>
  1045. /// 验证导入的Excel是否有数据
  1046. /// </summary>
  1047. /// <param name="excelFileStream"></param>
  1048. /// <returns></returns>
  1049. public static bool HasData(Stream excelFileStream)
  1050. {
  1051. using (excelFileStream)
  1052. {
  1053. IWorkbook workBook = new HSSFWorkbook(excelFileStream);
  1054. if (workBook.NumberOfSheets > 0)
  1055. {
  1056. ISheet sheet = workBook.GetSheetAt(0);
  1057. return sheet.PhysicalNumberOfRows > 0;
  1058. }
  1059. }
  1060. return false;
  1061. }
  1062. }
  1063. /// <summary>
  1064. /// 排序实现接口 不进行排序 根据添加顺序导出
  1065. /// </summary>
  1066. public class NoSort : IComparer
  1067. {
  1068. public int Compare(object x, object y)
  1069. {
  1070. return -1;
  1071. }
  1072. }
  1073. }

三、调用

3.1、增加一个“keywords”模型类,用作导出

  1. public class keywords
  2. {
  3. [Column("姓名")]
  4. public string IllegalKeywords { get; set; }
  5. }

3.2、添加一个控制器

3.3、编写导入导出的控制器代码

3.3.1、重写“Close”函数

在导出时,为了防止MemoryStream无法关闭从而报错,所以我们继承MemoryStream;代码如下:

  1. namespace WebApplication1 //命名空间依据自己的项目进行修改
  2. {
  3. public class NpoiMemoryStream : MemoryStream
  4. {
  5. public NpoiMemoryStream()
  6. {
  7. AllowClose = true;
  8. }
  9. public bool AllowClose { get; set; }
  10. public override void Close()
  11. {
  12. if (AllowClose)
  13. base.Close();
  14. }
  15. }
  16. }

3.3.2、添加控制器代码

  1. /// <summary>
  2. /// 本地环境
  3. /// </summary>
  4. private IHostingEnvironment _hostingEnv;
  5. /// <summary>
  6. /// Excel导入的具体实现
  7. /// </summary>
  8. /// <returns></returns>
  9. public IActionResult import_excel()
  10. {
  11. string filepath = _hostingEnv.WebRootPath + "/在线用户20230324.xlsx";//导入的文件地址路径,可动态传入
  12. Dictionary<string, string> dir = new Dictionary<string, string>();//申明excel列名和DataTable列名的对应字典
  13. dir.Add("IllegalKeywords","姓名");
  14. List<keywords> keyWordsList = ExcelHelper.ImportExceltoDt<keywords>(filepath, dir,"Sheet1",0);
  15. #region 将List动态添加至数据库
  16. //……
  17. #endregion
  18. return Json(new { code = 200, msg = "导入成功" });
  19. }
  20. /// <summary>
  21. /// Excel导出的具体实现
  22. /// </summary>
  23. /// <returns></returns>
  24. public IActionResult export_excel()
  25. {
  26. #region 添加测试数据
  27. List<keywords> keys = new List<keywords>();
  28. for (int i = 0; i < 6; i++)
  29. {
  30. keywords keyword = new keywords();
  31. keyword.IllegalKeywords = "测试_" + i;
  32. keys.Add(keyword);
  33. }
  34. #endregion
  35. #region 实例化DataTable并进行赋值
  36. DataTable dt = new DataTable();
  37. dt = listToDataTable(keys);//List<T>对象集合转DataTable
  38. #endregion
  39. string filename = DateTime.Now.ToString("在线用户yyyyMMdd") + ".xlsx";
  40. Dictionary<string, string> dir = new Dictionary<string, string>();
  41. dir.Add("IllegalKeywords", "姓名");
  42. XSSFWorkbook book= ExcelHelper.ExportExcel(dt, dir);
  43. dt.Dispose();//释放DataTable所占用的数据资源
  44. NpoiMemoryStream ms = new NpoiMemoryStream();
  45. ms.AllowClose = false;
  46. book.Write(ms, true);
  47. ms.Flush();
  48. ms.Position = 0;
  49. ms.Seek(0, SeekOrigin.Begin);
  50. ms.AllowClose = true;
  51. book.Dispose();//使用由XSSFWorkbook所占用的资源
  52. return File(ms, "application/vnd.ms-excel", Path.GetFileName(filename));//进行浏览器下载
  53. }

3.3.3、Excel导出效果

Excel导出效果

3.3.4、Excel导入效果

导入后的List再根据需求调用添加方法实现数据的添加
Excel导入效果

原文链接:https://www.cnblogs.com/lucasDC/p/17707810.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号