(转)使用Aspose.Cell控件实现Excel高难度报表的生成(一)
本文章主要介绍报表的生成,基于Aspose.Cell控件的报表生成。谈到报表,估计大家都有所领悟以及个人的理解,总的来说,一般的报表生成,基本上是基于以下几种方式:一种是基于微软Excel内置的引擎来实现;一种是构造HTML格式的Excle报表;一种是基于控件的方式来处理,基于控件有很多种方式,个人认为比较有名的是Aspose.Cell(收费破解)和NPOI(开源)。
而报表的表现方式大致可以分为两种:
一种是通用的二维表导出的Excel格式,这种方式通过封装一个操作类,传递一个DataTable参数,把数据导出就可以了。这种报表特点是操作方便,通用,能应付一般常用的数据报表,如下所示;
由于这种报表,一般是在一个数据表格中显示,通常的做法是把这个东西做成控件,一个可以解决分页问题,一个可以解决导出、打印问题等,
当然,也可以把导入导出Excel的操作封装成一个公用的辅助来调用,如我封装的Aspose.Cell的导入导出处理函数如下所示:
代码 public class AsposeExcelTools
{ public static bool DataTableToExcel(DataTable datatable, string filepath, out string error)
{
error = "";
try
{
if (datatable == null)
{
error = "DataTableToExcel:datatable 为空";
return false;
} Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();
Aspose.Cells.Worksheet sheet = workbook.Worksheets[];
Aspose.Cells.Cells cells = sheet.Cells; int nRow = ;
foreach (DataRow row in datatable.Rows)
{
nRow++;
try
{
for (int i = ; i < datatable.Columns.Count; i++)
{
if (row[i].GetType().ToString() == "System.Drawing.Bitmap")
{
//------插入图片数据-------
System.Drawing.Image image = (System.Drawing.Image)row[i];
MemoryStream mstream = new MemoryStream();
image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg);
sheet.Pictures.Add(nRow, i, mstream);
}
else
{
cells[nRow, i].PutValue(row[i]);
}
}
}
catch (System.Exception e)
{
error = error + " DataTableToExcel: " + e.Message;
}
} workbook.Save(filepath);
return true;
}
catch (System.Exception e)
{
error = error + " DataTableToExcel: " + e.Message;
return false;
}
} public static bool DataTableToExcel2(DataTable datatable, string filepath, out string error)
{
error = "";
Aspose.Cells.Workbook wb = new Aspose.Cells.Workbook(); try
{
if (datatable == null)
{
error = "DataTableToExcel:datatable 为空";
return false;
} //为单元格添加样式
Aspose.Cells.Style style = wb.Styles[wb.Styles.Add()];
//设置居中
style.HorizontalAlignment = Aspose.Cells.TextAlignmentType.Center;
//设置背景颜色
style.ForegroundColor = System.Drawing.Color.FromArgb(, , );
style.Pattern = BackgroundType.Solid;
style.Font.IsBold = true; int rowIndex = ;
for (int i = ; i < datatable.Columns.Count; i++)
{
DataColumn col = datatable.Columns[i];
string columnName = col.Caption ?? col.ColumnName;
wb.Worksheets[].Cells[rowIndex, i].PutValue(columnName);
wb.Worksheets[].Cells[rowIndex, i].Style = style;
}
rowIndex++; foreach (DataRow row in datatable.Rows)
{
for (int i = ; i < datatable.Columns.Count; i++)
{
wb.Worksheets[].Cells[rowIndex, i].PutValue(row[i].ToString());
}
rowIndex++;
} for (int k = ; k < datatable.Columns.Count; k++)
{
wb.Worksheets[].AutoFitColumn(k, , );
}
wb.Worksheets[].FreezePanes(, , , datatable.Columns.Count);
wb.Save(filepath);
return true;
}
catch (Exception e)
{
error = error + " DataTableToExcel: " + e.Message;
return false;
} } /// <summary>
/// Excel文件转换为DataTable.
/// </summary>
/// <param name="filepath">Excel文件的全路径</param>
/// <param name="datatable">DataTable:返回值</param>
/// <param name="error">错误信息:返回错误信息,没有错误返回""</param>
/// <returns>true:函数正确执行 false:函数执行错误</returns>
public static bool ExcelFileToDataTable(string filepath, out DataTable datatable, out string error)
{
error = "";
datatable = null;
try
{
if (File.Exists(filepath) == false)
{
error = "文件不存在";
datatable = null;
return false;
}
Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();
workbook.Open(filepath);
Aspose.Cells.Worksheet worksheet = workbook.Worksheets[];
datatable = worksheet.Cells.ExportDataTable(, , worksheet.Cells.MaxRow + , worksheet.Cells.MaxColumn + );
//-------------图片处理-------------
Aspose.Cells.Pictures pictures = worksheet.Pictures;
if (pictures.Count > )
{
string error2 = "";
if (InsertPicturesIntoDataTable(pictures, datatable, out datatable, out error2) == false)
{
error = error + error2;
}
}
return true;
}
catch (System.Exception e)
{
error = e.Message;
return false;
} } public static bool ExcelFileToLists(string filepath, out IList[] lists, out string error)
{
error = "";
lists = null;
DataTable datatable = new DataTable();
IList list = new ArrayList();
Pictures[] pictures;
if (ExcelFileToDataTable(filepath, out datatable, out error) && GetPicturesFromExcelFile(filepath, out pictures, out error))
{
lists = new ArrayList[datatable.Rows.Count];
//------------DataTable转换成IList[]--------------
//数据
int nRow = ;
foreach (DataRow row in datatable.Rows)
{
lists[nRow] = new ArrayList(datatable.Columns.Count);
for (int i = ; i <= datatable.Columns.Count - ; i++)
{
lists[nRow].Add(row[i]);
}
nRow++;
}
//图片
for (int i = ; i < pictures.Length; i++)
{
foreach (Picture picture in pictures[i])
{
try
{
//----把图片转换成System.Drawing.Image----
//MemoryStream mstream = new MemoryStream();
//mstream.Write(picture.Data, 0, picture.Data.Length);
//System.Drawing.Image image = System.Drawing.Image.FromStream(mstream);
//----Image放入IList------
//图片有可能越界
if (picture.UpperLeftRow <= datatable.Rows.Count && picture.UpperLeftColumn <= datatable.Columns.Count)
{
lists[picture.UpperLeftRow][picture.UpperLeftColumn] = picture.Data;
} }
catch (System.Exception e)
{
error = error + e.Message;
} }
} }
else
{ return false;
}
return true;
} public static bool ListsToExcelFile(string filepath, IList[] lists, out string error)
{
error = "";
//----------Aspose变量初始化----------------
Aspose.Cells.Workbook workbook = new Aspose.Cells.Workbook();
Aspose.Cells.Worksheet sheet = workbook.Worksheets[];
Aspose.Cells.Cells cells = sheet.Cells;
//-------------输入数据-------------
int nRow = ;
sheet.Pictures.Clear();
cells.Clear();
foreach (IList list in lists)
{ for (int i = ; i <= list.Count - ; i++)
{
try
{
System.Console.WriteLine(i.ToString() + " " + list[i].GetType());
if (list[i].GetType().ToString() == "System.Drawing.Bitmap")
{
//插入图片数据
System.Drawing.Image image = (System.Drawing.Image)list[i]; MemoryStream mstream = new MemoryStream(); image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg); sheet.Pictures.Add(nRow, i, mstream);
}
else
{
cells[nRow, i].PutValue(list[i]);
}
}
catch (System.Exception e)
{
error = error + e.Message;
} } nRow++;
}
//-------------保存-------------
workbook.Save(filepath); return true;
}
这样封装了Aspose.Cell的操作,每次生成Excel文件或者导入Excel内容,就非常方便,只需要如下调用方式即可完成:
private void button1_Click(object sender, EventArgs e)
{
DataTable dt = CreateTable("测试1,测试2,Test1,Test2", "testTable");
for (int i = ; i < ; i++)
{
DataRow dr = dt.NewRow();
for (int j = ; j < dt.Columns.Count; j++)
{
dr[j] = i.ToString();
}
dt.Rows.Add(dr);
} string outError = "";
string fileName = @"C:\test.xls";
AsposeExcelTools.DataTableToExcel2(dt, fileName, out outError); if (!string.IsNullOrEmpty(outError))
{
MessageBox.Show(outError);
}
else
{
Process.Start(fileName);
}
} public DataTable CreateTable(string nameString, string tableName)
{
string[] nameArray = nameString.Split(new char[] { ',', ';' });
List<string> nameList = new List<string>();
foreach (string item in nameArray)
{
if (!string.IsNullOrEmpty(item))
{
nameList.Add(item);
}
} return CreateTable(nameList, tableName);
}
另外一种是以Excel文件作为模板,然后填入必要的内容,形成比较综合性,复杂性较高的报表,这种报表一般比较专业、比较规范好看,在一些特殊的场合,必须使用这些固定格式的报表,如下所示:
或者这样的报表格式
这些报表,基本上就是用到了变量、函数等的概念才能处理好这些数据,如上面的出库单,里面的成本中心、部门、库房编号等,这些通过变量绑定应该就可以了,而里面的列表,则可以通过集合绑定实现,Aspose.Cell控件功能非常强大,很好支持这些操作,下面一步步介绍该控件制作这类报表的实现代码。
Aspose.Cell控件支持多种参数变量的绑定操作,如支持DataSet、Datatable、IList集合,实体类集合、类对象等。
DataSet ds = LoadDataSet();//使用DataSet对象
List<Customers> entity = GetCustomers();//使用实体类对象
DataTable dt = GetCustomersTable();//使用DataTable对象 //创建一个workbookdesigner对象
WorkbookDesigner designer = new WorkbookDesigner(); //制定报表模板
string path = System.IO.Path.Combine(Application.StartupPath,"SmartMarkerDesigner.xls");
designer.Open(path); //设置DataSet对象
//designer.SetDataSource(ds); //设置实体类对象
//designer.SetDataSource("Customers", entity); //设置Datatable对象 designer.SetDataSource(dt);
designer.SetDataSource(ds.Tables["Order Details"]); //设置变量对象
designer.SetDataSource("Variable", "Single Variable");
//设置集合变量
designer.SetDataSource("MultiVariable", new string[] { "Variable 1", "Variable 2", "Variable 3" });
//设置集合变量
designer.SetDataSource("MultiVariable2", new string[] { "Skip 1", "Skip 2", "Skip 3" }); //根据数据源处理生成报表内容
designer.Process(); //保存Excel文件
string fileToSave = System.IO.Path.Combine(Application.StartupPath, "SmartMarker.xls");
if (File.Exists(fileToSave))
{
File.Delete(fileToSave);
} designer.Save(fileToSave, FileFormatType.Excel2003);
//打开Excel文件 Process.Start(fileToSave);
以上的代码说明了改控件支持的各种参数变量,我们先看看报表的模板,然后看看报表的生成内容,对比一下就更直观了。
报表1模板如下所示(其中通过引用集合的对象是通过&=来引用,对象的属性或者列名,通过如&=Customer.City方式引用,非常直观方便:
报表1生成的效果如下所示(Customers可以使DataTable对象,也可以List<Customer>实体对象集合。
报表2的模板如下所示,对象也可以通过&=[Order Detail]方式引用,另外模板支持一些参数,其中{r}为当行的变量,翻译到实际的报表可能就是C4*D4这样的格式了,其中两个&=表示动态公式引用,区别于普通的变量和字符,如&=&=C{r}*D{r}后者汇总函数&=&=Sum(C{r}:D{r})等等。
(转)使用Aspose.Cell控件实现Excel高难度报表的生成(一)的更多相关文章
- 使用Aspose.Cell控件实现Excel高难度报表的生成(三)
在之前几篇文章中,介绍了关于Apsose.cell这个强大的Excel操作控件的使用,相关文章如下: 使用Aspose.Cell控件实现Excel高难度报表的生成(一) 使用Aspose.Cell控件 ...
- 使用Aspose.Cell控件实现Excel高难度报表的生成(二)
继续在上篇<使用Aspose.Cell控件实现Excel高难度报表的生成(一)>随笔基础上,研究探讨基于模板的Aspose.cell报表实现,其中提到了下面两种报表的界面,如下所示: 或者 ...
- 使用Aspose.Cell控件实现Excel高难度报表的生成
1.使用Aspose.Cell控件实现Excel高难度报表的生成(一) http://www.cnblogs.com/wuhuacong/archive/2011/02/23/1962147.html ...
- 使用Aspose.Cell控件实现Excel高难度报表的生成(一)
时光飞逝,生活.工作.业余研究总是在不停忙碌着,转眼快到月底,该月的博客文章任务未完,停顿回忆一下,总结一些经验以及好的东西出来,大家一起分享一下.本文章主要介绍报表的生成,基于Aspose.Cell ...
- 利用Aspose.Cell控件导入Excel非强类型的数据
导入Excel的操作是非常常见的操作,可以使用Aspose.Cell.APOI.MyXls.OLEDB.Excel VBA等操作Excel文件,从而实现数据的导入,在导入数据的时候,如果是强类型的数据 ...
- 利用Aspose.Word控件和Aspose.Cell控件,实现Word文档和Excel文档的模板化导出
我们知道,一般都导出的Word文档或者Excel文档,基本上分为两类,一类是动态生成全部文档的内容方式,一种是基于固定模板化的内容输出,后者在很多场合用的比较多,这也是企业报表规范化的一个体现. 我的 ...
- 使用Aspose.Cell控件实现多个Excel文件的合并
之前有写过多篇关于使用Apose.Cell控件制作自定义模板报表和通用的导出Excel表格数据的操作,对这个控件的功能还是比较满意,而且也比较便利.忽然有一天,一个朋友说:你已经有生成基于自定义模板报 ...
- 用Aspose.Cells控件读取Excel
Aspose是一个很强大的控件,可以用来操作word,excel,ppt等文件,用这个控件来导入.导出数据非常方便.其中Aspose.Cells就是用来操作Excel的,功能有很多.我所用的是最基本的 ...
- 基于C#语言MVC框架Aspose.Cells控件导出Excel表数据
控件bin文件下载地址:https://download.csdn.net/download/u012949335/10610726 @{ ViewBag.Title = "xx" ...
随机推荐
- C#中如何计算时间差?
C#中怎么计算两时间相差多少.计算2个时间之间的差,可以计算到时分秒! <1> label1.Text = "2004-1-1 15:36:05"; label2.Te ...
- 模拟TAB键
模拟TAB键 (2013/6/7 22:35:29) SelectNext(ActiveControl,True,True); 屏蔽Alt+F4关闭键 (2013/6/7 22:35:39) 启动某些 ...
- Winform 水印TextBox
方法一: public partial class WaterTextBox : TextBox { private readonly Label lblwaterText = new Label() ...
- PHP生成条形码
前阵子在做一个商家优惠券的功能,需要用到条形码,于是将资料重新整理下. 1.什么是条形码? 百度百科定义:条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息 ...
- Android录音--AudioRecord、MediaRecorder
Android提供了两个API用于实现录音功能:android.media.AudioRecord.android.media.MediaRecorder. 网上有很多谈论这两个类的资料.现在大致总结 ...
- HttpClient设置代理,超时,以及得到cookies
import java.net.URI; import java.util.List; import org.apache.http.HttpEntity; import org.apache.htt ...
- jQuery Validate 插件[表单验证 属性介绍]
详细介绍一下Validate插件 $("#form的Id").validate({ }) 属性 规则 描述 required:true 必须输入的字段 required: &quo ...
- [转]一步步教你如何在 Visual Studio 2013 上使用 Github
介绍 我承认越是能将事情变简单的工具我越会更多地使用它.尽管我已经知道了足够的命令来使用Github,但我宁愿它被集成到IDE中.在本教程中,我会告诉你使用Visual Studio 2013如何实现 ...
- xml版本学生管理系统
一: 需求描述 学生成绩管理系统,使用xml存储学生信息,可以对学生信息进行增.删.删除操作. 主要目的:练习操作xml元素的增删改查 二:代码结构 1:xml存储数据如下 exam.xml < ...
- 经常被忽略的几个CSS3属性之强大应用(一、timing-function: steps() 二、animation-direction 三、timing-function: cubic-bezier())
一.timing-function: steps() 一开始在使用CSS3的时候并没有太注意这个timing-function,只是注意到自定义贝塞尔曲线. 1)一个项目中的实例 先来看看左边加了st ...