我们常常会遇到这样的需求,将数据库中父子结构的表数据导出作为表头

我们实现的开发中就遇到这样的需求:将所有用户的权限表导出,权限作为表头

思路:sql求出每一条权限数据应该跨的行数,在代码中填充这些数据

create or replace function useEasy(mid in nvarchar2)
return number
is
FunctionResult number;
SubNum number;
CurrNum number;
begin
CurrNum := 1;
select count(*) into SubNum from sys_menu m where m.parentid = mid;
--CurrNum := SubNum + CurrNum;
if SubNum > 0 then
CurrNum := CurrNum-1;
FOR m1 IN (select m.id,m.parentid from sys_menu m where m.parentid = mid) LOOP CurrNum := CurrNum + useEasy(m1.id); end LOOP; end if; FunctionResult := CurrNum;
return(FunctionResult);
end useEasy;
select m.id,m.parentid,m.menutext,m.menucode,m.menutext,useEasy(m.id) OccupyRow from sys_menu m
where m.parentid = '2D14DFA8-8D9B-4034-A2CD-2099AD4A0A33'
order by m.menusort asc
 public class ExportUserPower
{ public ExportUserPower(string sheetName)
{
this.sheetName = sheetName;
} public HSSFWorkbook ExcelWork { get; set; } public string WorkName { get; set; }
private string sheetName { get; set; }
public string SheetName
{
get
{
return sheetName;
}
set
{
value = sheetName;
}
} public List<HeadMenuTree> MenuList { get; set; } private string systemCode;
public string SystemCode
{
get
{
return systemCode;
}
set
{
value = systemCode;
}
} /// <summary>
/// 创建Sheet
/// </summary>
/// <param name="hwb"></param>
/// <param name="sheetName"></param>
/// <returns></returns>
public HSSFSheet CreateSheet(HSSFWorkbook hwb, string sheetName)
{
//创建一个excel中的表格
HSSFSheet sheet = (HSSFSheet)hwb.CreateSheet(sheetName);
return sheet;
} public ICell CreateCell(HSSFRow row, int num)
{
ICell cell = row.CreateCell(num);
return cell;
} public void ExportExcelWork()
{
//创建一个excel
ExcelWork = new HSSFWorkbook();
//创建一个excel中的表格
HSSFSheet sheet = CreateSheet(ExcelWork, sheetName);
CreateHeadMenu(sheet);
} public void CreateHeadMenu(HSSFSheet sheet)
{
int _ColumnNum = 1; //定义列
int _RowNum = -1; //定义行
//HSSFRow headerrow = (HSSFRow)sheet.CreateRow(_RowNum);
//headerrow.CreateCell(_ColumnNum).SetCellValue("用户"); //创建头部 列1 用户
//TreeMenu sys_root = MenuList.Where(w => w.menucode == systemCode).FirstOrDefault();
CreateAllMenuColl(sheet, MenuList, _RowNum, _ColumnNum);
//sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 2));
} public void CreateAllMenuColl(HSSFSheet sheet, List<HeadMenuTree> list, int row, int startColumn)
{
int f = 0;
int thisRow = row + 1;
IRow headerrow;
if (sheet.LastRowNum < thisRow)
headerrow = sheet.CreateRow(thisRow);
else
headerrow = sheet.GetRow(thisRow);
if (headerrow == null)
headerrow = sheet.CreateRow(thisRow); int thisColumn = startColumn;
foreach (HeadMenuTree item in list)
{
//log4net.LogManager.GetLogger("OperationLogger").Error("thisColumn:" + thisColumn + ";thisRow:" + thisRow); ICell cell = headerrow.CreateCell(thisColumn);
cell.CellStyle = CreateCellStyle();
cell.SetCellValue(item.Name); if (thisColumn != (thisColumn + item.OccupyRow - 1))
sheet.AddMergedRegion(new CellRangeAddress(thisRow, thisRow, thisColumn, (thisColumn + item.OccupyRow) - 1)); if (item.Children.Count > 0)
CreateAllMenuColl(sheet, item.Children, thisRow, thisColumn); thisColumn = (thisColumn + item.OccupyRow); f++;
} thisColumn = 1;
thisRow = 0;
} public void FillData()
{
SystemMenuService service = new SystemMenuService();
MenuList = service.GetAllHeadMenu("ZhanJiang");
} 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;
} public ICellStyle CreateCellStyle()
{
ICellStyle cellStyle = ExcelWork.CreateCellStyle();
cellStyle.BorderBottom = BorderStyle.Thin;
cellStyle.BorderLeft = BorderStyle.Thin;
cellStyle.BorderRight = BorderStyle.Thin;
cellStyle.BorderTop = BorderStyle.Thin;
return cellStyle;
} }

