NPOIExcle.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. using NPOI.HSSF.UserModel;
  2. using NPOI.SS.UserModel;
  3. using NPOI.XSSF.UserModel;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Data;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace wispro.sp.utility
  12. {
  13. public class NPOIExcel
  14. {
  15. /// <summary>
  16. /// 将excel导入到datatable
  17. /// </summary>
  18. /// <param name="filePath">excel路径</param>
  19. /// <param name="isColumnName">是否有列名</param>
  20. /// <param name="ColumnNameRow">列名的所在行,0为第一行</param>
  21. /// <param name="IgnoreZeroHightRow">是否忽略隐藏行</param>
  22. /// <returns>返回datatable</returns>
  23. public static DataTable ExcelToDataTable(string filePath, bool isColumnName,bool IgnoreZeroHightRow = false,int ColumnNameRow=0,int iSheet=0)
  24. {
  25. DataTable dataTable = null;
  26. FileStream fs = null;
  27. DataColumn column = null;
  28. DataRow dataRow = null;
  29. IWorkbook workbook = null;
  30. ISheet sheet = null;
  31. IRow row = null;
  32. ICell cell = null;
  33. int startRow = 0;
  34. try
  35. {
  36. using (fs = File.OpenRead(filePath))
  37. {
  38. // 2007版本
  39. if (filePath.IndexOf(".xlsx") > 0)
  40. workbook = new XSSFWorkbook(fs);
  41. // 2003版本
  42. else if (filePath.IndexOf(".xls") > 0)
  43. workbook = new HSSFWorkbook(fs);
  44. if (workbook != null)
  45. {
  46. sheet = workbook.GetSheetAt(iSheet);//读取第一个sheet,当然也可以循环读取每个sheet
  47. dataTable = new DataTable();
  48. if (sheet != null)
  49. {
  50. int rowCount = sheet.LastRowNum;//总行数
  51. if (rowCount > 0)
  52. {
  53. IRow firstRow = sheet.GetRow(ColumnNameRow);//列头行
  54. int cellCount = firstRow.LastCellNum;//列数
  55. //构建datatable的列
  56. if (isColumnName)
  57. {
  58. startRow = ColumnNameRow+1;//如果有列名,则从第列头行的下一行开始读取
  59. for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
  60. {
  61. cell = firstRow.GetCell(i);
  62. if (cell != null)
  63. {
  64. if (cell.StringCellValue != null)
  65. {
  66. column = new DataColumn(cell.StringCellValue);
  67. dataTable.Columns.Add(column);
  68. }
  69. }
  70. }
  71. }
  72. else
  73. {
  74. for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
  75. {
  76. column = new DataColumn("column" + (i + 1));
  77. dataTable.Columns.Add(column);
  78. }
  79. }
  80. //填充行
  81. for (int i = startRow; i <= rowCount; ++i)
  82. {
  83. row = sheet.GetRow(i);
  84. //if(row.GetCell(1).ToString()== "PACN2110126")
  85. //{
  86. // System.Diagnostics.Debug.WriteLine("");
  87. //}
  88. if (row != null && IgnoreZeroHightRow && row.ZeroHeight)
  89. {
  90. System.Diagnostics.Debug.WriteLine (string.Format("[{0}]隐藏行:{1}", filePath, i));
  91. continue;
  92. }
  93. if (row == null || row.Cells.Count ==0) continue;
  94. dataRow = dataTable.NewRow();
  95. for (int j = row.FirstCellNum; j < cellCount; ++j)
  96. {
  97. cell = row.GetCell(j);
  98. if (cell == null)
  99. {
  100. dataRow[j] = "";
  101. }
  102. else
  103. {
  104. //CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
  105. switch (cell.CellType)
  106. {
  107. case CellType.Blank:
  108. dataRow[j] = "";
  109. break;
  110. case CellType.Numeric:
  111. short format = cell.CellStyle.DataFormat;
  112. //对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
  113. if (DateUtil.IsCellDateFormatted(cell))// || format == 14 || format == 31 || format == 57 || format == 58 || format == 165 || format == 177 || format == 176)
  114. try
  115. {
  116. dataRow[j] = cell.DateCellValue;
  117. }
  118. catch
  119. {
  120. //dataRow[j] = null;
  121. }
  122. else
  123. dataRow[j] = cell.NumericCellValue;
  124. break;
  125. case CellType.String:
  126. dataRow[j] = cell.StringCellValue;
  127. break;
  128. }
  129. }
  130. }
  131. dataTable.Rows.Add(dataRow);
  132. }
  133. }
  134. }
  135. }
  136. }
  137. return dataTable;
  138. }
  139. catch (Exception ex)
  140. {
  141. if (fs != null)
  142. {
  143. fs.Close();
  144. }
  145. return null;
  146. }
  147. }
  148. public static DataTable ExcelToDataTable(string v)
  149. {
  150. return ExcelToDataTable(v, false, true);
  151. }
  152. /// <summary>
  153. /// 写入excel
  154. /// </summary>
  155. /// <param name="dt">datatable</param>
  156. /// <param name="strFile">strFile</param>
  157. /// <returns></returns>
  158. public static bool DataTableToExcel(DataTable dt, string strFile,bool isAutoColumnWidth=true)
  159. {
  160. bool result = false;
  161. IWorkbook workbook = null;
  162. FileStream fs = null;
  163. IRow row = null;
  164. ISheet sheet = null;
  165. ICell cell = null;
  166. try
  167. {
  168. if (dt != null && dt.Rows.Count > 0)
  169. {
  170. workbook = new XSSFWorkbook();
  171. sheet = workbook.CreateSheet("Sheet0");//创建一个名称为Sheet0的表
  172. int rowCount = dt.Rows.Count;//行数
  173. int columnCount = dt.Columns.Count;//列数
  174. //设置列头
  175. row = sheet.CreateRow(0);//excel第一行设为列头
  176. for (int c = 0; c < columnCount; c++)
  177. {
  178. cell = row.CreateCell(c);
  179. cell.SetCellValue(dt.Columns[c].ColumnName);
  180. ICellStyle cellStyleColumn = workbook.CreateCellStyle();
  181. cellStyleColumn.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
  182. cellStyleColumn.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
  183. cellStyleColumn.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
  184. cellStyleColumn.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
  185. cellStyleColumn.WrapText = true;// 指定单元格自动换行
  186. cellStyleColumn.VerticalAlignment = VerticalAlignment.Center;//垂直居中
  187. cellStyleColumn.Alignment = HorizontalAlignment.Center; //水平居中
  188. IFont font = workbook.CreateFont();
  189. font.IsBold = true;
  190. cellStyleColumn.SetFont(font);
  191. cell.CellStyle = cellStyleColumn;
  192. }
  193. #region 设置边框
  194. ICellStyle cellStyle = workbook.CreateCellStyle();
  195. cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
  196. cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
  197. cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
  198. cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
  199. cellStyle.WrapText = true;// 指定单元格自动换行
  200. cellStyle.VerticalAlignment = VerticalAlignment.Center;//垂直居中
  201. cellStyle.Alignment = HorizontalAlignment.Center;
  202. #endregion
  203. //设置每行每列的单元格,
  204. for (int i = 0; i < rowCount; i++)
  205. {
  206. row = sheet.CreateRow(i + 1);
  207. row.Height = 30*20;
  208. for (int j = 0; j < columnCount; j++)
  209. {
  210. cell = row.CreateCell(j);//excel第二行开始写入数据
  211. if(dt.Rows[i][j] is System.DBNull)
  212. {
  213. cell.SetCellValue("");
  214. }
  215. else
  216. {
  217. switch (dt.Rows[i][j].GetType().ToString())
  218. {
  219. case "System.String":
  220. cell.SetCellValue(dt.Rows[i][j].ToString());
  221. break;
  222. case "System.Double":
  223. case "System.Int32":
  224. case "System.Int64":
  225. case "System.Float":
  226. case "System.Decimal":
  227. cell.SetCellValue(double.Parse(dt.Rows[i][j].ToString()));
  228. cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("###0.00");//(short)CellType.NUMERIC;
  229. break;
  230. case "System.DateTime":
  231. cell.SetCellValue(DateTime.Parse(dt.Rows[i][j].ToString()));
  232. break;
  233. default:
  234. cell.SetCellValue(dt.Rows[i][j].ToString());
  235. break;
  236. }
  237. }
  238. cell.CellStyle = cellStyle;
  239. }
  240. }
  241. using (fs = File.OpenWrite(strFile))
  242. {
  243. workbook.Write(fs);//向打开的这个xls文件中写入数据
  244. result = true;
  245. }
  246. #region 设定列宽
  247. if (isAutoColumnWidth)
  248. {
  249. for (int i = 0; i < columnCount; i++)
  250. {
  251. sheet.AutoSizeColumn(i);
  252. }
  253. //获取当前列的宽度,然后对比本列的长度,取最大值
  254. for (int columnNum = 0; columnNum <= columnCount; columnNum++)
  255. {
  256. int columnWidth = sheet.GetColumnWidth(columnNum) / 256;
  257. for (int rowNum = 0; rowNum <1; rowNum++)
  258. {
  259. IRow currentRow;
  260. //当前行未被使用过
  261. if (sheet.GetRow(rowNum) == null)
  262. {
  263. currentRow = sheet.CreateRow(rowNum);
  264. }
  265. else
  266. {
  267. currentRow = sheet.GetRow(rowNum);
  268. }
  269. if (currentRow.GetCell(columnNum) != null)
  270. {
  271. ICell currentCell = currentRow.GetCell(columnNum);
  272. int length = Encoding.Default.GetBytes(currentCell.ToString()).Length;
  273. if (columnWidth < length)
  274. {
  275. columnWidth = length;
  276. }
  277. }
  278. }
  279. sheet.SetColumnWidth(columnNum, columnWidth * 256);
  280. }
  281. }
  282. #endregion
  283. }
  284. return result;
  285. }
  286. catch (Exception ex)
  287. {
  288. if (fs != null)
  289. {
  290. fs.Close();
  291. }
  292. return false;
  293. }
  294. }
  295. /// <summary>
  296. /// Excel导入成Datable
  297. /// </summary>
  298. /// <param name="file">导入路径(包含文件名与扩展名)</param>
  299. /// <returns></returns>
  300. public static DataTable ExcelToTable(string file)
  301. {
  302. DataTable dt = new DataTable();
  303. IWorkbook workbook;
  304. string fileExt = Path.GetExtension(file).ToLower();
  305. using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
  306. {
  307. //XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
  308. if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(fs); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(fs); } else { workbook = null; }
  309. if (workbook == null) { return null; }
  310. ISheet sheet = workbook.GetSheetAt(0);
  311. //表头
  312. IRow header = sheet.GetRow(sheet.FirstRowNum);
  313. List<int> columns = new List<int>();
  314. for (int i = 0; i < header.LastCellNum; i++)
  315. {
  316. object obj = GetValueType(header.GetCell(i));
  317. if (obj == null || obj.ToString() == string.Empty)
  318. {
  319. dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
  320. }
  321. else
  322. dt.Columns.Add(new DataColumn(obj.ToString()));
  323. columns.Add(i);
  324. }
  325. //数据
  326. for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
  327. {
  328. DataRow dr = dt.NewRow();
  329. bool hasValue = false;
  330. foreach (int j in columns)
  331. {
  332. dr[j] = GetValueType(sheet.GetRow(i).GetCell(j));
  333. if (dr[j] != null && dr[j].ToString() != string.Empty)
  334. {
  335. hasValue = true;
  336. }
  337. }
  338. if (hasValue)
  339. {
  340. dt.Rows.Add(dr);
  341. }
  342. }
  343. }
  344. return dt;
  345. }
  346. /// <summary>
  347. /// Datable导出成Excel
  348. /// </summary>
  349. /// <param name="dt"></param>
  350. /// <param name="file">导出路径(包括文件名与扩展名)</param>
  351. public static void TableToExcel(DataTable dt, string file)
  352. {
  353. IWorkbook workbook;
  354. string fileExt = Path.GetExtension(file).ToLower();
  355. if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); }
  356. else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); }
  357. else { workbook = null; }
  358. if (workbook == null) { return; }
  359. ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);
  360. //表头
  361. IRow row = sheet.CreateRow(0);
  362. for (int i = 0; i < dt.Columns.Count; i++)
  363. {
  364. ICell cell = row.CreateCell(i);
  365. cell.SetCellValue(dt.Columns[i].ColumnName);
  366. }
  367. //数据
  368. for (int i = 0; i < dt.Rows.Count; i++)
  369. {
  370. IRow row1 = sheet.CreateRow(i + 1);
  371. for (int j = 0; j < dt.Columns.Count; j++)
  372. {
  373. ICell cell = row1.CreateCell(j);
  374. cell.SetCellValue(dt.Rows[i][j].ToString());
  375. }
  376. }
  377. //转为字节数组
  378. MemoryStream stream = new MemoryStream();
  379. workbook.Write(stream);
  380. var buf = stream.ToArray();
  381. //保存为Excel文件
  382. using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
  383. {
  384. fs.Write(buf, 0, buf.Length);
  385. fs.Flush();
  386. }
  387. }
  388. /// <summary>
  389. /// 获取单元格类型
  390. /// </summary>
  391. /// <param name="cell"></param>
  392. /// <returns></returns>
  393. private static object GetValueType(ICell cell)
  394. {
  395. if (cell == null)
  396. return null;
  397. switch (cell.CellType)
  398. {
  399. case CellType.Blank: //BLANK:
  400. return null;
  401. case CellType.Boolean: //BOOLEAN:
  402. return cell.BooleanCellValue;
  403. case CellType.Numeric: //NUMERIC:
  404. return cell.NumericCellValue;
  405. case CellType.String: //STRING:
  406. return cell.StringCellValue;
  407. case CellType.Error: //ERROR:
  408. return cell.ErrorCellValue;
  409. case CellType.Formula: //FORMULA:
  410. default:
  411. return "=" + cell.CellFormula;
  412. }
  413. }
  414. }
  415. }