NPOIExt.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. //using NPOI.HSSF.UserModel;
  2. //using NPOI.XSSF.UserModel;
  3. //using System;
  4. //using System.IO;
  5. //using System.Linq;
  6. //namespace Uninpho.Tools
  7. //{
  8. // /// <summary>
  9. // /// xls转为xlsx
  10. // /// </summary>
  11. // class NPOIExt
  12. // {
  13. // public static void ConvertToXlsx(string xlsPath, string newExcelPath)
  14. // {
  15. // using (var streamRead = new FileStream(xlsPath, FileMode.Open, FileAccess.Read))
  16. // using (var streamWrite = new FileStream(newExcelPath, FileMode.OpenOrCreate, FileAccess.Write))
  17. // {
  18. // var book = new HSSFWorkbook(streamRead);
  19. // var newBook = new HSSFWorkbook();
  20. // var copiedSheets = Enumerable.Range(0, book.NumberOfSheets).Select(i => book.CloneSheet(i));
  21. // copiedSheets.Select((sheet, index) => new { sheet, index }).ToList()
  22. // .ForEach(item => newBook.Insert(item.index, item.sheet));
  23. // newBook.Write(streamWrite);
  24. // }
  25. // #region MyRegion
  26. // //var oldWorkbook = new HSSFWorkbook(new FileStream(xlsPath, FileMode.Open));
  27. // //var oldWorkSheet = oldWorkbook.GetSheetAt(0);
  28. // //int m = 0;
  29. // //try
  30. // //{
  31. // // using (var fileStream = new FileStream(newExcelPath, FileMode.Create))
  32. // // {
  33. // // var newWorkBook = new XSSFWorkbook();
  34. // // var newWorkSheet = newWorkBook.CreateSheet("Sheet1");
  35. // // int i = 0;
  36. // // foreach (HSSFRow oldRow in oldWorkSheet)
  37. // // {
  38. // // var newRow = newWorkSheet.CreateRow(oldRow.RowNum);
  39. // // for (int ii = oldRow.FirstCellNum; ii < oldRow.Cells.Count; ii++)
  40. // // {
  41. // // m = ii;
  42. // // var newCell = newRow.CreateCell(ii);
  43. // // var ddd = oldRow.Cells[ii];
  44. // // newCell.SetCellValue( /*GetValueType()*/ddd.ToString());
  45. // // }
  46. // // }
  47. // // int sheetMergerCount = oldWorkSheet.NumMergedRegions;
  48. // // for (int me = 0; me < sheetMergerCount; me++)
  49. // // newWorkSheet.AddMergedRegion(oldWorkSheet.GetMergedRegion(me));
  50. // // newWorkBook.Write(fileStream);
  51. // // newWorkBook.Close();
  52. // // }
  53. // //}
  54. // //catch (Exception ex)
  55. // //{
  56. // // int b = m;
  57. // // throw;
  58. // //}
  59. // //oldWorkbook.Close();
  60. // //return newExcelPath;
  61. // #endregion
  62. // }
  63. // }
  64. //}
  65. using NPOI.XSSF.UserModel;
  66. using NPOI.SS.UserModel;
  67. using NPOI.SS.Util;
  68. using NPOI.HSSF.UserModel;
  69. using System.Collections.Generic;
  70. using System.Linq;
  71. using System.IO;
  72. namespace Uninpho.Tools
  73. {
  74. public static class NPOIExt
  75. {
  76. public static bool ConvertToXlsx(string xlsPath, string newExcelPath)
  77. {
  78. var streamRead = new FileStream(xlsPath, FileMode.Open, FileAccess.Read);
  79. var pReadByte = Convert(streamRead);
  80. FileStream pFileStream = null;
  81. try
  82. {
  83. pFileStream = new FileStream(newExcelPath, FileMode.OpenOrCreate);
  84. pFileStream.Write(pReadByte, 0, pReadByte.Length);
  85. }
  86. catch
  87. {
  88. return false;
  89. }
  90. finally
  91. {
  92. if (pFileStream != null)
  93. pFileStream.Close();
  94. }
  95. return true;
  96. }
  97. private static byte[] Convert(Stream sourceStream)
  98. {
  99. var source = new HSSFWorkbook(sourceStream);
  100. var destination = new XSSFWorkbook();
  101. for (int i = 0; i < source.NumberOfSheets; i++)
  102. {
  103. var xssfSheet = (XSSFSheet)destination.CreateSheet(source.GetSheetAt(i).SheetName);
  104. var hssfSheet = (HSSFSheet)source.GetSheetAt(i);
  105. CopyStyles(hssfSheet, xssfSheet);
  106. CopySheets(hssfSheet, xssfSheet);
  107. }
  108. using (var ms = new MemoryStream())
  109. {
  110. destination.Write(ms);
  111. return ms.ToArray();
  112. }
  113. }
  114. private static void CopyStyles(HSSFSheet from, XSSFSheet to)
  115. {
  116. for (short i = 0; i <= from.Workbook.NumberOfFonts; i++)
  117. {
  118. CopyFont(to.Workbook.CreateFont(), from.Workbook.GetFontAt(i));
  119. }
  120. for (short i = 0; i < from.Workbook.NumCellStyles; i++)
  121. {
  122. CopyStyle(to.Workbook.CreateCellStyle(), from.Workbook.GetCellStyleAt(i), to.Workbook, from.Workbook);
  123. }
  124. }
  125. private static void CopyFont(IFont toFront, IFont fontFrom)
  126. {
  127. toFront.Boldweight = fontFrom.Boldweight;
  128. toFront.Charset = fontFrom.Charset;
  129. toFront.Color = fontFrom.Color;
  130. toFront.FontHeightInPoints = fontFrom.FontHeightInPoints;
  131. toFront.FontName = fontFrom.FontName;
  132. toFront.IsBold = fontFrom.IsBold;
  133. toFront.IsItalic = fontFrom.IsItalic;
  134. toFront.IsStrikeout = fontFrom.IsStrikeout;
  135. //toFront.Underline = fontFrom.Underline; <- bug in npoi setter
  136. }
  137. private static void CopyStyle(ICellStyle toCellStyle, ICellStyle fromCellStyle, IWorkbook toWorkbook, IWorkbook fromWorkbook)
  138. {
  139. toCellStyle.Alignment = fromCellStyle.Alignment;
  140. toCellStyle.BorderBottom = fromCellStyle.BorderBottom;
  141. toCellStyle.BorderDiagonal = fromCellStyle.BorderDiagonal;
  142. toCellStyle.BorderDiagonalColor = fromCellStyle.BorderDiagonalColor;
  143. toCellStyle.BorderDiagonalLineStyle = fromCellStyle.BorderDiagonalLineStyle;
  144. toCellStyle.BorderLeft = fromCellStyle.BorderLeft;
  145. toCellStyle.BorderRight = fromCellStyle.BorderRight;
  146. toCellStyle.BorderTop = fromCellStyle.BorderTop;
  147. toCellStyle.BottomBorderColor = fromCellStyle.BottomBorderColor;
  148. toCellStyle.DataFormat = fromCellStyle.DataFormat;
  149. toCellStyle.FillBackgroundColor = fromCellStyle.FillBackgroundColor;
  150. toCellStyle.FillForegroundColor = fromCellStyle.FillForegroundColor;
  151. toCellStyle.FillPattern = fromCellStyle.FillPattern;
  152. toCellStyle.Indention = fromCellStyle.Indention;
  153. toCellStyle.IsHidden = fromCellStyle.IsHidden;
  154. toCellStyle.IsLocked = fromCellStyle.IsLocked;
  155. toCellStyle.LeftBorderColor = fromCellStyle.LeftBorderColor;
  156. toCellStyle.RightBorderColor = fromCellStyle.RightBorderColor;
  157. toCellStyle.Rotation = fromCellStyle.Rotation;
  158. toCellStyle.ShrinkToFit = fromCellStyle.ShrinkToFit;
  159. toCellStyle.TopBorderColor = fromCellStyle.TopBorderColor;
  160. toCellStyle.VerticalAlignment = fromCellStyle.VerticalAlignment;
  161. toCellStyle.WrapText = fromCellStyle.WrapText;
  162. toCellStyle.SetFont(toWorkbook.GetFontAt((short)(fromCellStyle.GetFont(fromWorkbook).Index + 1)));
  163. }
  164. private static void CopySheets(HSSFSheet source, XSSFSheet destination)
  165. {
  166. var maxColumnNum = 0;
  167. var mergedRegions = new List<CellRangeAddress>();
  168. var styleMap = new Dictionary<int, HSSFCellStyle>();
  169. for (int i = source.FirstRowNum; i <= source.LastRowNum; i++)
  170. {
  171. var srcRow = (HSSFRow)source.GetRow(i);
  172. var destRow = (XSSFRow)destination.CreateRow(i);
  173. if (srcRow != null)
  174. {
  175. CopyRow(source, destination, srcRow, destRow, mergedRegions);
  176. if (srcRow.LastCellNum > maxColumnNum)
  177. {
  178. maxColumnNum = srcRow.LastCellNum;
  179. }
  180. }
  181. }
  182. for (int i = 0; i <= maxColumnNum; i++)
  183. {
  184. destination.SetColumnWidth(i, source.GetColumnWidth(i));
  185. }
  186. }
  187. private static void CopyRow(HSSFSheet srcSheet, XSSFSheet destSheet, HSSFRow srcRow, XSSFRow destRow, List<CellRangeAddress> mergedRegions)
  188. {
  189. destRow.Height = srcRow.Height;
  190. for (int j = srcRow.FirstCellNum; srcRow.LastCellNum >= 0 && j <= srcRow.LastCellNum; j++)
  191. {
  192. var oldCell = (HSSFCell)srcRow.GetCell(j);
  193. var newCell = (XSSFCell)destRow.GetCell(j);
  194. if (oldCell != null)
  195. {
  196. if (newCell == null)
  197. {
  198. newCell = (XSSFCell)destRow.CreateCell(j);
  199. }
  200. CopyCell(oldCell, newCell);
  201. var mergedRegion = GetMergedRegion(srcSheet, srcRow.RowNum,
  202. (short)oldCell.ColumnIndex);
  203. if (mergedRegion != null)
  204. {
  205. var newMergedRegion = new CellRangeAddress(mergedRegion.FirstRow,
  206. mergedRegion.LastRow, mergedRegion.FirstColumn, mergedRegion.LastColumn);
  207. if (IsNewMergedRegion(newMergedRegion, mergedRegions))
  208. {
  209. mergedRegions.Add(newMergedRegion);
  210. destSheet.AddMergedRegion(newMergedRegion);
  211. }
  212. }
  213. }
  214. }
  215. }
  216. private static void CopyCell(HSSFCell oldCell, XSSFCell newCell)
  217. {
  218. CopyCellStyle(oldCell, newCell);
  219. CopyCellValue(oldCell, newCell);
  220. }
  221. private static void CopyCellValue(HSSFCell oldCell, XSSFCell newCell)
  222. {
  223. switch (oldCell.CellType)
  224. {
  225. case CellType.String:
  226. newCell.SetCellValue(oldCell.StringCellValue);
  227. break;
  228. case CellType.Numeric:
  229. newCell.SetCellValue(oldCell.NumericCellValue);
  230. break;
  231. case CellType.Blank:
  232. newCell.SetCellType(CellType.Blank);
  233. break;
  234. case CellType.Boolean:
  235. newCell.SetCellValue(oldCell.BooleanCellValue);
  236. break;
  237. case CellType.Error:
  238. newCell.SetCellErrorValue(oldCell.ErrorCellValue);
  239. break;
  240. case CellType.Formula:
  241. newCell.SetCellFormula(oldCell.CellFormula);
  242. break;
  243. default:
  244. break;
  245. }
  246. }
  247. private static void CopyCellStyle(HSSFCell oldCell, XSSFCell newCell)
  248. {
  249. if (oldCell.CellStyle == null) return;
  250. newCell.CellStyle = newCell.Sheet.Workbook.GetCellStyleAt((short)(oldCell.CellStyle.Index + 1));
  251. }
  252. private static CellRangeAddress GetMergedRegion(HSSFSheet sheet, int rowNum, short cellNum)
  253. {
  254. for (var i = 0; i < sheet.NumMergedRegions; i++)
  255. {
  256. var merged = sheet.GetMergedRegion(i);
  257. if (merged.IsInRange(rowNum, cellNum))
  258. {
  259. return merged;
  260. }
  261. }
  262. return null;
  263. }
  264. private static bool IsNewMergedRegion(CellRangeAddress newMergedRegion,
  265. List<CellRangeAddress> mergedRegions)
  266. {
  267. return !mergedRegions.Any(r =>
  268. r.FirstColumn == newMergedRegion.FirstColumn &&
  269. r.LastColumn == newMergedRegion.LastColumn &&
  270. r.FirstRow == newMergedRegion.FirstRow &&
  271. r.LastRow == newMergedRegion.LastRow);
  272. }
  273. }
  274. }