经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C#NPOI操作Excel,实现Excel数据导入导出(支持多个sheet)
来源:cnblogs  作者:£冷☆月№  时间:2023/2/15 9:22:10  对本文有异议

 

首先在项目中引用NPOI,通过管理NuGet程序包,搜索NPOI,选择版本2.3.0(支持.NET Framework 4.0)根据自己项目选择适当版本。

1.NpoiExcelHelper.cs  Npoi操作Excel类

  1. using System.Data;
  2. using System.IO;
  3. using NPOI.SS.UserModel;
  4. using NPOI.XSSF.UserModel;
  5. using NPOI.HSSF.UserModel;
  6. /// <summary>
  7. /// Npoi操作Excel类
  8. /// </summary>
  9. public static class NpoiExcelHelper
  10. {
  11. /// <summary>
  12. /// 根据Excel文件类型返回IWorkbook
  13. /// </summary>
  14. /// <param name="fileName">文件路径/文件名称(含后缀名)</param>
  15. /// <param name="rowNum">Excel行数</param>
  16. /// <param name="colNum">Excel列数</param>
  17. /// <param name="isFirstRowColumn">第一行是否是标题</param>
  18. /// <returns></returns>
  19. public static IWorkbook GetWorkbook(string fileName, out int rowNum, out int colNum, bool isFirstRowColumn = true)
  20. {
  21. bool isXlsx = Path.GetExtension(fileName).Equals(".xlsx");
  22. if (isXlsx)
  23. {
  24. if (isFirstRowColumn)
  25. {
  26. rowNum = 1048575;
  27. }
  28. else
  29. {
  30. rowNum = 1048576;
  31. }
  32. colNum = 16384;
  33. }
  34. else
  35. {
  36. if (isFirstRowColumn)
  37. {
  38. rowNum = 65535;
  39. }
  40. else
  41. {
  42. rowNum = 65536;
  43. }
  44. colNum = 256;
  45. }
  46. if (File.Exists(fileName))
  47. {
  48. using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
  49. {
  50. if (isXlsx)
  51. {
  52. return new XSSFWorkbook(fs);
  53. }
  54. else
  55. {
  56. return new HSSFWorkbook(fs);
  57. }
  58. }
  59. }
  60. else
  61. {
  62. if (isXlsx)
  63. {
  64. return new XSSFWorkbook();
  65. }
  66. else
  67. {
  68. return new HSSFWorkbook();
  69. }
  70. }
  71. }
  72. /// <summary>
  73. /// 将DataTable中的数据导入到excel中(第一行是标题)
  74. /// 支持根据Excel数据自动分页(多个Sheet)
  75. /// </summary>
  76. /// <param name="dt">DataTable</param>
  77. /// <param name="fileName">文件路径/文件名称(含后缀名)</param>
  78. /// <param name="columnFieldText">字段对应中文 顺序需要跟Excel中数据顺序一致</param>
  79. /// <param name="sheetName">Excel中Sheet名称(多个sheet时 名字后面自动加上数字序号)</param>
  80. /// <returns></returns>
  81. public static byte[] DataTableToExcel(DataTable dt, string fileName, string[,] columnFieldText = null, string sheetName = null)
  82. {
  83. int rowNum = 0;
  84. int colNum = 0;
  85. IWorkbook workbook = GetWorkbook(fileName, out rowNum, out colNum);
  86. var recordNum = dt.Rows.Count;
  87. int totalPage = recordNum % rowNum == 0 ? recordNum / rowNum : recordNum / rowNum + 1;
  88. for (var p = 0; p < totalPage; p++)
  89. {
  90. if (string.IsNullOrEmpty(sheetName))
  91. {
  92. sheetName = dt.TableName;
  93. }
  94. if (totalPage > 1)
  95. {
  96. if (string.IsNullOrEmpty(sheetName))
  97. {
  98. sheetName = "Sheet";
  99. }
  100. sheetName = sheetName + (p + 1).ToString();
  101. }
  102. else
  103. {
  104. if (string.IsNullOrEmpty(sheetName))
  105. {
  106. sheetName = "Sheet1";
  107. }
  108. }
  109. ISheet sheet = workbook.CreateSheet(sheetName);//创建工作表
  110.  
  111. #region 标题
  112. IRow row = sheet.CreateRow(0);//在工作表中添加一行
  113. if (columnFieldText != null)
  114. {
  115. var dataColumn = columnFieldText.GetLength(0);
  116. if (dataColumn <= colNum)
  117. {
  118. for (int m = 0; m < dataColumn; m++)
  119. {
  120. ICell cell = row.CreateCell(m);//在行中添加一列
  121. cell.SetCellValue(columnFieldText[m, 1]);//设置列的内容
  122. }
  123. }
  124. else
  125. {
  126. //数据列数超过了Excel的列数
  127. }
  128. }
  129. else
  130. {
  131. var dataColumn = dt.Columns.Count;
  132. if (dataColumn <= colNum)
  133. {
  134. for (int i = 0; i < dataColumn; i++)
  135. {
  136. ICell cell = row.CreateCell(i);//在行中添加一列
  137. cell.SetCellValue(dt.Columns[i].ColumnName);//设置列的内容
  138. }
  139. }
  140. else
  141. {
  142. //数据列数超过了Excel的列数
  143. }
  144. }
  145. #endregion
  146. #region 填充数据
  147.  
  148. int startIndex = p * rowNum;
  149. int endindex = (p + 1) * rowNum - 1;
  150. if (endindex >= recordNum)
  151. {
  152. endindex = recordNum - 1;
  153. }
  154. for (int i = startIndex; i <= endindex; i++)//遍历DataTable行
  155. {
  156. DataRow dataRow = dt.Rows[i];
  157. row = sheet.CreateRow(i - startIndex + 1);//在工作表中添加一行
  158.  
  159. if (columnFieldText != null)
  160. {
  161. var dataColumn = columnFieldText.GetLength(0);
  162. if (dataColumn <= colNum)
  163. {
  164. for (int m = 0; m < dataColumn; m++)
  165. {
  166. ICell cell = row.CreateCell(m);//在行中添加一列
  167. cell.SetCellValue(dataRow[columnFieldText[m, 0]].ToString());//设置列的内容
  168. }
  169. }
  170. else
  171. {
  172. //数据列数超过了Excel的列数
  173. }
  174. }
  175. else
  176. {
  177. var dataColumn = dt.Columns.Count;
  178. if (dataColumn <= colNum)
  179. {
  180. for (int j = 0; j < dt.Columns.Count; j++)//遍历DataTable列
  181. {
  182. ICell cell = row.CreateCell(j);//在行中添加一列
  183. cell.SetCellValue(dataRow[j].ToString());//设置列的内容
  184. }
  185. }
  186. else
  187. {
  188. //数据列数超过了Excel的列数
  189. }
  190. }
  191. }
  192. #endregion
  193. }
  194. #region 输出Excel
  195. using (MemoryStream stream = new MemoryStream())
  196. {
  197. workbook.Write(stream);
  198. return stream.ToArray();
  199. }
  200. #endregion
  201. }
  202. /// <summary>
  203. /// 将excel中的数据导入到DataTable中(第一行是标题)
  204. /// 支持多个sheet数据导入(建议多个sheet的数据格式保持一致,将没有数据的sheet删除)
  205. /// </summary>
  206. /// <param name="fileName">文件路径(含文件名称后缀名)</param>
  207. /// <param name="columnFieldText">字段对应中文 顺序需要跟Excel中数据顺序一致</param>
  208. /// <param name="sheetName">指定Excel中Sheet名称 如果为null时,读取所有sheet中的数据</param>
  209. /// <returns>返回的DataTable</returns>
  210. public static DataTable ExcelToDataTable(string fileName, string[,] columnFieldText = null, string sheetName = null)
  211. {
  212. DataTable data = new DataTable();
  213. int rowNum = 0;
  214. int colNum = 0;
  215. IWorkbook workbook = GetWorkbook(fileName, out rowNum, out colNum);
  216. for (int e = 0; e < workbook.NumberOfSheets; e++)
  217. {
  218. ISheet sheet = workbook.GetSheetAt(e);
  219. if (sheet != null)
  220. {
  221. var currentSheetIndex = 0;
  222. if (!string.IsNullOrEmpty(sheetName))
  223. {
  224. if (sheet.SheetName == sheetName)
  225. {
  226. currentSheetIndex = e;
  227. }
  228. }
  229. IRow firstRow = sheet.GetRow(0);
  230. if (firstRow != null)
  231. {
  232. int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
  233.  
  234. var dataColumn = columnFieldText != null ? columnFieldText.GetLength(0) : cellCount;
  235. int startRow = sheet.FirstRowNum;
  236. if (dataColumn <= colNum)
  237. {
  238. if (e == currentSheetIndex)
  239. {
  240. for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
  241. {
  242. ICell cell = firstRow.GetCell(i);
  243. if (cell != null)
  244. {
  245. string cellValue = cell.StringCellValue;
  246. if (cellValue != null)
  247. {
  248. DataColumn column = new DataColumn((columnFieldText != null ? columnFieldText[i, 0] : cellValue));
  249. data.Columns.Add(column);
  250. }
  251. }
  252. }
  253. }
  254. startRow = sheet.FirstRowNum + 1;
  255. //最后一列的标号
  256. int rowCount = sheet.LastRowNum;
  257. for (int i = startRow; i <= rowCount; ++i)
  258. {
  259. IRow row = sheet.GetRow(i);
  260. if (row == null) continue; //没有数据的行默认是null       
  261. DataRow dataRow = data.NewRow();
  262. for (int j = row.FirstCellNum; j < cellCount; ++j)
  263. {
  264. if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
  265. dataRow[j] = row.GetCell(j).ToString();
  266. }
  267. data.Rows.Add(dataRow);
  268. }
  269. }
  270. else
  271. {
  272. //数据列数超过了Excel的列数
  273. }
  274. }
  275. if (!string.IsNullOrEmpty(sheetName))
  276. {
  277. if (sheet.SheetName == sheetName)
  278. {
  279. break;
  280. }
  281. }
  282. }
  283. }
  284. return data;
  285. }
  286. }
