ExportDgvToExcel.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  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.Diagnostics;
  8. using System.IO;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Windows.Forms;
  12. namespace WWPipeLine.Commons
  13. {
  14. public class ExportDgvToExcel
  15. {
  16. /// <summary>
  17. /// CANCELRESULTSTRING = "Cancel"
  18. /// </summary>
  19. public static readonly string CANCELRESULTSTRING = "Cancel";
  20. public static string ExportExcel(List<DataGridView> dgvs)
  21. {
  22. if (dgvs.Count == 0) { return ("内容为空!"); }
  23. string saveFileName = "";
  24. SaveFileDialog sfd = new SaveFileDialog
  25. {
  26. DefaultExt = "xlsx",
  27. Filter = "Excel文件(*.xlsx)|*.xlsx",
  28. RestoreDirectory = true,
  29. Title = "Excel文件保存路径"
  30. };
  31. if (sfd.ShowDialog() == DialogResult.Cancel) return CANCELRESULTSTRING;
  32. saveFileName = sfd.FileName;
  33. if (!CheckFiles(saveFileName)) return "文件被占用,请关闭文件";
  34. MemoryStream ms = new MemoryStream();
  35. XSSFWorkbook workbook = new XSSFWorkbook();
  36. if (workbook == null) return "生成IWorkbook失败";
  37. //设置单元格样式
  38. ICellStyle cellStyle = workbook.CreateCellStyle();
  39. //水平居中对齐和垂直居中对齐
  40. cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
  41. cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
  42. //设置字体
  43. IFont font = workbook.CreateFont();
  44. font.FontName = "雅黑";//字体名称
  45. font.FontHeightInPoints = 12;//字号
  46. font.Color = NPOI.HSSF.Util.HSSFColor.Black.Index;//字体颜色
  47. cellStyle.SetFont(font);
  48. foreach (DataGridView dgv in dgvs.ToArray())
  49. {
  50. if (dgv.Rows.Count > 1000000) { return ("行数超过Excel限制!"); }
  51. string sheetName = "S" + DateTime.Now.Ticks;
  52. if (dgv.Tag != null)
  53. sheetName = dgv.Tag.ToString();
  54. ISheet sheet = workbook.CreateSheet(sheetName);
  55. //添加列名
  56. IRow headRow = sheet.CreateRow(0);
  57. var cIndex = 0;
  58. Dictionary<int, int> columnsVisiable = new Dictionary<int, int>();
  59. foreach (DataGridViewColumn column in dgv.Columns)
  60. {
  61. if (!column.Visible) continue;
  62. headRow.CreateCell(cIndex).SetCellValue(column.HeaderText);
  63. headRow.GetCell(cIndex).CellStyle = cellStyle;
  64. columnsVisiable.Add(cIndex, dgv.Columns.IndexOf(column));
  65. cIndex++;
  66. }
  67. //根据类型写入内容
  68. for (int rowNum = 0; rowNum < dgv.Rows.Count; rowNum++)
  69. {
  70. //跳过第一行,第一行为列名
  71. IRow dataRow = sheet.CreateRow(rowNum + 1);
  72. foreach (int columnIndex in columnsVisiable.Keys)
  73. {
  74. int columnNum = columnsVisiable[columnIndex];
  75. ICell cell = dataRow.CreateCell(columnIndex);
  76. if (dgv.Rows[rowNum].Cells[columnNum].Value == null)
  77. {
  78. cell.SetCellType(CellType.Blank); continue;
  79. }
  80. if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Int32"))
  81. {
  82. cell.SetCellValue(Convert.ToInt32(dgv.Rows[rowNum].Cells[columnNum].Value));
  83. }
  84. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.String"))
  85. {
  86. cell.SetCellValue(dgv.Rows[rowNum].Cells[columnNum].Value.ToString());
  87. }
  88. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Single"))
  89. {
  90. cell.SetCellValue(Convert.ToSingle(dgv.Rows[rowNum].Cells[columnNum].Value));
  91. }
  92. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Double"))
  93. {
  94. cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
  95. }
  96. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Decimal"))
  97. {
  98. cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
  99. }
  100. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DateTime"))
  101. {
  102. cell.SetCellValue(Convert.ToDateTime(dgv.Rows[rowNum].Cells[columnNum].Value).ToString("yyyy-MM-dd"));
  103. }
  104. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DBNull"))
  105. {
  106. cell.SetCellValue("");
  107. }
  108. //单元格样式
  109. dataRow.GetCell(columnIndex).CellStyle = cellStyle;
  110. }
  111. }
  112. }
  113. if (!ms.CanRead) return string.Empty;
  114. //保存为Excel文件
  115. workbook.Write(ms);
  116. using (FileStream file = new FileStream(saveFileName, FileMode.Create))
  117. {
  118. workbook.Write(file);
  119. file.Close();
  120. }
  121. ms.Close();
  122. ms.Dispose();
  123. LogHelper.Info("导出成功");
  124. return string.Empty;
  125. }
  126. public static string ExportExcel(DataGridView dgv)
  127. {
  128. if (dgv.Rows.Count == 0) { return ("内容为空!"); }
  129. if (dgv.Rows.Count > 1000000) { return ("行数超过Excel限制!"); }
  130. string saveFileName = "";
  131. SaveFileDialog sfd = new SaveFileDialog
  132. {
  133. DefaultExt = "xlsx",
  134. Filter = "Excel文件(*.xlsx)|*.xlsx",
  135. RestoreDirectory = true,
  136. Title = "Excel文件保存路径"
  137. };
  138. if (sfd.ShowDialog() == DialogResult.Cancel) return CANCELRESULTSTRING;
  139. saveFileName = sfd.FileName;
  140. if (!CheckFiles(saveFileName)) return "文件被占用,请关闭文件";
  141. MemoryStream ms = new MemoryStream();
  142. XSSFWorkbook workbook = new XSSFWorkbook();
  143. if (workbook == null) return "生成IWorkbook失败";
  144. //设置单元格样式
  145. ICellStyle cellStyle = workbook.CreateCellStyle();
  146. //水平居中对齐和垂直居中对齐
  147. cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
  148. cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
  149. //设置字体
  150. IFont font = workbook.CreateFont();
  151. font.FontName = "雅黑";//字体名称
  152. font.FontHeightInPoints = 12;//字号
  153. font.Color = NPOI.HSSF.Util.HSSFColor.Black.Index;//字体颜色
  154. cellStyle.SetFont(font);
  155. string sheetName = "S" + DateTime.Now.Ticks;
  156. if (dgv.Tag != null)
  157. sheetName = dgv.Tag.ToString();
  158. ISheet sheet = workbook.CreateSheet(sheetName);
  159. //添加列名
  160. IRow headRow = sheet.CreateRow(0);
  161. var cIndex = 0;
  162. Dictionary<int, int> columnsVisiable = new Dictionary<int, int>();
  163. foreach (DataGridViewColumn column in dgv.Columns)
  164. {
  165. if (!column.Visible) continue;
  166. headRow.CreateCell(cIndex).SetCellValue(column.HeaderText);
  167. headRow.GetCell(cIndex).CellStyle = cellStyle;
  168. columnsVisiable.Add(cIndex, dgv.Columns.IndexOf(column));
  169. cIndex++;
  170. }
  171. //根据类型写入内容
  172. for (int rowNum = 0; rowNum < dgv.Rows.Count; rowNum++)
  173. {
  174. //跳过第一行,第一行为列名
  175. IRow dataRow = sheet.CreateRow(rowNum + 1);
  176. foreach (int columnIndex in columnsVisiable.Keys)
  177. {
  178. int columnNum = columnsVisiable[columnIndex];
  179. ICell cell = dataRow.CreateCell(columnIndex);
  180. if (dgv.Rows[rowNum].Cells[columnNum].Value == null)
  181. {
  182. cell.SetCellType(CellType.Blank); continue;
  183. }
  184. if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Int32"))
  185. {
  186. cell.SetCellValue(Convert.ToInt32(dgv.Rows[rowNum].Cells[columnNum].Value));
  187. }
  188. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.String"))
  189. {
  190. cell.SetCellValue(dgv.Rows[rowNum].Cells[columnNum].Value.ToString());
  191. }
  192. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Single"))
  193. {
  194. cell.SetCellValue(Convert.ToSingle(dgv.Rows[rowNum].Cells[columnNum].Value));
  195. }
  196. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Double"))
  197. {
  198. cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
  199. }
  200. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Decimal"))
  201. {
  202. cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
  203. }
  204. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DateTime"))
  205. {
  206. cell.SetCellValue(Convert.ToDateTime(dgv.Rows[rowNum].Cells[columnNum].Value).ToString("yyyy-MM-dd"));
  207. }
  208. else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DBNull"))
  209. {
  210. cell.SetCellValue("");
  211. }
  212. //单元格样式
  213. dataRow.GetCell(columnIndex).CellStyle = cellStyle;
  214. }
  215. }
  216. if (!ms.CanRead) return string.Empty;
  217. //保存为Excel文件
  218. workbook.Write(ms);
  219. using (FileStream file = new FileStream(saveFileName, FileMode.Create))
  220. {
  221. workbook.Write(file);
  222. file.Close();
  223. }
  224. ms.Close();
  225. ms.Dispose();
  226. LogHelper.Info("导出成功");
  227. return string.Empty;
  228. }
  229. //public static string ExportExcel(string fileName, DataGridView dgv, string fontname = "雅黑", short fontsize = 12)
  230. //{
  231. // //判断datagridview中内容是否为空
  232. // if (dgv.Rows.Count == 0) { return ("DataGridView中内容为空!"); }
  233. // //保存文件
  234. // string saveFileName = "";
  235. // SaveFileDialog sfd = new SaveFileDialog
  236. // {
  237. // DefaultExt = "xls",
  238. // Filter = "Excel文件(*.xls)|*.xls|Excel文件(*.xlsx)|*.xlsx",
  239. // RestoreDirectory = true,
  240. // Title = "Excel文件保存路径",
  241. // FileName = fileName
  242. // };
  243. // if (sfd.ShowDialog() == DialogResult.OK)
  244. // {
  245. // saveFileName = sfd.FileName;
  246. // }
  247. // else
  248. // {
  249. // //ms.Close();
  250. // //ms.Dispose();
  251. // return CANCELRESULTSTRING;
  252. // }
  253. // //if (string.IsNullOrEmpty(fileName))
  254. // //{}
  255. // //else
  256. // //{
  257. // // saveFileName = fileName;
  258. // //}
  259. // //**程序开始计时**//
  260. // Stopwatch sw = new Stopwatch();
  261. // sw.Start();
  262. // //检测文件是否被占用
  263. // if (!CheckFiles(saveFileName))
  264. // {
  265. // //ms.Close();
  266. // //ms.Dispose();
  267. // return "文件被占用,请关闭文件";
  268. // }
  269. // MemoryStream ms = new MemoryStream(); //MemoryStream
  270. // //*** 根据扩展名xls和xlsx来创建对象
  271. // IWorkbook workbook;
  272. // ISheet sheet;
  273. // string fileExt = Path.GetExtension(saveFileName).ToLower();
  274. // if (fileExt == ".xlsx")
  275. // {
  276. // workbook = new XSSFWorkbook();
  277. // }
  278. // else
  279. // {
  280. // workbook = new HSSFWorkbook();
  281. // }
  282. // //***
  283. // //创建Sheet
  284. // if (workbook == null) return "未知错误";
  285. // sheet = workbook.CreateSheet("Sheet1");//Sheet的名称
  286. // //设置单元格样式
  287. // ICellStyle cellStyle = workbook.CreateCellStyle();
  288. // //水平居中对齐和垂直居中对齐
  289. // cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
  290. // cellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;
  291. // //设置字体
  292. // IFont font = workbook.CreateFont();
  293. // font.FontName = fontname;//字体名称
  294. // font.FontHeightInPoints = fontsize;//字号
  295. // font.Color = NPOI.HSSF.Util.HSSFColor.Black.Index;//字体颜色
  296. // cellStyle.SetFont(font);
  297. // //添加列名
  298. // IRow headRow = sheet.CreateRow(0);
  299. // var cIndex = 0;
  300. // Dictionary<int, int> columnsVisiable = new Dictionary<int, int>();
  301. // foreach (DataGridViewColumn column in dgv.Columns)
  302. // {
  303. // if (!column.Visible) continue;
  304. // headRow.CreateCell(cIndex).SetCellValue(column.HeaderText);
  305. // headRow.GetCell(cIndex).CellStyle = cellStyle;
  306. // columnsVisiable.Add(cIndex, dgv.Columns.IndexOf(column));
  307. // cIndex++;
  308. // }
  309. // //根据类型写入内容
  310. // for (int rowNum = 0; rowNum < dgv.Rows.Count; rowNum++)
  311. // {
  312. // ///跳过第一行,第一行为列名
  313. // IRow dataRow = sheet.CreateRow(rowNum + 1);
  314. // foreach (int columnIndex in columnsVisiable.Keys)
  315. // {
  316. // int columnNum = columnsVisiable[columnIndex];
  317. // int columnWidth = sheet.GetColumnWidth(columnNum) / 256; //列宽
  318. // //隐藏行列不导出
  319. // if (dgv.Rows[rowNum].Visible == true && dgv.Columns[columnNum].Visible == true)
  320. // {
  321. // //防止行列超出Excel限制
  322. // if (fileExt == ".xls")
  323. // {
  324. // //03版Excel最大行数是65536行,最大列数是256列
  325. // if (rowNum > 65536)
  326. // {
  327. // return ("行数超过Excel限制!");
  328. // }
  329. // if (columnNum > 256)
  330. // {
  331. // return ("列数超过Excel限制!");
  332. // }
  333. // }
  334. // else if (fileExt == ".xlsx")
  335. // {
  336. // //07版Excel最大行数是1048576行,最大列数是16384列
  337. // if (rowNum > 1048576)
  338. // {
  339. // return ("行数超过Excel限制!");
  340. // }
  341. // if (columnNum > 16384)
  342. // {
  343. // return ("列数超过Excel限制!");
  344. // }
  345. // }
  346. // ICell cell = dataRow.CreateCell(columnIndex);
  347. // if (dgv.Rows[rowNum].Cells[columnNum].Value == null)
  348. // {
  349. // cell.SetCellType(CellType.Blank);
  350. // }
  351. // else
  352. // {
  353. // if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Int32"))
  354. // {
  355. // cell.SetCellValue(Convert.ToInt32(dgv.Rows[rowNum].Cells[columnNum].Value));
  356. // }
  357. // else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.String"))
  358. // {
  359. // cell.SetCellValue(dgv.Rows[rowNum].Cells[columnNum].Value.ToString());
  360. // }
  361. // else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Single"))
  362. // {
  363. // cell.SetCellValue(Convert.ToSingle(dgv.Rows[rowNum].Cells[columnNum].Value));
  364. // }
  365. // else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Double"))
  366. // {
  367. // cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
  368. // }
  369. // else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.Decimal"))
  370. // {
  371. // cell.SetCellValue(Convert.ToDouble(dgv.Rows[rowNum].Cells[columnNum].Value));
  372. // }
  373. // else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DateTime"))
  374. // {
  375. // cell.SetCellValue(Convert.ToDateTime(dgv.Rows[rowNum].Cells[columnNum].Value).ToString("yyyy-MM-dd"));
  376. // }
  377. // else if (dgv.Rows[rowNum].Cells[columnNum].ValueType.FullName.Contains("System.DBNull"))
  378. // {
  379. // cell.SetCellValue("");
  380. // }
  381. // }
  382. // //设置列宽
  383. // IRow currentRow;
  384. // if (sheet.GetRow(rowNum) == null)
  385. // {
  386. // currentRow = sheet.CreateRow(rowNum);
  387. // }
  388. // else
  389. // {
  390. // currentRow = sheet.GetRow(rowNum);
  391. // }
  392. // if (currentRow.GetCell(columnNum) != null)
  393. // {
  394. // ICell currentCell = currentRow.GetCell(columnNum);
  395. // int length = Encoding.Default.GetBytes(currentCell.ToString()).Length;
  396. // if (columnWidth < length)
  397. // {
  398. // columnWidth = length + 10; //设置列宽数值
  399. // }
  400. // }
  401. // sheet.SetColumnWidth(columnNum, columnWidth * 256);
  402. // //单元格样式
  403. // dataRow.GetCell(columnIndex).CellStyle = cellStyle;
  404. // }
  405. // }
  406. // }
  407. // if (!ms.CanRead) return string.Empty;
  408. // //保存为Excel文件
  409. // workbook.Write(ms);
  410. // FileStream file = new FileStream(saveFileName, FileMode.Create);
  411. // workbook.Write(file);
  412. // file.Close();
  413. // ms.Close();
  414. // ms.Dispose();
  415. // //**程序结束计时**//
  416. // sw.Stop();
  417. // double totalTime = sw.ElapsedMilliseconds / 1000.0;
  418. // LogHelper.Info(fileName + " 导出成功 耗时" + totalTime + "s");
  419. // return string.Empty;
  420. //}
  421. #region 检测文件是否被占用
  422. /// <summary>
  423. /// 判定文件是否打开
  424. /// </summary>
  425. [DllImport("kernel32.dll")]
  426. public static extern IntPtr Lopen(string lpPathName, int iReadWrite);
  427. [DllImport("kernel32.dll")]
  428. public static extern bool CloseHandle(IntPtr hObject);
  429. public const int OF_READWRITE = 2;
  430. public const int OF_SHARE_DENY_NONE = 0x40;
  431. public static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
  432. /// <summary>
  433. /// 检测文件被占用
  434. /// </summary>
  435. /// <param name="FileNames">要检测的文件路径</param>
  436. /// <returns></returns>
  437. public static bool CheckFiles(string FileNames)
  438. {
  439. if (!File.Exists(FileNames)) return true;
  440. try
  441. {
  442. IntPtr vHandle = Lopen(FileNames, OF_READWRITE | OF_SHARE_DENY_NONE);
  443. if (vHandle == HFILE_ERROR)//文件被占用
  444. return false;
  445. //文件没被占用
  446. CloseHandle(vHandle);
  447. }
  448. catch { return false; }
  449. return true;
  450. }
  451. #endregion
  452. }
  453. }