使用Aspose.Cell控件实现Excel高难度报表的生成(三)

在之前几篇文章中,介绍了关于Apsose.cell这个强大的Excel操作控件的使用,相关文章如下:

使用Aspose.Cell控件实现Excel高难度报表的生成(一)

使用Aspose.Cell控件实现Excel高难度报表的生成(二)

使用Aspose.Cell控件实现多个Excel文件的合并

这几篇文章,都对Apose.Cell这个控件生成各种Excel的方式进行了阐述,对直接把DataTable或者IList生成Excel的操作,对通过模板方式实现自定义报表的各种方式,以及多个文件的合并的方式进行了介绍。

本文继续介绍该控件进一步的使用,也主要介绍如何动态生成(不使用模板文件)各种单元格,以及图表的增加等功能,介绍生成的表格完全自定义,这个报表时一个典型的图文并茂的统计报表,它的最终样式如下所示。

这个报表,表格数据是动态生成,图形则是直接从窗体的图表控件(如ZedGraph图表控件)或者PictureBox控件中获取,写入Excel文档中的。

测试程序主界面如下所示。

和很多其他的Excel操作控件(NPOI、Myxls)一样吗,Apose.Cell也提供了WorkBook、WorkSheet、Range、Cell这些对象的包装,操作这些对象,基本上能够满足我们各种复杂的需求,给我们更加弹性化的操作。

1、 添加基本对象进行操作

            Workbook workbook = new Workbook();
            Worksheet worksheet = workbook.Worksheets[0];

这几个对象是操作Excel必须的,如果需要设定生成的Excel打印预览的参数,进行一些属性设置,如下所示。

            Workbook workbook = new Workbook();
            Worksheet worksheet = workbook.Worksheets[0];

            worksheet.PageSetup.Orientation = PageOrientationType.Landscape;//横向打印
            worksheet.PageSetup.Zoom = 100;//以100%的缩放模式打开
            worksheet.PageSetup.PaperSize = PaperSizeType.PaperA4;

我们知道,由于该报表完全是手工生成,报表的标题,以及下面几行说明文字,也是需要生成的,操作其实就是把一些单元格合并为一个区域(Range),然后赋值,改变样式就可以了,如下所示的效果和代码

            Range range; Cell cell;
            int colSpan = 4 + DeptNameList.Count * 2;
            range = worksheet.Cells.CreateRange(0, 0, 1, colSpan);
            range.Merge();
            range.RowHeight = 20;
            range.Style = CreateTitleStyle(workbook);
            cell = range[0, 0];
            cell.PutValue("患病情况统计");

            range = worksheet.Cells.CreateRange(1, 0, 1, colSpan);
            range.Merge();
            range.RowHeight = 15;
            cell = range[0, 0];
            cell.PutValue("所选部别范围内,总计有1000名人员,查询统计结果如下:");

            range = worksheet.Cells.CreateRange(2, 0, 1, colSpan);
            range.Merge();
            range.RowHeight = 15;
            cell = range[0, 0];
            cell.PutValue("自2007-1-1开始到现在,统计共有500人有患病史,累计900人次,患病情况如下表:");

2、生成报表头部表格

报表中最复杂的是表头的生成,因为它是不规则的表头,因此需要很细的操作Cell和Range对象,实现复杂表头(也是很常见的)的生成。

这个是慢工出细活,需要对Cell和Range熟悉使用,然后给他们分配不同的行列就可以生成一个标准如下的表头了。

            Style headStyle = CreateStyle(workbook, true);
            Style normalStyle = CreateStyle(workbook, false);
            int startRow = 4;
            range = worksheet.Cells.CreateRange(startRow, 0, 2, 1);
            range.Merge();
            range.Style = headStyle;
            cell = range[0, 0];
            cell.PutValue("序号");
            cell.Style = headStyle;

            range = worksheet.Cells.CreateRange(startRow, 1, 2, 1);
            range.Merge();
            range.Style = headStyle;
            range.ColumnWidth = 40;
            cell = range[0, 0];
            cell.PutValue("疾病名称");
            cell.Style = headStyle;

            int startCol = 2;
            foreach (string deptName in DeptNameList)
            {
                range = worksheet.Cells.CreateRange(startRow, startCol, 1, 2);
                range.Merge();
                range.Style = headStyle;
                cell = range[0, 0];
                cell.PutValue(deptName);

                cell = worksheet.Cells[startRow + 1, startCol];
                cell.PutValue("人次");
                cell.Style = headStyle;
                cell = worksheet.Cells[startRow + 1, startCol + 1];
                cell.PutValue("百分比");
                cell.Style = headStyle;

                startCol += 2;
            }

            range = worksheet.Cells.CreateRange(startRow, startCol, 1, 2);
            range.Merge();
            range.Style = headStyle;
            cell = range[0, 0];
            cell.PutValue("合计");

            cell = worksheet.Cells[startRow + 1, startCol];
            cell.PutValue("人次");
            cell.Style = headStyle;
            cell = worksheet.Cells[startRow + 1, startCol + 1];
            cell.PutValue("百分比");
            cell.Style = headStyle;
            #endregion

