.Net Core NPOI 导出多级表头的实现代码

 更新时间:2024年11月11日 09:19:51   作者:我想火火火  
这篇文章介绍了如何使用.NetCore和NPOI库导出多级表头的表格数据,并附上了源码,感兴趣的朋友一起看看吧

想要导出这样的表格

数据准备格式

附上源码

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using System.Data;
using System.Text.RegularExpressions;
namespace TestConsoleApp
{
    /// <summary>
    /// 导出Excel
    /// </summary>
    public static class ExportHelper
    {
        public static void Export()
        {
            var dt = CreteTable();
            var titles = GetExcelTitles(dt.Columns, out int maxTitleLevel);
            HSSFWorkbook workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet("Sheet1");
            var allRowCount = dt.Rows.Count + maxTitleLevel;
            //创建所有单元格
            for (int i = 0; i < allRowCount; i++)
            {
                var row = sheet.CreateRow(i);
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    row.CreateCell(j);
                }
            }
            //合并创建表头
            foreach (var tit in titles)
            {
                sheet.GetRow(tit.StartRow).GetCell(tit.StartColumn).SetCellValue(tit.Title);
                if (tit.MergeColumnCount + tit.MergeRowCount > 0)
                {
                    sheet.AddMergedRegion(new CellRangeAddress(tit.StartRow, tit.StartRow + tit.MergeRowCount, tit.StartColumn, tit.StartColumn + tit.MergeColumnCount));
                }
            }
            //生成数据行
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    string cellValue = dt.Rows[i][j].ToString();
                   sheet.GetRow(maxTitleLevel + i).Cells[j].SetCellValue(cellValue);
                }
            }
            using FileStream stm = File.OpenWrite(@"D:\Drivers\Merge.xls");
            workbook.Write(stm);
        }
        private static DataTable CreteTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("编号");
            dt.Columns.Add("收入-线上采购-数量");
            dt.Columns.Add("收入-线上采购-金额");
            dt.Columns.Add("收入-线下采购-数量");
            dt.Columns.Add("收入-线下采购-金额");
            dt.Columns.Add("回收-数量");
            dt.Columns.Add("回收-金额");
            dt.Columns.Add("支出-测试01-数量");
            dt.Columns.Add("支出-测试01-金额");
            dt.Columns.Add("支出-测试02-数量");
            dt.Columns.Add("支出-测试02-金额");
            dt.Columns.Add("其它-数量");
            dt.Columns.Add("其它-金额");
            dt.Columns.Add("备注");
            for (int i = 1; i <= 100; i++)
            {
                var row = dt.NewRow();
                row["编号"] = "编号" + i;
                row["收入-线上采购-数量"] = i;
                row["收入-线上采购-金额"] = i;
                row["收入-线下采购-数量"] = i;
                row["收入-线下采购-金额"] = i;
                row["回收-数量"] = i;
                row["回收-金额"] = i;
                row["支出-测试01-数量"] = i;
                row["支出-测试01-金额"] = i;
                row["支出-测试02-数量"] = i;
                row["支出-测试02-金额"] = i;
                row["其它-数量"] = i;
                row["其它-金额"] = i;
                row["备注"] = i;
                dt.Rows.Add(row);
            }
            return dt;
        }
        private static List<ExcelTitle> GetExcelTitles(DataColumnCollection columns, out int maxTitleLevel)
        {
            maxTitleLevel = 0;
            List<LevelExcelTitle> levelExcelTitles = new List<LevelExcelTitle>();
            for (var index = 0; index < columns.Count; index++)
            {
                var column = columns[index].ToString();
                var arr = column.Split("-");
                if (maxTitleLevel < arr.Length)
                {
                    maxTitleLevel = arr.Length;
                }
                for (int i = 0; i < arr.Length; i++)
                {
                    levelExcelTitles.Add(new LevelExcelTitle()
                    {
                        Title = arr[i],
                        LevelCode = string.Join("-", arr[..(i + 1)]),
                        RowIndex = i,
                        ColumnIndex = index,
                        TotalLevel = arr.Length
                    });
                }
            }
            var titleLevel = maxTitleLevel;
            var excelTitles = levelExcelTitles
                .GroupBy(b => new
                {
                    b.LevelCode,
                    b.Title
                })
               .Select(b => new ExcelTitle()
               {
                   Title = b.Key.Title,
                   StartRow = b.Min(c => c.RowIndex),
                   MergeRowCount = b.Min(c => c.RowIndex) + 1 == b.Max(c => c.TotalLevel) ? titleLevel - b.Max(c => c.TotalLevel) : 0,
                   StartColumn = b.Min(c => c.ColumnIndex),
                   MergeColumnCount = b.Count() - 1,//排除自身
               }).ToList();
            return excelTitles;
        }
    }
    public class ExcelTitle
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 开始行
        /// </summary>
        public int StartRow { get; set; }
        /// <summary>
        /// 合并行
        /// </summary>
        public int MergeRowCount { get; set; }
        /// <summary>
        /// 开始列
        /// </summary>
        public int StartColumn { get; set; }
        /// <summary>
        /// 合并列
        /// </summary>
        public int MergeColumnCount { get; set; }
    }
    public class LevelExcelTitle
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        public string LevelCode { get; set; }
        /// <summary>
        /// 第几行
        /// </summary>
        public int RowIndex { get; set; }
        /// <summary>
        /// 第几列
        /// </summary>
        public int ColumnIndex { get; set; }
        /// <summary>
        /// 总层
        /// </summary>
        public int TotalLevel { get; set; }
    }
}

到此这篇关于.Net Core NPOI 导出多级表头的文章就介绍到这了,更多相关.Net Core NPOI 导出多级表头内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

最新评论