如何將資料庫中的樹結構表匯出EXCEL
阿新 • • 發佈:2021-08-06
我們常常會遇到這樣的需求,將資料庫中父子結構的表資料匯出作為表頭
我們實現的開發中就遇到這樣的需求:將所有使用者的許可權表匯出,許可權作為表頭
思路: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 fromsys_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; endif; 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; } }