C# 後台生成Excel并下載至本地(自定義表格樣式、单元格自適應寬度)

  1 [HttpGet]
  2 public virtual ActionResult ExportExcel(string guid)
  3 {
  4     //1.取出緩存
  5     DataTable dtTemp = (DataTable)Cache.GetCache(guid);
  6     //2. 取得實際數據
  7     DataTable dtDetail = new DataTable("detailDt");
  8     ManageLib manageLib = new ManageLib();
  9     manageLib.CreateListTable(dtTemp, true, false, out dtDetail);
 10 
 11     //创建Excel文件的对象
 12     NPOI.HSSF.UserModel.HSSFWorkbook workBook = new NPOI.HSSF.UserModel.HSSFWorkbook();
 13     //添加一個sheet
 14     NPOI.SS.UserModel.ISheet sheet1 = workBook.CreateSheet("sheet1");
 15 
 16 
 17     //添加頭標題
 18     NPOI.SS.UserModel.IRow row1 = sheet1.CreateRow(0);
 19     ICell cell = row1.CreateCell(0);
 20     cell.SetCellValue("標題");
 21     //1.1 設置標題屬性
 22     {
 23         ICellStyle style = workBook.CreateCellStyle();
 24         //设置单元格的样式:水平对齐居中
 25         style.Alignment = HorizontalAlignment.Center;
 26         //設置單元格的樣式: 上下居中
 27         style.VerticalAlignment = VerticalAlignment.Center;
 28         //新建一个字体样式对象
 29         IFont font = workBook.CreateFont();
 30         //设置字体加粗样式
 31         font.Boldweight = short.MaxValue;
 32         //設置字體字號
 33         font.FontHeightInPoints = 18;
 34         //使用SetFont方法将字体样式添加到单元格样式中 
 35         style.SetFont(font);
 36         //将新的样式赋给单元格
 37         cell.CellStyle = style;
 38         //设置单元格的高度实际是设置其所在行高,所以要在单元格所在行上设置行高,行高设置数值好像是像素点的1 / 20,所以 * 20以便达到设置效果;
 39         //设置单元格的宽度实际上是设置其所在列宽,所以要在单元格所在列上设置(列的设置在工作表上),宽度数值好像是字符的1 / 256,所以 * 256以便达到设置效果。
 40 
 41         //设置单元格的高度
 42         row1.Height = 30 * 20;
 43         //设置单元格的宽度
 44         //sheet1.SetColumnWidth(0, 30 * 256);
 45         //合併單元格 為列寬數
 46         sheet1.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtDetail.Columns.Count - 1));
 47     }
 48     //1.2設置表頭 單元格屬性
 49     ICellStyle style1 = workBook.CreateCellStyle();
 50     //设置单元格的样式:水平对齐居中
 51     style1.Alignment = HorizontalAlignment.Center;
 52     //設置單元格的樣式: 上下居中
 53     style1.VerticalAlignment = VerticalAlignment.Center;
 54     //新建一个字体样式对象
 55     IFont font1 = workBook.CreateFont();
 56     //设置字体加粗样式
 57     //font1.Boldweight = short.MaxValue;
 58     //設置字體字號
 59     font1.FontHeightInPoints = 11;
 60     //使用SetFont方法将字体样式添加到单元格样式中 
 61     style1.SetFont(font1);
 62 
 63     //1.2設置表頭 單元格屬性
 64     ICellStyle style2 = workBook.CreateCellStyle();
 65     //设置单元格的样式:水平对齐居中
 66     style2.Alignment = HorizontalAlignment.Center;
 67     //設置單元格的樣式: 上下居中
 68     style2.VerticalAlignment = VerticalAlignment.Center;
 69     //新建一个字体样式对象
 70     IFont font2 = workBook.CreateFont();
 71     //设置字体加粗样式
 72     font2.Boldweight = short.MaxValue;
 73     //設置字體字號
 74     font2.FontHeightInPoints = 11;
 75     //使用SetFont方法将字体样式添加到单元格样式中 
 76     style2.SetFont(font2);
 77 
 78     //設置表頭
 79     NPOI.SS.UserModel.IRow row2 = sheet1.CreateRow(1);
 80     for (int i = 0; i < dtDetail.Columns.Count; i++)
 81     {
 82         row2.CreateCell(i).SetCellValue(dtDetail.Columns[i].ToString());//列頭
 83         row2.Cells[i].CellStyle = style1;
 84     }
 85 
 86     //設置表體
 87     for (int i = 0; i < dtDetail.Rows.Count; i++)
 88     {
 89         NPOI.SS.UserModel.IRow rowtemp = sheet1.CreateRow(i + 2);
 90         for (int j = 0; j < dtDetail.Columns.Count; j++)
 91         {
 92             rowtemp.CreateCell(j).SetCellValue(dtDetail.Rows[i][j].ToString());//
 93         }
 94     }
 95 
 96     //追加表體
 97     //取得并加入至表尾
 98     string overCollarNo = dtTemp.Rows[0]["ENCODING"].ToString(); 
 99     DataTable dtSignDetails = manageLib.GetSignDetails(overCollarNo, "");
100     if (dtSignDetails != null && dtSignDetails.Rows.Count > 0)
101     {
102         NPOI.SS.UserModel.IRow rowend = sheet1.CreateRow(dtDetail.Rows.Count + 3);//間隔一列
103         rowend.CreateCell(0).SetCellValue("");//第一列為空
104         for (int i = 0; i < dtSignDetails.Rows.Count; i++)
105         {
106             rowend.CreateCell(2 * i).SetCellValue(dtSignDetails.Rows[i]["REMARK01"].ToString());
107             rowend.CreateCell(2 * i + 1).SetCellValue(dtSignDetails.Rows[i]["REMARK02"].ToString());//
108             rowend.Cells[2 * i].CellStyle = style2;
109             rowend.Cells[2 * i + 1].CellStyle = style2;
110         }
111     }
112     //获取当前列的宽度,然后对比本列的长度,取最大值
113     //自適應寬度
114     for (int columnNum = 0; columnNum < dtDetail.Columns.Count; columnNum++)
115     {
116         int columnWidth = sheet1.GetColumnWidth(columnNum) / 256;
117         for (int rowNum = 1; rowNum < sheet1.LastRowNum + 1; rowNum++)
118         {
119             IRow currentRow;
120             //当前行未被使用过
121             if (sheet1.GetRow(rowNum) == null)
122             {
123                 currentRow = sheet1.CreateRow(rowNum);
124             }
125             else
126             {
127                 currentRow = sheet1.GetRow(rowNum);
128             }
129 
130             if (currentRow.GetCell(columnNum) != null)
131             {
132                 ICell currentCell = currentRow.GetCell(columnNum);
133                 int length = Encoding.Default.GetBytes(currentCell.ToString()).Length;
134                 if (columnWidth < length + 1)
135                 {
136                     columnWidth = length + 2;
137                 }
138             }
139         }
140         sheet1.SetColumnWidth(columnNum, columnWidth * 256);
141     }
142 
143 
144     MemoryStream memoryStream = new MemoryStream();
145     workBook.Write(memoryStream);
146     memoryStream.Seek(0, SeekOrigin.Begin);
147     return File(memoryStream, "application/vnd.ms-excel", $@"明細_{DateTime.Today.ToString("yyyyMMdd")}.xls");
148 }
View Code

 

posted @ 2020-05-27 16:27  Yookee  阅读(211)  评论(0编辑  收藏  举报