如何将数据库中的树结构表导出EXCEL的更多相关文章

  1. 用C# ASP.net将数据库中的数据表导出到Excel中

    需要用到组件GridView和一个button即可. 给GridView添加一个数据源, 选择你想要的数据库中的表的字段,添加成功后GridView中就显示数据. 再添加一个button,双击控件添加 ...

  2. NPOI 操作数据库中数据的导入导出(Excel.xls文件) 和null数据的处理。

    App.config: <?xml version="1.0" encoding="utf-8" ?> <configuration> ...

  3. SQLSERVER如何获取一个数据库中的所有表的名称、一个表中所有字段的名称

    1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...

  4. 怎样用SQL语句查询一个数据库中的所有表?

    怎样用SQL语句查询一个数据库中的所有表?  --读取库中的所有表名 select name from sysobjects where xtype='u'--读取指定表的所有列名select nam ...

  5. [转]SQLSERVER如何获取一个数据库中的所有表的名称、一个表中所有字段的名称

    1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...

  6. SQLSERVER | 查询数据库中所有的表的名字 | 查询数据库中的所有数据库名

    SQLSERVER 1.查询某个数据库中所有的表名:  SELECT Name FROM SysObjects Where XType='U' ORDER BY Name 2.查询数据库中的所有数据库 ...

  7. sql 2000以及2005以上获取数据库中所有的表(不包括系统表)

    ---------------------------------------------------------------------------- --sql 2005以上数据库 --- 获取数 ...

  8. 对SharePoint 2007数据库中一些数据表的使用

    转:http://blog.csdn.net/ma_jiang/article/details/6553392 在工作中接触了一些SharePoint的数据库中的一些表.在此做个总结. 一位高手告诉我 ...

  9. SQL数据库中把一个表中的数据复制到另一个表中

    1.如果是整个表复制表达如下: insert into table1 select  * from table2 2.如果是有选择性的复制数据表达如下: insert into table1(colu ...

  10. Oracle中查询当前数据库中的所有表空间和对应的数据文件语句命令

    Oracle中查询当前数据库中的所有表空间和对应的数据文件语句命令 ------------------------------------------------------------------ ...

随机推荐

  1. 火山引擎DataLeap联合DataFun发布《数据治理知识地图》

    近期,火山引擎DataLeap和技术社区DataFun联合发布<数据治理知识地图专业版V1>(以下简称"地图"),地图将数据治理的领域.流程.技术.工具等内容进行系统化 ...

  2. MQTT 客户端 MQTT.fx 使用说明

    下载 官网:https://softblade.de/en/download-2/ 说明:最后的免费版本是 MQTT.fx 1.7.1,官网已经没有免费的版本 下载 MQTT.fx 1.7.1 htt ...

  3. Hugging Face 入选 Time《时代周刊》2023 全球前 100 最具影响力的公司

    喜报 Hugging Face 入选 Time<时代周刊>2023 全球前 100 最具影响力的公司 继续为梦想努力 继续为开源贡献 榜单链接: https://time.com/100c ...

  4. 台大李宏毅机器学习公开课2020版登陆B站

    课程简介: 真正大师的课程往往都是免费的,诸如吴恩达,李飞飞等.不过大家应该对李宏毅老师也不陌生吧?很多机器学习初学者,首选李宏毅老师.毕竟中文授课,而且他讲课通俗易懂.课程案例生动有趣(还记得宝可梦 ...

  5. Python 网络舆情分析系统,舆论可视化界面

    1 简介 舆情管理系统,这不仅仅可以帮助当地的管理人员迅速的排查跟本地有关的负面言论,还可以避免网民因为本身意识不到位而评论或发布一些不好的观点的情况,最终的目的就是帮助社会更好的发展. 2 技术栈 ...

  6. JSP 学习笔记 | 六、Filter & Listener

    前文:JSP 学习笔记 | 五.会话技术 Session & Cookie 前文:JSP 学习笔记 | 四.JSP标准标签库(JSTL)个人使用指南 前文:JSP 学习笔记 | 三.EL 表达 ...

  7. 汇编 | mov. add. sub指令

    Description 前面我们用到了mov, add. sub指令,它们都带有两个操作对象.到现在,我们知道,mov指令可以有以下几种形式. mov 寄存器,数据 比如: mov ax,8 mov ...

  8. BZOJ 2038: [2009国家集训队]小Z的袜子【莫队算法裸题】

    作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿. 终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命. 具体来说,小Z把这N只袜子从1到N编号,然后从 ...

  9. C++ 的两种换行符区别

    当我们在C++执行一个输出语句时,在输出语句最后可以使用 std::endl 或 \n 建立一个新行. 但这两种换行方式对程序有不同的影响. std::endl 它在建立一个新的行的同时,还会自动刷新 ...

  10. VScode 中 Code Runner 插件乱码问题

    安装好,Code Runner 插件,可以很方便的运行多种语言的文本,但是提示和输出经常会报错 进入 File - > Preference -> setting, 然后在输入框搜索 se ...