NPOI方式(NPOI开源免费):
1 /// <summary> 2 /// 导出Excel文件 3 /// </summary> 4 /// <param name="sheetName"></param> 5 /// <param name="titles">EXCEL表格表头</param> 6 /// <param name="rowSpan">要合并的行数</param> 7 /// <param name="cols">需要合并的左侧列</param> 8 /// <param name="dt">数据表</param> 9 /// <param name="path">保存路径</param> 10 /// <param name="IsSpan">是否需要合并</param> 11 /// <param name="IsFormula">是否需要导出公式</param> 12 public static bool ExportExcelNPOI(string sheetName, List<Tuple<string, int, Type>> titles, int rowSpan, int cols, System.Data.DataTable dt, string path, bool IsSpan = true,bool IsFormula=false) 13 { 14 try 15 { 16 IWorkbook wb = new XSSFWorkbook(); 17 ISheet sheet = wb.CreateSheet(sheetName); //创建工作表 18 IRow row_Title = sheet.CreateRow(0); //创建列头行 19 row_Title.HeightInPoints = 19.5F; //设置列头行高 20 21 IDataFormat dataformat = wb.CreateDataFormat();//用于格式化单元格内容 22 23 #region 设置列头单元格样式 24 ICellStyle cs_Title = wb.CreateCellStyle(); //创建字符串列头样式 25 cs_Title.Alignment = HorizontalAlignment.Center; //水平居中 26 cs_Title.VerticalAlignment = VerticalAlignment.Center; //垂直居中 27 IFont cs_Title_Font = wb.CreateFont(); //创建字体 28 cs_Title_Font.IsBold = true; //字体加粗 29 cs_Title_Font.FontHeightInPoints = 12; //字体大小 30 cs_Title.SetFont(cs_Title_Font); //将字体绑定到样式 31 32 ICellStyle cs_Date_Title = wb.CreateCellStyle(); 33 cs_Date_Title.CloneStyleFrom(cs_Title); 34 cs_Date_Title.DataFormat = dataformat.GetFormat("yyyy/M/d"); 35 #endregion 36 37 #region 填充列头 38 ICell cell_Title; 39 int cnt = 0; 40 foreach (var title in titles) 41 { 42 cell_Title = row_Title.CreateCell(cnt); //创建单元格 43 44 if (title.Item3 == typeof(DateTime)) 45 { 46 cell_Title.CellStyle = cs_Date_Title; //将样式绑定到单元格 47 cell_Title.SetCellValue(DateTime.Parse(title.Item1)); 48 } 49 else if (title.Item3 == typeof(int)) 50 { 51 cell_Title.CellStyle = cs_Title; //将样式绑定到单元格 52 cell_Title.SetCellValue(int.Parse(title.Item1)); 53 } 54 else 55 { 56 cell_Title.CellStyle = cs_Title; 57 cell_Title.SetCellValue(title.Item1); 58 } 59 60 sheet.SetColumnWidth(cnt, title.Item2);//设置列宽 61 62 cnt++; 63 } 64 #endregion 65 66 #region 填充数据 67 List<int> valueTypeColNo = new List<int>();//除日期列和总计列之外其它值类型列的列号 68 if (dt.Columns.Contains("Inventory")) 69 { 70 valueTypeColNo.Add(dt.Columns["Inventory"].Ordinal); 71 } 72 73 int indexNo = 1;//序号 74 int dataRowNum = 0;//DataTalbe数据行行号 75 int excelRowNum = 0;//Excel数据行行号 76 #region 计算公式列名 77 string startCol, endCol; 78 string inventoryCol, demandCol, commitCol; 79 #endregion 80 foreach (DataRow row in dt.Rows) 81 { 82 excelRowNum = dataRowNum + 1; 83 84 #region 设置内容单元格样式 85 ICellStyle cs_Content = wb.CreateCellStyle(); //创建单元格样式 86 cs_Content.Alignment = HorizontalAlignment.Center; //水平居中 87 cs_Content.VerticalAlignment = VerticalAlignment.Center; //垂直居中 88 89 90 ICellStyle cs_Content_Date = wb.CreateCellStyle(); 91 cs_Content_Date.CloneStyleFrom(cs_Content); 92 cs_Content_Date.DataFormat = dataformat.GetFormat("yyyy/M/d"); 93 #endregion 94 95 IRow row_Content = sheet.CreateRow(excelRowNum); //创建数据行 96 row_Content.HeightInPoints = 16; 97 98 #region 设置序号 99 ICell cell_IndexNo = row_Content.CreateCell(0); //序号列 100 cell_IndexNo.CellStyle = cs_Content; 101 102 if (dataRowNum % rowSpan == 0) 103 { 104 cell_IndexNo.SetCellValue(indexNo); 105 indexNo++; 106 } 107 if (IsSpan && excelRowNum % rowSpan == 0)//合并单元格 108 { 109 sheet.AddMergedRegion(new CellRangeAddress(excelRowNum - (rowSpan - 1), excelRowNum, 0, 0)); 110 } 111 #endregion 112 113 for (int j = 0; j < dt.Columns.Count; j++) 114 { 115 ICell cell_Conent = row_Content.CreateCell(j + 1); //创建单元格 116 cell_Conent.CellStyle = cs_Content; 117 118 if (row[j] == DBNull.Value) 119 { 120 cell_Conent.SetCellValue(string.Empty); 121 } 122 else 123 { 124 if (row[j].GetType() == typeof(int)) 125 { 126 cell_Conent.SetCellValue(int.Parse(row[j].ToString())); 127 } 128 else if (row[j].GetType() == typeof(DateTime)) 129 { 130 cell_Conent.CellStyle = cs_Content_Date; 131 cell_Conent.SetCellValue(DateTime.Parse(row[j].ToString())); 132 } 133 else 134 { 135 cell_Conent.SetCellValue(row[j].ToString()); 136 } 137 } 138 139 if (IsSpan && excelRowNum % rowSpan == 0 && j < cols - 1)//合并单元格 140 { 141 sheet.AddMergedRegion(new CellRangeAddress(excelRowNum - (rowSpan - 1), excelRowNum, j + 1, j + 1)); 142 } 143 144 #region 导出公式 145 if (IsFormula) 146 { 147 if (j == dt.Columns.Count - 1)//最后一列求和 148 { 149 startCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex - (dt.Columns.Count - cols - 1), excelRowNum + 1); 150 endCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex - 1, excelRowNum + 1); 151 cell_Conent.SetCellFormula(string.Format("sum({0}:{1})", startCol, endCol)); 152 } 153 154 if (excelRowNum % rowSpan == 0 && j != dt.Columns.Count - 1) 155 { 156 if (j == cols)//第一个日期列 157 { 158 inventoryCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex - 2, excelRowNum - rowSpan + 2); 159 demandCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex, excelRowNum - rowSpan + 2); 160 commitCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex, excelRowNum - rowSpan + 3); 161 cell_Conent.SetCellFormula(string.Format("{0}+{1}-{2}", inventoryCol, commitCol, demandCol)); 162 } 163 else if (j > cols) 164 { 165 inventoryCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex - 1, excelRowNum + 1); 166 demandCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex, excelRowNum - rowSpan + 2); 167 commitCol = EXCELUtilty.GetCellIdentity(cell_Conent.ColumnIndex, excelRowNum - rowSpan + 3); 168 cell_Conent.SetCellFormula(string.Format("{0}+{1}-{2}", inventoryCol, commitCol, demandCol)); 169 } 170 171 } 172 173 } 174 #endregion 175 } 176 177 dataRowNum++; 178 } 179 180 sheet.ForceFormulaRecalculation = true;//激活公式 181 #endregion 182 183 using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write)) 184 { 185 wb.Write(file); 186 } 187 188 return true; 189 } 190 catch 191 { 192 return false; 193 } 194 }