首页 > 代码库 > 分享使用NPOI导出Excel树状结构的数据,如部门用户菜单权限

分享使用NPOI导出Excel树状结构的数据,如部门用户菜单权限

        大家都知道使用NPOI导出Excel格式数据 很简单,网上一搜,到处都有示例代码。

         因为工作的关系,经常会有处理各种数据库数据的场景,其中处理Excel 数据导出,以备客户人员确认数据,场景很常见。

         一个系统开发出来,系统要运行起来,很多数据要初始化,这个时候也是需要客户提供各种业务的基础数据。客户提供的数据中,其中除了word、pdf,最常见的就是Excel。

        废话不多说,直接上图上代码:

      如图,

          左侧三列,作为 一个系统 所有菜单的树状结构。

         其他列 以用户的信息(如用户名、登录名) 作为表头,需要注意的是在整理数据进行导出时,需保证列名不能重复

技术分享

 

 

 public static void DataTree(string path, DataTable table, int treeIndex = 10000)        {            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))            {                IWorkbook workBook = new HSSFWorkbook();                //现在使用的仍然是生成Excel2003的Excel文件,由于03对行数(65535)和列数(255)有限制,所以当数据超出范围后难免出错                //ArgumentException: Invalid column index (256). Allowable column range for BIFF8 is (0..255) or (‘A‘..‘IV‘) ...                if (Path.GetExtension(path).Equals(".xlsx", System.StringComparison.OrdinalIgnoreCase))                {                    workBook = new XSSFWorkbook();                }                string sheetName = string.IsNullOrWhiteSpace(table.TableName) ? "Sheet1" : table.TableName;                ISheet sheet = workBook.CreateSheet(sheetName);                IRow row = null;                int colNum = table.Columns.Count;                if (treeIndex < table.Columns.Count || treeIndex > 0)                {                    colNum = treeIndex;                }                ICellStyle cellCenterStyle = GetCenter(workBook);                int beginNum = 1;//排除列头,从1开始                //处理表格列头                row = sheet.CreateRow(beginNum - 1);                for (int i = 0; i < table.Columns.Count; i++)                {                    string strVal = table.Columns[i].ColumnName;                    ICell cell = row.CreateCell(i);                    cell.SetCellValue(strVal);                    cell.CellStyle = cellCenterStyle;                    row.Height = 350;                    sheet.AutoSizeColumn(i);                }                //处理数据内容                for (int i = 0; i < table.Rows.Count; i++)                {                    row = sheet.CreateRow(beginNum + i);                    row.Height = 250;                    for (int j = 0; j < table.Columns.Count; j++)                    {                        string strVal = table.Rows[i][j].ToString();                        ICell currCell = row.CreateCell(j);                        currCell.SetCellValue(strVal);                        currCell.CellStyle = cellCenterStyle;                        sheet.SetColumnWidth(j, 256 * 15);                    }                }                for (int i = 0; i < colNum; i++)                {                    List<int> lstColWidth = new List<int>();                    string currVal = string.Empty;                    string nextVal = string.Empty;                    for (int j = beginNum; j <= sheet.LastRowNum; j++)                    {                        currVal = sheet.GetRow(j).Cells[i].StringCellValue;                        int mk = j;                        if (!string.IsNullOrWhiteSpace(currVal))//排除 空值,空值不做合并处理                        {                            for (int k = j + 1; k <= sheet.LastRowNum; k++)                            {                                nextVal = sheet.GetRow(k).Cells[i].StringCellValue;                                if (currVal != nextVal)                                {                                    //因为k 累加所以导致当前值与下个值 不相同,所以记录 当前行数要 减去1                                    mk = k - 1;                                    break;                                }                                else if (k == sheet.LastRowNum) //边界值,处理最后一行,则提前Break 并记录当前 k                                {                                    mk = k;                                    break;                                }                            }                        }                        if (mk != j)//排除 空值外,下个值的行数不等于当前行数,则需要合并                        {                            sheet.AddMergedRegion(new CellRangeAddress(j, mk, i, i));                        }                        //if (i == 0) //如果是第一列,则 垂直水平居中                        {                            sheet.GetRow(j).Cells[i].CellStyle = cellCenterStyle;                        }                        //跳到执行下一个不同数据的行                        j = mk;                        //记录列长度                        lstColWidth.Add(DataLength(currVal));                    }                    //设置列宽                    int maxWidth = lstColWidth.Max() * 200;                    sheet.SetColumnWidth(i, maxWidth);                }//固定列、行 滚动时不变                sheet.CreateFreezePane(3, 1, 3, 1);                //写入数据流                workBook.Write(fs);            }        }        private static ICellStyle GetCenter(IWorkbook workBook, short fontSize = 10)        {            ICellStyle cellStyle = workBook.CreateCellStyle();            IFont font = workBook.CreateFont();            font.FontName = "微软雅黑";            font.FontHeightInPoints = fontSize;            cellStyle.SetFont(font);            cellStyle.VerticalAlignment = VerticalAlignment.Center;            cellStyle.Alignment = HorizontalAlignment.Center;            return cellStyle;        }        /// <summary>        /// 获取字符串长度(中文按2个字节长度)        /// </summary>        /// <param name="stringWithEnglishAndChinese"></param>        /// <returns></returns>        private static int DataLength(string stringWithEnglishAndChinese)        {            int lng = 0;            for (int i = 0; i < stringWithEnglishAndChinese.Length; i++)            {                byte[] b = System.Text.Encoding.Default.GetBytes(stringWithEnglishAndChinese.Substring(i, 1));                if (b.Length > 1)                    lng += 2;                else                    lng += 1;            }            return lng;        }

 

分享使用NPOI导出Excel树状结构的数据,如部门用户菜单权限