树结构关系的数据导出为excel
该文针对的是关于树结构的数据的导出,每一个节点都可以创建不定数的子节点,在选择好某个节点进行导出
时,会把该节点以及子节点的数据都导出来。导出后的excel的格式大概如下图的形式,这个是一个比较理想
的状态,合并的空单元格也比较顺利,但实际的子节点数肯定不可能是一样的,合并必要的单元格也肯定不会
这么简单。

难点就在于得到数据和合并必要的空单元格。其实现在的数据导出有很多的博文,并且有关的一些坑也踩了好
多。导出像上图的excel格式的话,首先需要通过深度优先得到该子节点下的数据,然后得到不合并单元格的
excel格式,再然后通过从得到的树的深度的倒数第二层来看看得到需要合并的范围。依据就是首先查出该节
点的子节点数,在遍历子节点的一列,记录下合并的起始位置,结束位置来进行合并。
通过深度优先得到要导出的数据
//遍历tree
public List<Dictionary<string, object>> getTree(string id, int width)
{
List<ft_topic> list = getChild(id);
width++;
int hex = height + 1;
Dictionary<string, object> map = new Dictionary<string, object>();
ft_topic entity = db.ft_topic.Where(t => t.id == id).Single();
map.Add("name", entity.name);
map.Add("id", entity.id);
map.Add("width", width);
map.Add("height", height);
entities.Add(map);
for (int i = 0; i < list.Count; i++)
{
getTree(list[i].id, width);
}
if(list.Count == 0)
{
height++;
}
if (depth < width)
{
depth = width;
}
return entities;
}
合并必要的空单元格
//合并单元格sheet, depth, height
public void mergeCell(HSSFSheet sheet, int depth, int height)
{
//合并单元格, 起始行号,终止行号, 起始列号,终止列号
if (depth >= 3)
{
for (int j = depth - 2; j >= 0; j--)
{
if (j == 0)
{
sheet.AddMergedRegion(new CellRangeAddress(1, height, 0, 0));
}
else
{
int cell = 2 * j - 1;
for (int i = 1; i <= height; i++)
{
String id = sheet.GetRow(i).GetCell(cell).StringCellValue;
if (id != null && !"".Equals(id))
{
List<ft_topic> topics = db.ft_topic.Where(o => o.pid == id).Where(o => o.status == "A").ToList();
if (topics.Count() > 0)
{
//得到merge范围
List<int> range = mergeCellRange(sheet, id, cell + 2, height, topics.Count());
range = getRealRanage(range);
if (range[0] != range[1])
{
sheet.AddMergedRegion(new CellRangeAddress(range[0], range[1], cell, cell));
String duplicateId = sheet.GetRow(range[0]).GetCell(cell).StringCellValue;
for (int k = range[0] + 1; k <= range[1]; k++)
{
String tmpId = sheet.GetRow(k).GetCell(cell).StringCellValue;
if (tmpId == null || "".Equals(tmpId))
{
sheet.GetRow(k).GetCell(cell).SetCellValue(duplicateId);
}
}
sheet.AddMergedRegion(new CellRangeAddress(range[0], range[1], cell + 1, cell + 1));
}
}
}
}
}
}
}
else
{
sheet.AddMergedRegion(new CellRangeAddress(1, height, 0, 0));
}
}
得到合并范围
//得到合并范围
public List<int> mergeCellRange(HSSFSheet sheet, String pid, int cell, int height, int childnum)
{
List<int> res = new List<int>();
List<String> ids = new List<string>();
for (int i = 1; i <= height; i++)
{
String id = sheet.GetRow(i).GetCell(cell).StringCellValue;
if (!ids.Contains(id))
{
if (db.ft_topic.Where(o => o.pid == pid).Where(t => t.id == id).Where(t => t.status == "A").SingleOrDefault() != null)
{
ids.Add(id);
if (ids.Count() == 1)
{
res.Add(i);
}
if (ids.Count() == childnum)
{
res.Add(i);
//break;
}
}
}
else
{
res.Add(i);
}
}
return res;
}
注意点需要知道上面得到的范围内容有多个,因此还需要在这多个值里面得到最大,最小的值,来合并。
树结构关系的数据导出为excel的更多相关文章
- 学习笔记 DataGridView数据导出为Excel
DataGridView数据导出为Excel 怎样把WinForm下的“DGV”里的绑定数据库后的数据导出到Excel中. 比如:在窗体里有个一“DGV”,DataGridView1,绑定了数据源 ...
- 将C1Chart数据导出到Excel
大多数情况下,当我们说将图表导出到Excel时,意思是将Chart当成图片导出到Excel中.如果是这样,你可以参考帮助文档中保存和导出C1Chart章节. 不过,也有另一种情况,当你想把图表中的数据 ...
- vb.net-三种将datagridview数据导出为excel文件的函数
第一种方法较慢,但是数据格式都比较好,需要引用excel的 Microsoft.Office.Interop.Excel.dll office.dll #Region "导出excel函数 ...
- 数据导出至Excel文件--好库编程网http://code1.okbase.net/codefile/SerializeHelper.cs_2012122018724_118.htm
using System; using System.IO; using System.Data; using System.Collections; using System.Data.OleDb; ...
- 数据导出到Excel中
自己修改后的一个数据导出到Excel的方法,粘出来与大家共享. 只需要将 System.Web.HttpContext.Current.Response.Charset = ...
- asp.net将数据导出到excel
本次应用datatable导出,若用gridview(假设gridview设为了分页显示)会出现只导出当前页的情况. protected void btnPrn_Click(object sender ...
- 将datagrid中数据导出到excel中 -------<<工作日志2014-6-6>>
前台datagrid数据绑定 #region 导出到excel中 /// <summary> /// 2014-6-6 /// </summary> / ...
- 机房收费系统——在VB中将MSHFlexGrid控件中的数据导出到Excel
机房收费系统中,好多查询的窗体都包含同一个功能:将数据库中查询到的数据显示在MSHFlexGrid控件中,然后再把MSHFlexGrid控件中的数据导出到Excel表格中. 虽然之前做过学生信息管理系 ...
- Qt中将QTableView中的数据导出为Excel文件
如果你在做一个报表类的程序,可能将内容导出为Excel文件是一项必须的功能.之前使用MFC的时候我就写过一个类,用于将grid中的数据导出为Excel文件.在使用了QtSql模块后,我很容易的将这个类 ...
随机推荐
- jackson使用问题:mapper.readValue()将JSON字符串转反序列化为对象失败或异常
问题根源:转化目标实体类的属性要与被转JSON字符串总的字段 一 一对应!字符串里可以少字段,但绝对不能多字段. 先附上我这段出现了问题的源码: // 1.接收并转化相应的参数.需要在pom.xml中 ...
- python数据结构与算法第十三天【归并排序】
1.代码实现 def merge_sort(alist): if len(alist) <= 1: return alist # 二分分解 num = len(alist)/2 left = m ...
- LODOP中page-break-before:always给div分页
Lodop中超过超文本打印项高度会自动分页:Lodop打印控件 超文本自动分页Lodop中还有NewPage和NewPageA,用于手动分页:Lodop强制分页LODOP.NewPage()和LODO ...
- 【python练习题】程序14
#题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. #我的方法应该比网上的更加简洁,只是递归可能速度慢 n = input('请输入一个正整数:') n = int(n) X ...
- SQL 给视图赋权限
授予表权限 创建视图 授予视图权限 测试权限 复杂程度: 初级 数据要求: 使用自备的数据 您可以使用 SQL 在企业级地理数据库中创建表和要素类的视图. 本主题中的示例显示如何使用 Microsof ...
- codeforces605A
Sorting Railway Cars CodeForces - 605A 一辆列车有N节车厢,编号为1...N(每节车厢编号都不同),并且他们的排列是混乱的.李老湿想要把这N节车厢重新排列为升序排 ...
- iOS WKWebView全屏浏览网页返回 状态栏问题
问题: 用这个方法隐藏显示状态栏,总是带有残余 过一会才能消失掉 [[UIApplication sharedApplication]setStatusBarHidden:YES]; 可以切换状态栏的 ...
- poj-1386(欧拉回路)
题意:给你n个单词,每个单词可以和另一个单词连接,前提是(这个单词的尾字母等下一个单词的首字母),问你有没有一种连法能够连接所有的单词: 解题思路:每个单词可以看成是首字母指向尾字母的一条边,那么就变 ...
- Android与H5交互 原理与对比
原文: https://www.jianshu.com/p/345f4d8a5cfa 1.Android调用JS的方法有2种: (1)通过WebView的loadUrl() // 调用js中的函数: ...
- 自定义django-admin命令
我们可以通过manage.py编写和注册自定义的命令. 自定义的管理命令对于独立脚本非常有用,特别是那些使用Linux的crontab服务,或者Windows的调度任务执行的脚本.比如,你有个需求,需 ...