3、填入表格内容

这个不算复杂,只需要遍历然后生成内容到单元格即可。

            //写入数据到Excel
            startRow = startRow + 2;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                startCol = 0;
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    DataRow dr = dt.Rows[i];
                    cell = worksheet.Cells[startRow, startCol];
                    cell.PutValue(dr[j]);
                    cell.Style = normalStyle;

                    startCol++;
                }
                startRow++;
            }

4、插入图表及导出打开操作

这个Apose.Cell控件的WorkSheet提供了worksheet.Pictures.Add方法,可以添加图片的操作,不过图片是通过流方式写入,我们把图表的Image对象转换一下,创建一个内存流就可以了。如下所示。

            //写入图注
            startRow += 1;//跳过1行
            range = worksheet.Cells.CreateRange(startRow++, 0, 1, colSpan);
            range.Merge();
            range.RowHeight = 15;
            cell = range[0, 0];
            cell.PutValue("以柱状图展示如下:");

            //插入图片到Excel里面
            byte[] bytes = ImageHelper.ImageToBytes(this.pictureBox1.Image);
            using (MemoryStream stream = new MemoryStream(bytes))
            {
                worksheet.Pictures.Add(startRow, 0, stream);
            }

            //Save the excel file.
            string saveFile = FileDialogHelper.SaveExcel("rangecells.xls", "C:\\");
            if (!string.IsNullOrEmpty(saveFile))
            {
                workbook.Save(saveFile);
                if (MessageUtil.ShowYesNoAndTips("保存成功,是否打开文件?") == System.Windows.Forms.DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start(saveFile);
                }
            }

至此,基于Apose.Cell的自定义报表的另外一种操作也全部实现了,为了实现这个简单的例子,以便在项目中使用,花了不少时间,不过以后对于生成这类复杂的和自定义报表,可以直接利用它们基础的对象进行操作即可;

如果是一些常规的报表,可以利用自定义模板的方式生成,然后绑定数据源;如果是二维表,或者ILIst集合,导出Excel就更简单了。以上两种都可以直接利用封装好的AsposeExcelTools来进行操作,这个通用的类库,可以省却每次去编写代码的繁琐,提高效率。

本文转自博客园伍华聪的博客,原文链接:使用Aspose.Cell控件实现Excel高难度报表的生成(三),如需转载请自行联系原博主。

时间: 2024-12-26 23:50:30

使用Aspose.Cell控件实现Excel高难度报表的生成(三)的相关文章

使用Aspose.Cell控件实现Excel高难度报表的生成(二)

