使用第三類包:NPOI
介紹
Github地址:https://github.com/tonyqus/npoi,Java POI項目的.NET版。
通過它可以在沒有安裝Office軟件的情況下,快速的讀寫Office文檔。
特點:
- 跨平台
- 支持Office2003及以后所有版本
- 支持Excel的大部分特性
- 開源
- 實例豐富
- 維護者是中國人,所以交流應該問題不大
Nuget包下載:https://www.nuget.org/packages/NPOI/
實踐一:讀取Excel數據
注意:行列開始索引為0,沒有數據的Cell為NULL。
/// <summary> /// 讀取Excel所有單元格數據 /// </summary> /// <param name="path">文件路徑</param> /// <param name="sheetName">Sheet名</param> /// <param name="startRow">讀取開始行位置</param> /// <param name="columns">讀取列表</param> /// <returns>單元格列表</returns> public static async Task<IList<ICell>> ReadAllCellsAsync(string path, string sheetName, int startRow = 1, IList<int> columns = null) { var ret = new List<ICell>(); await Task.Factory.StartNew(() => { using (var file = new FileStream(path, FileMode.Open, FileAccess.Read)) { var book = WorkbookFactory.Create(file); var sheet = book?.GetSheet(sheetName); if (sheet != null) { for (int row = startRow - 1; row <= sheet.LastRowNum; row++) { var rowValue = sheet.GetRow(row); if (rowValue == null) { continue; } if (columns == null || columns?.Count <= 0) { columns = Enumerable.Range(1, rowValue.LastCellNum + 1).ToList(); } foreach (int col in columns) { var cell = rowValue.GetCell(col - 1); if (cell == null) { continue; } ret.Add(cell); } } } book?.Close(); } }); return ret; }
取Cell值擴展函數
public static string GetCellValue(this ICell cell) { if (cell == null) { return string.Empty; } switch (cell.CellType) { case CellType.Formula: case CellType.String: return cell.StringCellValue; case CellType.Numeric: if (DateUtil.IsCellDateFormatted(cell)) { return cell.DateCellValue.ToString(); } else { return cell.NumericCellValue.ToString(); } case CellType.Boolean: return cell.BooleanCellValue.ToString(); default: return string.Empty; } }
實踐二:寫Excel數據
1,創建Book。
public static IWorkbook CreateBook(this string path) { IWorkbook book; string extension = Path.GetExtension(path); // HSSF => Microsoft Excel(xls形式)(excel 97-2003) // XSSF => Office Open XML Workbook形式(xlsx形式)(excel 2007+) if (extension == ".xls") { book = new HSSFWorkbook(); } else { book = new XSSFWorkbook(); } return book; }
2,創建Sheet。
var sheet = book.CreateSheet(“test”);
3,創建單元格。(為了不區分HSSHyperLink與XSSFHyperLink直接使用了設置函數形式)
ICellStyle hlink_style = book.CreateCellStyle(); IFont hlink_font = book.CreateFont(); hlink_font.Underline = FontUnderlineType.Single; hlink_font.Color = IndexedColors.Blue.Index; hlink_style.SetFont(hlink_font); var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex); var cell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex); cell.SetCellValue("test"); // OR hyperlink var linkcell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex); linkcell.SetCellFormula($"hyperlink(\"{linkValue}\",\"{value}\")"); linkcell.CellStyle = hlink_style;
4,創建合並單元格。
sheet.AddMergedRegion(new CellRangeAddress(rowStart, rowEnd, columnStart, columnEnd));
5,創建單元格數據入力規則。
public static void WriteValidation(this ISheet sheet, int rowStart, int rowEnd, int columnStart, int columnEnd, string[] values) { var addressList = new CellRangeAddressList(rowStart, rowEnd, columnStart, columnEnd); var helper = sheet.GetDataValidationHelper(); var dataValidation = helper.CreateValidation(helper.CreateExplicitListConstraint(values), addressList); if (dataValidation is XSSFDataValidation) { dataValidation.SuppressDropDownArrow = true; dataValidation.ShowErrorBox = true; } else { dataValidation.SuppressDropDownArrow = false; } dataValidation.EmptyCellAllowed = true; dataValidation.ShowPromptBox = true; sheet.AddValidationData(dataValidation); }
6,創建過濾器。
sheet.SetAutoFilter(new CellRangeAddress(row + 1, row + 1, 0, col - 1));
7,創建自動調整寬度。
for (int i = 0; i <= col; i++) { sheet.AutoSizeColumn(i, true); }
8,單元格格式設置。
注意:如果所有單元格使用同一個ICellStyle實例,那CellStyle對象一樣。
var commonFont = book.CreateFont(); commonFont.Color = IndexedColors.Black.Index; commonFont.FontHeightInPoints = 12; var Common= book.CreateCellStyle(); Common.SetFont(commonFont); Common.BorderBottom = BorderStyle.Thin; Common.BorderLeft = BorderStyle.Thin; Common.BorderRight = BorderStyle.Thin; Common.BorderTop = BorderStyle.Thin; Common.WrapText = true; Common.Alignment = HorizontalAlignment.Left; Common.VerticalAlignment = VerticalAlignment.Center; var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex); var cell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex); cell.CellStyle = Common;
9,單元格部分文字顏色設置。
int rowIndex = 10; int columnIndex = 5; var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex); var cell = row.GetCell(columnIndex) ?? row.CreateCell(columnIndex); IRichTextString richText; if (sheet is HSSFSheet) { richText = new HSSFRichTextString("Microsoft OfficeTM"); } else { richText = new XSSFRichTextString("Microsoft OfficeTM"); } //apply font to "Microsoft Office" IFont redFont = workbook.CreateFont(); redFont.FontHeightInPoints = 12; redFont.Color = IndexedColors.Red.Index; richText.ApplyFont(0, 16, redFont); //apply font to "TM" IFont blueFont = workbook.CreateFont(); blueFont.TypeOffset = FontSuperScript.Super; blueFont.IsItalic = true; blueFont.Color = IndexedColors.Blue.Index; blueFont.FontHeightInPoints = 12; richText.ApplyFont(16, 18, blueFont); var style = workbook.CreateCellStyle(); style.BorderBottom = BorderStyle.Thin; style.BorderLeft = BorderStyle.Thin; style.BorderRight = BorderStyle.Thin; style.BorderTop = BorderStyle.Thin; // 解決字體大小不一樣問題 richText.ApplyFont(style.FontIndex); cell.SetCellValue(richText); cell.CellStyle = style;
實行結果:
這樣通過NPOI基本的Excel操作就沒問題了。