zoukankan      html  css  js  c++  java
  • Excel导出---NPOI和MS两种方式

    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         }
    View Code

    MS方式(有版权的,微软要收费):

     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         public static void ExportExcel(string sheetName, Dictionary<string, int> titles, int rowSpan, int cols, System.Data.DataTable dt, bool IsSpan = true)
    10         {
    11             //0.注意:  
    12             // * Excel中形如Cells[x][y]的写法,前面的数字是列,后面的数字是行!  
    13             // * Excel中的行、列都是从1开始的,而不是0  
    14             //制作一个新的Excel文档实例  
    15             EXCEL.Application xlsApp = new EXCEL.Application();
    16             xlsApp.DisplayAlerts = false;
    17             xlsApp.Workbooks.Add(true);
    18             //设置Excel分页卡标题  
    19             xlsApp.ActiveSheet.Name = sheetName;
    20 
    21             EXCEL.Range range;
    22 
    23             //填写各列的标题行
    24             int colNum = 1;//列号
    25             int rowNum = 1;//行号
    26 
    27             int cnt = 0;
    28             foreach (var title in titles)
    29             {
    30                 xlsApp.Cells[colNum + cnt][rowNum] = title.Key;
    31                 xlsApp.Cells[colNum + cnt][rowNum].ColumnWidth = title.Value;
    32                 cnt++;
    33             }
    34 
    35             xlsApp.Rows[rowNum].Font.Name = "宋体";
    36             xlsApp.Rows[rowNum].Font.Size = 13;//设置字号  
    37             xlsApp.Rows[rowNum].Font.Bold = true;//粗体  
    38             xlsApp.Rows[rowNum].HorizontalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;//居中
    39 
    40             //填充数据
    41             int rcnt = 0;
    42             int indexNo = 1;//序号列
    43             int row;//EXCEL行号
    44             int col;//EXCEL列号
    45            
    46             for (int i = 0; i < dt.Rows.Count; i++)
    47             {
    48                 row = i + 2;
    49 
    50                 #region 设置序号
    51                 if (rcnt % rowSpan == 0)
    52                 {
    53                     xlsApp.Cells[1][row] = indexNo;
    54                     indexNo++;
    55                 }
    56                 if (IsSpan && (row - 1) % rowSpan == 0)
    57                 {
    58                     range = xlsApp.ActiveSheet.Range[xlsApp.ActiveSheet.Cells[row - (rowSpan-1), 1], xlsApp.ActiveSheet.Cells[row, 1]];
    59                     range.Merge(0);
    60                     xlsApp.ActiveSheet.Cells[row - (rowSpan - 1), 1] = indexNo - 1;
    61                 }
    62                 #endregion
    63 
    64                 for (int j = 0; j < dt.Columns.Count; j++)
    65                 {
    66                     col = j + 2;
    67                     xlsApp.Cells[col][row] = dt.Rows[i][j];//填充值
    68 
    69                     if (IsSpan && (row - 1) % rowSpan == 0 && col <= cols)
    70                     {
    71                         range = xlsApp.ActiveSheet.Range[xlsApp.ActiveSheet.Cells[row - (rowSpan - 1), col], xlsApp.ActiveSheet.Cells[row, col]];
    72                         range.Merge(0);
    73                         xlsApp.ActiveSheet.Cells[row - (rowSpan - 1), col] = dt.Rows[i - (rowSpan - 1)][j];
    74                     }
    75                 }
    76 
    77                 rcnt++;
    78             }
    79 
    80             //打开制作完毕的表格  
    81             xlsApp.Visible = true;
    82         }
    View Code

    这里介绍一个坑,如果通过AJAX导出EXCEL,浏览器无法直接下载文件。我的做法是先把文件存到服务器上,向前端ajax方法返回服务器路径。

     function openExport() {
                var Id = $("#Id").val();
                $.ajax({
                    type: 'POST',
                    url: "/XXX/ExportExcel?Id=" + Id,
                    success: function (res) {
                        if (res.type === 'E') {
                            $.hqmsg.showMsg({ msgtype: 'E', content: "导出失败" });
                        } else if (res.type === 'S') {
                            $.hqmsg.showMsg({ msgtype: 'S', content: "导出成功" });
                            var link = $('<a href="' + res.message + '" target="_blank"></a>');
                            link.get(0).click();
                        }
                    }
                });
            }

    辅助类代码:

      1 class EXCELUtilty
      2     {
      3         public static ISheet GetExcelSheet(string path,int sheetIndex)
      4         {
      5             IWorkbook book;
      6             try
      7             {
      8                 using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
      9                 {
     10                     book = WorkbookFactory.Create(file);
     11                     return book.GetSheetAt(sheetIndex);
     12                 }
     13             }
     14             catch
     15             {
     16                 return null;
     17             }
     18         }
     19 
     20         /// <summary>
     21         /// 读Excel单元格的数据
     22         /// </summary>
     23         /// <param name="cell">Excel单元格</param>
     24         /// <param name="type">列数据类型</param>
     25         /// <returns>object 单元格数据</returns>
     26         public static dynamic GetCellData(ICell cell, Type type)
     27         {
     28             var cellValue = GetCellValue(cell);
     29             if (cellValue == null)
     30             {
     31                 return DBNull.Value;
     32             }
     33 
     34             if (type.Name == "Int32")
     35             {
     36                 int intobj = 0;
     37                 if (int.TryParse(cellValue, out intobj))
     38                 {
     39                     return intobj;
     40                 }
     41                 else
     42                 {
     43                     return DBNull.Value;
     44                 }
     45             }
     46             else if (type.Name == "Decimal")
     47             {
     48                 decimal decobj = 0.0m;
     49                 if (decimal.TryParse(cellValue, out decobj))
     50                 {
     51                     return decobj;
     52                 }
     53 
     54                 return DBNull.Value;
     55             }
     56 
     57             return cellValue;
     58         }
     59         private static string GetCellValue(ICell cell)
     60         {
     61             if (cell == null)
     62                 return null;
     63             switch (cell.CellType)
     64             {
     65                 case CellType.Blank: //空数据类型 这里类型注意一下,不同版本NPOI大小写可能不一样,有的版本是Blank(首字母大写)
     66                     return null;
     67                 case CellType.Boolean: //bool类型
     68                     return cell.BooleanCellValue.ToString();
     69                 case CellType.Error:
     70                     return cell.ErrorCellValue.ToString();
     71                 case CellType.Numeric: //数字类型
     72                     if (HSSFDateUtil.IsCellDateFormatted(cell))//日期类型
     73                     {
     74                         return cell.DateCellValue.ToString();
     75                     }
     76                     else //其它数字
     77                     {
     78                         return cell.NumericCellValue.ToString();
     79                     }
     80                 case CellType.Unknown: //无法识别类型
     81                 default: //默认类型
     82                     return cell.ToString();//
     83                 case CellType.String: //string 类型
     84                     return cell.StringCellValue == null ? cell.StringCellValue : cell.StringCellValue.Trim();
     85                 case CellType.Formula: //带公式类型
     86                     try
     87                     {
     88                         IFormulaEvaluator eval = new XSSFFormulaEvaluator(cell.Sheet.Workbook);
     89                         eval.EvaluateInCell(cell);
     90                         return cell.ToString();
     91                     }
     92                     catch
     93                     {
     94                         try
     95                         {
     96                             HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(cell.Sheet.Workbook);
     97                             e.EvaluateInCell(cell);
     98                             return cell.ToString();
     99                         }
    100                         catch
    101                         {
    102                             return cell.NumericCellValue.ToString();
    103                         }
    104                     }
    105             }
    106         }
    107 
    108         public static string GetCellIdentity(int colIndex, int rowNum)
    109         {
    110             return GetCellColName(colIndex) + rowNum;
    111         }
    112 
    113         public static string GetCellColName(int colIndex)
    114         {
    115             if (colIndex < 26)
    116             {
    117                return ((char)('A' + colIndex)).ToString();
    118             }
    119             else if (colIndex <= 26 + 26 * 26)
    120             {
    121                 return ((char)('A' + (colIndex - 26) / 26)).ToString()
    122                   + ((char)('A' + (colIndex - 26) % 26)).ToString();
    123             }
    124             else
    125             {
    126                 throw new Exception("");
    127             }
    128         }
    129 
    130     }
    View Code

     导出的EXCEL文件样式:

  • 相关阅读:
    在k8s上部署第一个php应用
    在k8s中的基本概念
    kubernetes 环境搭建
    docker搭建私有仓库
    mysql导入数据乱码的解决
    代码单词
    让代码更容易读
    docker中的link
    docker基本
    解决无法将“babel”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
  • 原文地址:https://www.cnblogs.com/brainthink/p/9007512.html
Copyright © 2011-2022 走看看