View Code

2.WEB项目的调用方法:

(1)数据导出到Excel中(支持根据DataTable数据及Excel自动分成多个Sheet)

 调用方法:

  1. int record = 500;
  2. DataTable data = CreateDataTable(record);
  3. string fileName = "客户明细_" + DateTime.Now.ToString("MMddhhmmss") + ".xls";
  4. string sheetName = "客户明细";
  5. string[,] columnFieldText = new[,]{
  6. { "ID", "编号" },
  7. { "Name", "姓名" },
  8. { "CreateTime", "创建时间" }
  9. };
  10. //string[,] columnFieldText = null;
  11.  
  12. var buf = NpoiExcelHelper.DataTableToExcel(data, fileName, columnFieldText, sheetName);
  13. Response.Buffer = true;
  14. Response.Clear();
  15. Response.ClearHeaders();
  16. Response.ClearContent();
  17. Response.Charset = "UTF8";
  18. Response.ContentEncoding = Encoding.UTF8;
  19. Response.ContentType = "application/vnd.ms-excel";
  20. string browser = Request.Browser.Browser;
  21. if (browser.Contains("InternetExplorer"))
  22. Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
  23. else
  24. Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
  25. Response.AddHeader("Content-Length", buf.Length.ToString());
  26. Response.Flush();
  27. Response.BinaryWrite(buf);
  1. /// <summary>
  2. /// 创建DataTable对象
  3. /// </summary>
  4. public DataTable CreateDataTable(int record)
  5. {
  6. //创建DataTable
  7. DataTable dt = new DataTable("NewDt");
  8. //创建自增长的ID列
  9. DataColumn dc = dt.Columns.Add("ID", Type.GetType("System.Int32"));
  10. dc.AutoIncrement = true; //自动增加
  11. dc.AutoIncrementSeed = 1; //起始为1
  12. dc.AutoIncrementStep = 1; //步长为1
  13. dc.AllowDBNull = false; //非空
  14. //创建其它列表
  15. dt.Columns.Add(new DataColumn("Name", Type.GetType("System.String")));
  16. dt.Columns.Add(new DataColumn("CreateTime", Type.GetType("System.DateTime")));
  17. DataRow dr;
  18. for (int i = 0; i < record; i++)
  19. {
  20. dr = dt.NewRow();
  21. dr["Name"] = "名字" + i.ToString();
  22. dr["CreateTime"] = DateTime.Now;
  23. dt.Rows.Add(dr);
  24. }
  25. return dt;
  26. }

(2)Excel中数据导入DataTable中(支持指定Sheet名称 / 多个数据格式一致的Shee)

  1. string fileName = "客户明细_0213023109.xls";
  2. string sheetName = "客户明细1";
  3. string[,] columnFieldText = new[,]{
  4. { "ID", "编号" },
  5. { "Name", "姓名" },
  6. { "CreateTime", "创建时间" }
  7. };
  8. //string[,] columnFieldText = null;
  9.  
  10. var dt = NpoiExcelHelper.ExcelToDataTable(Server.MapPath(fileName), columnFieldText, sheetName);

以上基本实现WEB通过NPOI操作Excel数据导入导出的功能。其他可自行研究。

原文链接:https://www.cnblogs.com/wsk198726/p/17120104.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号