继续在上篇<使用Aspose.Cell控件实现Excel高难度报表的生成(一)>随笔基础上,研究探讨基于模板的Aspose.cell报表实现,其中提到了下面两种报表的界面,如下所示:  或者这样的报表格式    首先来分析第一种报表,这个其实还是比较固定的二维表,我们只要绑定相关的信息即可,设计模板如下所示:   实际生成的报表如下所示:   实现的代码其实不复杂,如下所示:          private DataTable GetTable(string sql)         {  

利用Aspose.Cell控件导入Excel非强类型的数据

导入Excel的操作是非常常见的操作,可以使用Aspose.Cell.APOI.MyXls.OLEDB.Excel VBA等操作Excel文件,从而实现数据的导入,在导入数据的时候,如果是强类型的数据,那么这几种方式好像都表现差不多,正常操作能够导入数据.如果是非强类型的数据,那么就需要特别注意了,一般情况下,导入的DataTable数据列的类型是以第一行内容作为确定列类型的,本文介绍利用Aspose.Cell控件导入Excel非强类型的数据的操作. 什么是强类型的数据呢,就是在Excel表格中

利用Aspose.Word控件和Aspose.Cell控件,实现Word文档和Excel文档的模板化导出

我们知道,一般都导出的Word文档或者Excel文档,基本上分为两类,一类是动态生成全部文档的内容方式,一种是基于固定模板化的内容输出,后者在很多场合用的比较多,这也是企业报表规范化的一个体现. 我的博客介绍过几篇关于Aspose.Word控件和Aspose.Cell控件的使用操作,如下所示. <使用Aspose.Cell控件实现Excel高难度报表的生成(一)> <使用Aspose.Cell控件实现Excel高难度报表的生成(二)> <使用Aspose.Cell控件实现Ex

使用Aspose.Cell控件实现多个Excel文件的合并

之前有写过多篇关于使用Apose.Cell控件制作自定义模板报表和通用的导出Excel表格数据的操作,对这个控件的功能还是比较满意,而且也比较便利.忽然有一天,一个朋友说:你已经有生成基于自定义模板报表了,可是我每个单位都导出一张相同的报表的话,我岂不是要生成很多文件,而且对比查看也不方便,有没有更好的办法合并他们到一个文件里面呢?这样我看报表就方便很多了.本文主要介绍如何实现基于一个自定义报表模式,生成多个类似报表合并在一个文件中具体操作. 查询Apose.Cell控件的使用介绍,WorkBo

利用Aspose.Word控件实现Word文档的操作

原文:利用Aspose.Word控件实现Word文档的操作 Aspose系列的控件,功能都挺好,之前一直在我的Winform开发框架中用Aspose.Cell来做报表输出,可以实现多样化的报表设计及输出,由于一般输出的内容比较正规化或者多数是表格居多,所以一般使用Aspose.Cell来实现我想要的各种Excel报表输出.虽然一直也知道Aspose.Word是用来生成Word文档的,而且深信其也是一个很强大的控件,但一直没用用到,所以就不是很熟悉. 偶然一次机会,一个项目的报表功能指定需要导出为

关于控件导出Excel格式问题的新解决方案

今天弄了一下控件导出Excel,于是产生了格式问题了,一些日期如20091222的名称被显示为科学记数法. 所以,我搜了博客园.一大堆的文章都是复制来复制去的资料. 基本上都有这么一行闪亮的代码:文本:vnd.ms-excel.numberformat:@ 有深入一点的文章,会告诉你,这个东西要写在<td style="vnd.ms-excel.numberformat:@">xxx</td>里 于是这里就产生这两个分支方法: 1.直接就写上<td sty

Android编程获取控件宽和高的方法总结分析_Android

本文总结分析了Android编程获取控件宽和高的方法.分享给大家供大家参考,具体如下: 我们都知道在onCreate()里面获取控件的高度是0,这是为什么呢?我们来看一下示例: 首先我们自己写一个控件,这个控件非常简单: public class MyImageView extends ImageView { public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); } public MyIm

calendar-我在日历控件里的每一天动态生成一个按钮,但是事件不生效是怎么回事

问题描述 我在日历控件里的每一天动态生成一个按钮,但是事件不生效是怎么回事 我在Calendar控件里的每一天动态生成一个LinkButton,显示农历且可以点击,但是Command事件不生效是怎么回事? 这是代码,农历能正常显示,但是LinkButton不能点击 //日的读取 protected void Calendar1_DayRender(object sender, DayRenderEventArgs e) { //农历 LinkButton lbChinaDate = new Li

导出CListCtrl控件到Excel文件

CListCtrl获得列的属性可以使用BOOL CListCtrl::GetColumn( int nCol, LVCOLUMN* pColumn ),nCol为需要获得获得属性值的列序号,pColumn 为 LVCOLUMN 结构体的指针.LVCOLUMN结构体中的 UINT mask 作为输入,决定返回哪些属性的值,如果 mask 的值包含 LVCF_TEXT ,则需要将字符串缓存的首地址指针置入结构体中的 LPTSTR pszText; 变量,缓存大小置入 int cchTextMax;