树结构关系的数据导出为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模块后,我很容易的将这个类 ...
随机推荐
- AJAX+springmvc遇到的问题
当我使用AJAX将表单的值传入处理器中后,经过了一个判断再进行页面跳转时,不能在处理器中使用重定向,它会将重定向的页面内容在AJAX的data中显示出来而不是显示一个页面 所以只能在AJAX 的suc ...
- java学习之—栈匹配字符串符号
/** * 栈 * Create by Administrator * 2018/6/11 0011 * 上午 10:20 **/ public class StackR { private int ...
- Linux用户权限指令, 定时任务等指令
一. 网卡配置详解 网络配置文件: /etc/sysconfig/network 网络接口配置文件: /etc/sysconfig/network-scripts/ifcfg-INTERFACE_NA ...
- 循环神经网络RNN及LSTM
一.循环神经网络RNN RNN综述 https://juejin.im/entry/5b97e36cf265da0aa81be239 RNN中为什么要采用tanh而不是ReLu作为激活函数? htt ...
- tensorflow中使用指定的GPU及GPU显存 CUDA_VISIBLE_DEVICES
参考: https://blog.csdn.net/jyli2_11/article/details/73331126 https://blog.csdn.net/cfarmerreally/arti ...
- Hbase和Oracle的对比
转自:http://www.cnblogs.com/chay1227/archive/2013/03/17/2964020.html 转自:http://blog.csdn.net/allen879/ ...
- 关于jQuery.when()用法
1.该方法在jQuery1.5开始被引入. 2.用法测试 a. var url1 = "/resource/ar/hometab/index_tab_games.json", ur ...
- 3、springframe常用注解
1.@controller 控制器(注入服务) 2.@service 服务(注入dao) 3.@repository dao(实现dao访问) 4.@component (把普通pojo实例化到spr ...
- fpm 打包教程
常用yum命令: Yum安装时需要安装到指定的文件夹,则需要 --installroot yum install --installroot=/usr/src/ vim 常用rpm命令: 常用yum仓 ...
- CodeCraft-19 and Codeforces Round #537 Div. 2
D:即有不超过52种物品,求容量为n/2的有序01背包方案数.容易想到设f[i][j]为前i种物品已用容量为j的方案数,有f[i][j]=f[i-1][j-a[i]]*C(n/2-j+a[i],a[i ...