1.导出 处理 逻辑。
try
{
int propertyCount = getPropertyCount(typeof(T));
var hssfWorkbook = new XSSFWorkbook();
var sheet1 = hssfWorkbook.CreateSheet(sheetName);
var row1 = (XSSFRow)sheet1.CreateRow(2);
//表头样式
var rowstyle = hssfWorkbook.CreateCellStyle();
rowstyle.Alignment = HorizontalAlignment.Center;
//rowstyle.FillBackgroundColor = HSSFColor.Grey25Percent.Index;
var font1 = hssfWorkbook.CreateFont();
font1.FontHeight = 20;
//font1.Boldweight = 600;
rowstyle.SetFont(font1);
font1.FontHeightInPoints = 20;
font1.Boldweight = 700;
WriteHeader(typeof(T), row1, rowstyle);
int i = 0;
for (int j = 0; j < listData.Count; j++)
{
int rowIndex = i;
var rowData = (XSSFRow)sheet1.CreateRow(rowIndex + 3);
WriteData(listData[j], typeof(T), rowData);
i++;
}
setAutoColumn(sheet1, i);
//sheet1 就是 在内存中 填充好的 Excel数据。下面合并要用到
///
///这里 放置 合并方法。
///第 0 列 合并。
mergeuser(sheet1,0);
var rowfooter = (XSSFRow)sheet1.CreateRow(i + 3);
//NpoiMemoryStream 是 重写Npoi流方法
using (NpoiMemoryStream ms = new NpoiMemoryStream())
{
ms.AllowClose = false;
hssfWorkbook.Write(ms);
ms.Flush();
ms.Position = 0;
hssfWorkbook = null;
return ms;
}
}
catch (Exception ex)
{
throw ex;
}
2.重写 Npoi流。
/// <summary>
/// 重写Npoi流方法
/// </summary>
public class NpoiMemoryStream : MemoryStream
{
public NpoiMemoryStream()
{
AllowClose = true;
}
public bool AllowClose { get; set; }
/// <summary>
/// 关闭
/// </summary>
public override void Close()
{
if (AllowClose)
base.Close();
}
}
3.合并 单元格 方法。
private static void mergeuser(ISheet sheet, int columnIndex)
{
//开始 要合并的内容为空
var previous = "";
//startRow 是你Excel 数据是 第几行开始的
var startRow = 3;
for (int rowNum = 3; rowNum <= sheet.LastRowNum; rowNum++)
{
//获取 指定行,指定列的 数据内容
var current = sheet.GetRow(rowNum).GetCell(columnIndex).StringCellValue;
// 判断 获取到的内容是否和 上一列 相等
if (current.Equals(previous))
{continue;}
else
{
// 第一级 合并。
//将获取到的 内容 赋值到 previous
previous = current;
// 判断开始行,是否小于 循环的行数。
if (startRow < rowNum)
{
//第二级 合并
var celltext = "";
var startAM = startRow;
for (int i = startRow; i <= rowNum; i++)
{
var endtext = sheet.GetRow(i).GetCell(1).StringCellValue;
if (celltext.Equals(endtext))
{ continue; }
else
{
celltext = endtext;
if (startAM < i)
{
// CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
//这里 终止行号 -1 原因是:上面循环判断时 内容不一样的 才进行 合并,
//这时 行数 i 内容 已经不一样,所以 需要减去 1 进行合并
sheet.AddMergedRegion(new CellRangeAddress(startAM, i - 1, columnIndex + 1, columnIndex + 1));
}
// 将 当前行数,进行赋值给 启始行数。
startAM = i;
}
}
sheet.AddMergedRegion(new CellRangeAddress(startRow, rowNum - 1, columnIndex, columnIndex));
}
startRow = rowNum;
}
}
}