關於NPOI的相關信息,我想博客園已經有很多了,而且NPOI導出Execl的文章和例子也很多,但導出多表頭缺蠻少的;今天要講的通過自己畫html表格;通過html表格來導出自定義的多表頭;
先來看要實現的多表頭格式:
第一步:畫html表格(備注有一定的格式要求)
//td需要4個屬性,rowspan(跨行數)、colspan(跨列數)、row(所在行)、col(所在列);備注:其實除了跨行和跨列數外,后面只需要所在列都可以了;
<tr> <td rowspan="2" colspan="1" row="0" col="0">名稱1</td> <td rowspan="2" colspan="1" row="0" col="1">名稱2</td> <td rowspan="2" colspan="1" row="0" col="2">名稱3</td> <td rowspan="1" colspan="4" row="0" col="3">名稱4</td> <td rowspan="1" colspan="4" row="0" col="7">名稱5</td> <td rowspan="1" colspan="4" row="0" col="11">名稱6</td> <td rowspan="1" colspan="4" row="0" col="15">名稱7</td> <td rowspan="2" colspan="1" row="0" col="19">名稱8</td> <td rowspan="2" colspan="1" row="0" col="20">名稱9</td> <td rowspan="2" colspan="1" row="0" col="21">備注</td> </tr> <tr> <td rowspan="1" colspan="1" row="1" col="3">效果1</td> <td rowspan="1" colspan="1" row="1" col="4">效果2</td> <td rowspan="1" colspan="1" row="1" col="5">效果3</td> <td rowspan="1" colspan="1" row="1" col="6">效果4</td> <td rowspan="1" colspan="1" row="1" col="7">效果5</td> <td rowspan="1" colspan="1" row="1" col="8">效果6</td> <td rowspan="1" colspan="1" row="1" col="9">效果7</td> <td rowspan="1" colspan="1" row="1" col="10">效果8</td> <td rowspan="1" colspan="1" row="1" col="11">效果9</td> <td rowspan="1" colspan="1" row="1" col="12">效果10</td> <td rowspan="1" colspan="1" row="1" col="13">效果11</td> <td rowspan="1" colspan="1" row="1" col="14">效果12</td> <td rowspan="1" colspan="1" row="1" col="15">效果13</td> <td rowspan="1" colspan="1" row="1" col="16">效果14</td> <td rowspan="1" colspan="1" row="1" col="17">效果15</td> <td rowspan="1" colspan="1" row="1" col="18">效果16</td> </tr>
第二步,解析html表格
1、正則遍歷tr
string rowContent = string.Empty; MatchCollection rowCollection = Regex.Matches(html, @"<tr[^>]*>[\s\S]*?<\/tr>", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); //對tr進行篩選
2、循環tr正則遍歷td
MatchCollection columnCollection = Regex.Matches(rowContent, @"<td[^>]*>[\s\S]*?<\/td>", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); //對td進行篩選
3、解析td原屬
var match = Regex.Match(columnCollection[j].Value, "<td.*?rowspan=\"(?<row>.*?)\".*?colspan=\"(?<col>.*?)\".*?row=\"(?<row1>.*?)\".*?col=\"(?<col1>.*?)\">(?<value>.*?)<\\/td>", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); if (match.Success) { int rowspan = Convert.ToInt32(match.Groups["row"].Value);//表格跨行 int colspan = Convert.ToInt32(match.Groups["col"].Value);//表格跨列 int rowcount = Convert.ToInt32(match.Groups["row1"].Value);//所在行 int col = Convert.ToInt32(match.Groups["col1"].Value);//所在列 string value = match.Groups["value"].Value;//值
}
通過上面幾步,都可以解析出對應的表格原屬
使用NPOI
1、創建HSSFWorkbook
HSSFWorkbook hssfworkbook = new HSSFWorkbook();;//創建Workbook對象 HSSFSheet sheet1 = (HSSFSheet)hssfworkbook.CreateSheet("測試多表頭");//創建工作表
2、在tr循環中創建行
//寫在tr循環中
for (int i = 0; i < rowCollection.Count; i++){
HSSFRow row = (HSSFRow)sheet1.CreateRow(i); rowContent = rowCollection[i].Value;
}
3、在td循環中創建列(關鍵)
//遍歷td
for (int j = 0; j < columnCollection.Count; j++) { var match = Regex.Match(columnCollection[j].Value, "<td.*?rowspan=\"(?<row>.*?)\".*?colspan=\"(?<col>.*?)\".*?row=\"(?<row1>.*?)\".*?col=\"(?<col1>.*?)\">(?<value>.*?)<\\/td>", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture); if (match.Success) { int rowspan = Convert.ToInt32(match.Groups["row"].Value);//表格跨行 int colspan = Convert.ToInt32(match.Groups["col"].Value);//表格跨列 int rowcount = Convert.ToInt32(match.Groups["row1"].Value);//所在行 int col = Convert.ToInt32(match.Groups["col1"].Value);//所在列 string value = match.Groups["value"].Value; if (colspan == 1)//判斷是否跨列 { var cell = row.CreateCell(col);//創建列 cell.SetCellValue(value);//設置列的值 if (value.Length > 0) { int width = value.Length * 25 / 6; if (width > 255) width = 250; sheet1.SetColumnWidth(col, width * 256); } } //判斷是否跨行、跨列 if (rowspan > 1 || colspan > 1) { int firstRow = 0, lastRow = 0, firstCol = 0, lastCol = 0; if (rowspan > 1)//跨行 { firstRow = rowcount; lastRow = firstRow + rowspan - 1; } else { firstRow = lastRow = i; } if (colspan > 1)//跨列 { firstCol = col; int cols = col + colspan; for (; col < cols; col++) { var cell = row.CreateCell(col); cell.SetCellValue(value); } lastCol = col - 1; } else { firstCol = lastCol = col; }
//關鍵是這里,設置起始行數,結束行數;起始列數,結束列數 sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); } } }
保存execl
string year = DateTime.Now.Year.ToString(); string ppath = HttpContext.Current.Server.MapPath(DateTime.Now.ToString("yyyyMMddmmss") + ".xls"); FileStream file = new FileStream(ppath, FileMode.Create); hssfworkbook.Write(file); file.Close();
這樣都保存在服務器上了,可以通過下載自行下載下來;這里不復制代碼了;
如果有什么問題,請指教,謝謝!