该文针对的是关于树结构的数据的导出,每一个节点都可以创建不定数的子节点,在选择好某个节点进行导出

时,会把该节点以及子节点的数据都导出来。导出后的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的更多相关文章

  1. 学习笔记 DataGridView数据导出为Excel

    DataGridView数据导出为Excel   怎样把WinForm下的“DGV”里的绑定数据库后的数据导出到Excel中. 比如:在窗体里有个一“DGV”,DataGridView1,绑定了数据源 ...

  2. 将C1Chart数据导出到Excel

    大多数情况下,当我们说将图表导出到Excel时,意思是将Chart当成图片导出到Excel中.如果是这样,你可以参考帮助文档中保存和导出C1Chart章节. 不过,也有另一种情况,当你想把图表中的数据 ...

  3. vb.net-三种将datagridview数据导出为excel文件的函数

    第一种方法较慢,但是数据格式都比较好,需要引用excel的 Microsoft.Office.Interop.Excel.dll  office.dll #Region "导出excel函数 ...

  4. 数据导出至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; ...

  5. 数据导出到Excel中

    自己修改后的一个数据导出到Excel的方法,粘出来与大家共享. 只需要将             System.Web.HttpContext.Current.Response.Charset =   ...

  6. asp.net将数据导出到excel

    本次应用datatable导出,若用gridview(假设gridview设为了分页显示)会出现只导出当前页的情况. protected void btnPrn_Click(object sender ...

  7. 将datagrid中数据导出到excel中 -------<<工作日志2014-6-6>>

    前台datagrid数据绑定 #region 导出到excel中    /// <summary>    /// 2014-6-6    /// </summary>    / ...

  8. 机房收费系统——在VB中将MSHFlexGrid控件中的数据导出到Excel

    机房收费系统中,好多查询的窗体都包含同一个功能:将数据库中查询到的数据显示在MSHFlexGrid控件中,然后再把MSHFlexGrid控件中的数据导出到Excel表格中. 虽然之前做过学生信息管理系 ...

  9. Qt中将QTableView中的数据导出为Excel文件

    如果你在做一个报表类的程序,可能将内容导出为Excel文件是一项必须的功能.之前使用MFC的时候我就写过一个类,用于将grid中的数据导出为Excel文件.在使用了QtSql模块后,我很容易的将这个类 ...

随机推荐

  1. python之路--FTP 上传视频示例

    # 服务端 import json import socket import struct server = socket.socket() server.bind(('127.0.0.1',8001 ...

  2. 如何在Mac系统安装MySQL

    方法一: (1)使用brew install mysql (2)使用mysql -uroot连接时报错: Authentication plugin 'caching_sha2_password' c ...

  3. mybatis 批量查询参数语句

    在mybatis  传入数组在sql语句中进行查询 1.传入一个map集合,已或者的形式拼接数组循环 <select id="selectUserByList" parame ...

  4. JQuery跳出each循环的方法(包含数组遍历)

    0. 前言 也许我们通过 jquery 的循环方法进行数组遍历,但是当不符合条件时,怎么跳出当前循环?(即用each方法内,当不满足条件时想break跳出循环体,想continue继续执行下一个循环遍 ...

  5. Thread的其他属性方法

    from threading import Thread,currentThread,active_count import time def task(): print('%s is running ...

  6. 【python练习题】程序10

    #10.题目:暂停一秒输出,并格式化当前时间. import time print(time.time())#timestamp print(time.localtime(time.time()))# ...

  7. JS获取宽度高度大集合

    网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...

  8. ceil以及double的精度问题

    Codeforces Round #518 (Div. 2) A CF一道水题,总过不去 后面看了一下数据发现是精度出问题了 1000000000000000000 1 1 1000000000000 ...

  9. BZOJ4818 [SDOI2017] 序列计数 【矩阵快速幂】

    题目分析: 一个很显然的同类项合并.注意到p的大小最大为100,考虑把模p意义下相同的求出来最后所有的减去没有质数的做矩阵快速幂即可. 代码: #include<bits/stdc++.h> ...

  10. 【BZOJ1419】Red is good 期望DP

    题目大意 桌面上有\(R\)张红牌和\(B\)张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到\(1\)美元,黑牌则付出\(1\)美元.可以随时停止翻牌,在最优策略下平均能得到多少钱 ...